blob: 91cf103395c3b896cb4f02e39d1b2a408342e286 [file] [log] [blame]
John Edward Broadbent605085a2021-11-05 13:45:45 -07001#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
17namespace estoraged
18{
19
John Edward Broadbent605085a2021-11-05 13:45:45 -070020class 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
53class 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
70class 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 {
John Edward Broadbent5d799bb2022-03-22 16:14:24 -070097 doSanitize(util::findSizeOfBlockDevice(devPath));
John Edward Broadbent605085a2021-11-05 13:45:45 -070098 }
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
117struct 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