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