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