#pragma once #include "erase.hpp" #include #include #include #include #include #include #include #include #include namespace estoraged { using stdplus::fd::ManagedFd; class IOCTLWrapperInterface { public: /** @brief Wrapper around ioctl * @details Used for mocking purposes. * * @param[in] devPath - File name of block device * @param[in] request - Device-dependent request code * @param[in] mmc_ioc_cmd - eMMC cmd */ virtual int doIoctl(std::string_view devPath, unsigned long request, struct mmc_ioc_cmd data) = 0; /** @brief Wrapper around ioctl * @details Used for mocking purposes. * * @param[in] devPath - File name of block device * @param[in] request - Device-dependent request code * @param[in] mmc_io_mutli_cmd - many eMMC cmd */ virtual int doIoctlMulti(std::string_view devPath, unsigned long request, struct mmc_io_multi_cmd_erase data) = 0; virtual ~IOCTLWrapperInterface() = default; IOCTLWrapperInterface() = default; IOCTLWrapperInterface(const IOCTLWrapperInterface&) = delete; IOCTLWrapperInterface& operator=(const IOCTLWrapperInterface&) = delete; IOCTLWrapperInterface(IOCTLWrapperInterface&&) = delete; IOCTLWrapperInterface& operator=(IOCTLWrapperInterface&&) = delete; }; // mockIOCTLWapper also inherits from IOCTLWrapperInterface class IOCTLWrapperImpl : public IOCTLWrapperInterface { public: int doIoctl(std::string_view devPath, unsigned long request, struct mmc_ioc_cmd data) override; int doIoctlMulti(std::string_view devPath, unsigned long request, struct mmc_io_multi_cmd_erase data) override; ~IOCTLWrapperImpl() override = default; IOCTLWrapperImpl() = default; IOCTLWrapperImpl(const IOCTLWrapperImpl&) = delete; IOCTLWrapperImpl& operator=(const IOCTLWrapperImpl&) = delete; IOCTLWrapperImpl(IOCTLWrapperImpl&&) = delete; IOCTLWrapperImpl& operator=(IOCTLWrapperImpl&&) = delete; }; class Sanitize : public Erase { public: /** @breif Creates a sanitize erase object * * @param[in] inDevPath - the linux device path for the block device. * @param[in] IOCTLWrapper - This is a ioctl wrapper, it can be used for * testing */ Sanitize(std::string_view inDevPath, std::unique_ptr inIOCTL = std::make_unique()) : Erase(inDevPath), ioctlWrapper(std::move(inIOCTL)) {} /** @brief sanitize the drive, using eMMC specifed erase commands * * param[in] driveSize - size of the drive in bytes */ void doSanitize(uint64_t driveSize); /** @brief sanitize the drive, using eMMC specifed erase commands * This function uses the built in utils to call sanitize */ void doSanitize() { doSanitize(util::Util::findSizeOfBlockDevice(devPath)); } private: /* Wrapper for ioctl*/ std::unique_ptr ioctlWrapper; /** @brief uses the eMMC defined sanitize command, it is not the same as * vendor_sanitize */ void emmcSanitize(); /** @brief uses the eMMC defined erase command * * param[in] driveSize - size of the drive in bytes */ void emmcErase(uint64_t driveSize); }; // can't use the real mmc_ioc_multi_cmd b/c of zero length array // see uapi/linux/mmc/ioctl.h struct mmc_io_multi_cmd_erase { uint64_t num_of_cmds; struct mmc_ioc_cmd cmds[3]; // NOLINT (c arrays usage) }; } // namespace estoraged