xref: /openbmc/estoraged/include/sanitize.hpp (revision 0ff7100b)
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 class 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
53 class 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 
70 class 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     {
97         doSanitize(util::findSizeOfBlockDevice(devPath));
98     }
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
117 struct 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
124