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 /** @brief 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 */ Sanitize(std::string_view inDevPath,std::unique_ptr<IOCTLWrapperInterface> inIOCTL=std::make_unique<IOCTLWrapperImpl> ())79 Sanitize(std::string_view inDevPath, 80 std::unique_ptr<IOCTLWrapperInterface> inIOCTL = 81 std::make_unique<IOCTLWrapperImpl>()) : 82 Erase(inDevPath), ioctlWrapper(std::move(inIOCTL)) 83 {} 84 85 /** @brief sanitize the drive, using eMMC specified erase commands 86 * 87 * param[in] driveSize - size of the drive in bytes 88 */ 89 void doSanitize(uint64_t driveSize); 90 91 /** @brief sanitize the drive, using eMMC specified erase commands 92 * This function uses the built in utils to call sanitize 93 */ doSanitize()94 void doSanitize() 95 { 96 doSanitize(util::findSizeOfBlockDevice(devPath)); 97 } 98 99 private: 100 /* Wrapper for ioctl*/ 101 std::unique_ptr<IOCTLWrapperInterface> ioctlWrapper; 102 103 /** @brief uses the eMMC defined sanitize command, it is not the same as 104 * vendor_sanitize */ 105 void emmcSanitize(); 106 107 /** @brief uses the eMMC defined erase command 108 * 109 * param[in] driveSize - size of the drive in bytes 110 */ 111 void emmcErase(uint64_t driveSize); 112 }; 113 114 // can't use the real mmc_ioc_multi_cmd b/c of zero length array 115 // see uapi/linux/mmc/ioctl.h 116 struct mmc_io_multi_cmd_erase 117 { 118 uint64_t num_of_cmds; 119 struct mmc_ioc_cmd cmds[3]; // NOLINT (c arrays usage) 120 }; 121 122 } // namespace estoraged 123