1 #pragma once 2 3 #include "erase.hpp" 4 5 #include <linux/mmc/ioctl.h> 6 #include <sys/ioctl.h> 7 #include <sys/types.h> 8 9 #include <stdplus/fd/managed.hpp> 10 #include <util.hpp> 11 12 #include <array> 13 #include <cstddef> 14 #include <span> 15 #include <string_view> 16 17 namespace estoraged 18 { 19 20 class IOCTLWrapperInterface 21 { 22 public: 23 /** @brief Wrapper around ioctl 24 * @details Used for mocking purposes. 25 * 26 * @param[in] devPath - File name of block device 27 * @param[in] request - Device-dependent request code 28 * @param[in] mmc_ioc_cmd - eMMC cmd 29 */ 30 virtual int doIoctl(std::string_view devPath, unsigned long request, 31 struct mmc_ioc_cmd data) = 0; 32 33 /** @brief Wrapper around ioctl 34 * @details Used for mocking purposes. 35 * 36 * @param[in] devPath - File name of block device 37 * @param[in] request - Device-dependent request code 38 * @param[in] mmc_io_mutli_cmd - many eMMC cmd 39 */ 40 virtual int doIoctlMulti(std::string_view devPath, unsigned long request, 41 struct mmc_io_multi_cmd_erase data) = 0; 42 43 virtual ~IOCTLWrapperInterface() = default; 44 IOCTLWrapperInterface() = default; 45 IOCTLWrapperInterface(const IOCTLWrapperInterface&) = delete; 46 IOCTLWrapperInterface& operator=(const IOCTLWrapperInterface&) = delete; 47 48 IOCTLWrapperInterface(IOCTLWrapperInterface&&) = delete; 49 IOCTLWrapperInterface& operator=(IOCTLWrapperInterface&&) = delete; 50 }; 51 52 // mockIOCTLWapper also inherits from IOCTLWrapperInterface 53 class IOCTLWrapperImpl : public IOCTLWrapperInterface 54 { 55 public: 56 int doIoctl(std::string_view devPath, unsigned long request, 57 struct mmc_ioc_cmd data) override; 58 int doIoctlMulti(std::string_view devPath, unsigned long request, 59 struct mmc_io_multi_cmd_erase data) override; 60 ~IOCTLWrapperImpl() override = default; 61 IOCTLWrapperImpl() = default; 62 63 IOCTLWrapperImpl(const IOCTLWrapperImpl&) = delete; 64 IOCTLWrapperImpl& operator=(const IOCTLWrapperImpl&) = delete; 65 66 IOCTLWrapperImpl(IOCTLWrapperImpl&&) = delete; 67 IOCTLWrapperImpl& operator=(IOCTLWrapperImpl&&) = delete; 68 }; 69 70 class Sanitize : public Erase 71 { 72 public: 73 /** @breif Creates a sanitize erase object 74 * 75 * @param[in] inDevPath - the linux device path for the block device. 76 * @param[in] IOCTLWrapper - This is a ioctl wrapper, it can be used for 77 * testing 78 */ 79 Sanitize(std::string_view inDevPath, 80 std::unique_ptr<IOCTLWrapperInterface> inIOCTL = 81 std::make_unique<IOCTLWrapperImpl>()) : 82 Erase(inDevPath), 83 ioctlWrapper(std::move(inIOCTL)) 84 {} 85 86 /** @brief sanitize the drive, using eMMC specifed erase commands 87 * 88 * param[in] driveSize - size of the drive in bytes 89 */ 90 void doSanitize(uint64_t driveSize); 91 92 /** @brief sanitize the drive, using eMMC specifed erase commands 93 * This function uses the built in utils to call sanitize 94 */ 95 void doSanitize() 96 { 97 doSanitize(util::findSizeOfBlockDevice(devPath)); 98 } 99 100 private: 101 /* Wrapper for ioctl*/ 102 std::unique_ptr<IOCTLWrapperInterface> ioctlWrapper; 103 104 /** @brief uses the eMMC defined sanitize command, it is not the same as 105 * vendor_sanitize */ 106 void emmcSanitize(); 107 108 /** @brief uses the eMMC defined erase command 109 * 110 * param[in] driveSize - size of the drive in bytes 111 */ 112 void emmcErase(uint64_t driveSize); 113 }; 114 115 // can't use the real mmc_ioc_multi_cmd b/c of zero length array 116 // see uapi/linux/mmc/ioctl.h 117 struct mmc_io_multi_cmd_erase 118 { 119 uint64_t num_of_cmds; 120 struct mmc_ioc_cmd cmds[3]; // NOLINT (c arrays usage) 121 }; 122 123 } // namespace estoraged 124