xref: /openbmc/estoraged/include/sanitize.hpp (revision 15b63e12)
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     /** @brief 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      */
Sanitize(std::string_view inDevPath,std::unique_ptr<IOCTLWrapperInterface> inIOCTL=std::make_unique<IOCTLWrapperImpl> ())79     Sanitize(std::string_view inDevPath,
80              std::unique_ptr<IOCTLWrapperInterface> inIOCTL =
81                  std::make_unique<IOCTLWrapperImpl>()) :
82         Erase(inDevPath), ioctlWrapper(std::move(inIOCTL))
83     {}
84 
85     /** @brief sanitize the drive, using eMMC specified erase commands
86      *
87      * param[in] driveSize - size of the drive in bytes
88      */
89     void doSanitize(uint64_t driveSize);
90 
91     /** @brief sanitize the drive, using eMMC specified erase commands
92      *   This function uses the built in utils to call sanitize
93      */
doSanitize()94     void doSanitize()
95     {
96         doSanitize(util::findSizeOfBlockDevice(devPath));
97     }
98 
99   private:
100     /* Wrapper for ioctl*/
101     std::unique_ptr<IOCTLWrapperInterface> ioctlWrapper;
102 
103     /** @brief uses the eMMC defined sanitize command, it is not the same as
104      * vendor_sanitize  */
105     void emmcSanitize();
106 
107     /** @brief uses the eMMC defined erase command
108      *
109      * param[in] driveSize - size of the drive in bytes
110      */
111     void emmcErase(uint64_t driveSize);
112 };
113 
114 // can't use the real mmc_ioc_multi_cmd b/c of zero length array
115 // see uapi/linux/mmc/ioctl.h
116 struct mmc_io_multi_cmd_erase
117 {
118     uint64_t num_of_cmds;
119     struct mmc_ioc_cmd cmds[3]; // NOLINT (c arrays usage)
120 };
121 
122 } // namespace estoraged
123