blob: 7ec5a4a8af1ccf98a4aa18d83f38aff4eb695fd1 [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
20using stdplus::fd::ManagedFd;
21
22class 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
55class 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
72class 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 {
John Edward Broadbent5d799bb2022-03-22 16:14:24 -070099 doSanitize(util::findSizeOfBlockDevice(devPath));
John Edward Broadbent605085a2021-11-05 13:45:45 -0700100 }
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
119struct 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