xref: /openbmc/estoraged/src/erase/zero.cpp (revision 1e169d0cdf79269db9208a8e4cd594432641faab)
1 #include "zero.hpp"
2 
3 #include "erase.hpp"
4 
5 #include <unistd.h>
6 
7 #include <phosphor-logging/lg2.hpp>
8 #include <stdplus/fd/create.hpp>
9 #include <stdplus/fd/managed.hpp>
10 #include <xyz/openbmc_project/Common/error.hpp>
11 
12 #include <array>
13 #include <chrono>
14 #include <span>
15 #include <thread>
16 
17 namespace estoraged
18 {
19 
20 using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
21 using stdplus::fd::Fd;
22 
writeZero(const uint64_t driveSize,Fd & fd)23 void Zero::writeZero(const uint64_t driveSize, Fd& fd)
24 {
25     uint64_t currentIndex = 0;
26     const std::array<const std::byte, blockSize> blockOfZeros{};
27 
28     while (currentIndex < driveSize)
29     {
30         uint32_t writeSize = currentIndex + blockSize < driveSize
31                                  ? blockSize
32                                  : driveSize - currentIndex;
33         try
34         {
35             size_t written = 0;
36             size_t retry = 0;
37             while (written < writeSize)
38             {
39                 written += fd.write(std::span{blockOfZeros}.subspan(
40                                         written, writeSize - written))
41                                .size();
42                 if (written == writeSize)
43                 {
44                     break;
45                 }
46                 if (written > writeSize)
47                 {
48                     throw InternalFailure();
49                 }
50                 retry++;
51                 if (retry > maxRetry)
52                 {
53                     lg2::error("Unable to make full write",
54                                "REDFISH_MESSAGE_ID",
55                                std::string("eStorageD.1.0.EraseFailure"));
56                     throw InternalFailure();
57                 }
58                 std::this_thread::sleep_for(delay);
59             }
60         }
61         catch (...)
62         {
63             lg2::error("Estoraged erase zeros unable to write size",
64                        "REDFISH_MESSAGE_ID",
65                        std::string("eStorageD.1.0.EraseFailure"));
66             throw InternalFailure();
67         }
68         currentIndex += writeSize;
69     }
70 }
71 
verifyZero(uint64_t driveSize,Fd & fd)72 void Zero::verifyZero(uint64_t driveSize, Fd& fd)
73 {
74     uint64_t currentIndex = 0;
75     std::array<std::byte, blockSize> readArr{};
76     const std::array<const std::byte, blockSize> blockOfZeros{};
77 
78     while (currentIndex < driveSize)
79     {
80         uint32_t readSize = currentIndex + blockSize < driveSize
81                                 ? blockSize
82                                 : driveSize - currentIndex;
83         try
84         {
85             size_t read = 0;
86             size_t retry = 0;
87             while (read < readSize)
88             {
89                 read +=
90                     fd.read(std::span{readArr}.subspan(read, readSize - read))
91                         .size();
92                 if (read == readSize)
93                 {
94                     break;
95                 }
96                 if (read > readSize)
97                 {
98                     throw InternalFailure();
99                 }
100                 retry++;
101                 if (retry > maxRetry)
102                 {
103                     lg2::error("Unable to make full read", "REDFISH_MESSAGE_ID",
104                                std::string("eStorageD.1.0.EraseFailure"));
105                     throw InternalFailure();
106                 }
107                 std::this_thread::sleep_for(delay);
108             }
109         }
110         catch (...)
111         {
112             lg2::error("Estoraged erase zeros block unable to read size",
113                        "REDFISH_MESSAGE_ID",
114                        std::string("eStorageD.1.0.EraseFailure"));
115             throw InternalFailure();
116         }
117         if (memcmp(readArr.data(), blockOfZeros.data(), readSize) != 0)
118         {
119             lg2::error("Estoraged erase zeros block is not zero",
120                        "REDFISH_MESSAGE_ID",
121                        std::string("eStorageD.1.0.EraseFailure"));
122             throw InternalFailure();
123         }
124         currentIndex += readSize;
125     }
126 }
127 
128 } // namespace estoraged
129