xref: /openbmc/estoraged/include/sanitize.hpp (revision 67a47446)
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::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