blob: 7ec5a4a8af1ccf98a4aa18d83f38aff4eb695fd1 [file] [log] [blame]
#pragma once
#include "erase.hpp"
#include <linux/mmc/ioctl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <stdplus/fd/managed.hpp>
#include <util.hpp>
#include <array>
#include <cstddef>
#include <span>
#include <string_view>
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<IOCTLWrapperInterface> inIOCTL =
std::make_unique<IOCTLWrapperImpl>()) :
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::findSizeOfBlockDevice(devPath));
}
private:
/* Wrapper for ioctl*/
std::unique_ptr<IOCTLWrapperInterface> 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