14bc8a10cSJohn Edward Broadbent #include "zero.hpp"
24bc8a10cSJohn Edward Broadbent
34bc8a10cSJohn Edward Broadbent #include "erase.hpp"
44bc8a10cSJohn Edward Broadbent
5*d6071fc2SJohn Edward Broadbent #include <unistd.h>
6*d6071fc2SJohn Edward Broadbent
74bc8a10cSJohn Edward Broadbent #include <phosphor-logging/lg2.hpp>
84bc8a10cSJohn Edward Broadbent #include <stdplus/fd/create.hpp>
94bc8a10cSJohn Edward Broadbent #include <stdplus/fd/managed.hpp>
104bc8a10cSJohn Edward Broadbent #include <xyz/openbmc_project/Common/error.hpp>
114bc8a10cSJohn Edward Broadbent
124bc8a10cSJohn Edward Broadbent #include <array>
13*d6071fc2SJohn Edward Broadbent #include <chrono>
144bc8a10cSJohn Edward Broadbent #include <span>
15*d6071fc2SJohn Edward Broadbent #include <thread>
164bc8a10cSJohn Edward Broadbent
174bc8a10cSJohn Edward Broadbent namespace estoraged
184bc8a10cSJohn Edward Broadbent {
194bc8a10cSJohn Edward Broadbent
204bc8a10cSJohn Edward Broadbent using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
21*d6071fc2SJohn Edward Broadbent using stdplus::fd::Fd;
224bc8a10cSJohn Edward Broadbent
writeZero(const uint64_t driveSize,Fd & fd)23*d6071fc2SJohn Edward Broadbent void Zero::writeZero(const uint64_t driveSize, Fd& fd)
244bc8a10cSJohn Edward Broadbent {
254bc8a10cSJohn Edward Broadbent uint64_t currentIndex = 0;
264bc8a10cSJohn Edward Broadbent const std::array<const std::byte, blockSize> blockOfZeros{};
274bc8a10cSJohn Edward Broadbent
284bc8a10cSJohn Edward Broadbent while (currentIndex < driveSize)
294bc8a10cSJohn Edward Broadbent {
304bc8a10cSJohn Edward Broadbent uint32_t writeSize = currentIndex + blockSize < driveSize
314bc8a10cSJohn Edward Broadbent ? blockSize
324bc8a10cSJohn Edward Broadbent : driveSize - currentIndex;
334bc8a10cSJohn Edward Broadbent try
344bc8a10cSJohn Edward Broadbent {
35*d6071fc2SJohn Edward Broadbent size_t written = 0;
36*d6071fc2SJohn Edward Broadbent size_t retry = 0;
37*d6071fc2SJohn Edward Broadbent while (written < writeSize)
38*d6071fc2SJohn Edward Broadbent {
39*d6071fc2SJohn Edward Broadbent written += fd.write({blockOfZeros.data() + written,
40*d6071fc2SJohn Edward Broadbent writeSize - written})
41*d6071fc2SJohn Edward Broadbent .size();
42*d6071fc2SJohn Edward Broadbent if (written == writeSize)
43*d6071fc2SJohn Edward Broadbent {
44*d6071fc2SJohn Edward Broadbent break;
45*d6071fc2SJohn Edward Broadbent }
46*d6071fc2SJohn Edward Broadbent if (written > writeSize)
47*d6071fc2SJohn Edward Broadbent {
48*d6071fc2SJohn Edward Broadbent throw InternalFailure();
49*d6071fc2SJohn Edward Broadbent }
50*d6071fc2SJohn Edward Broadbent retry++;
51*d6071fc2SJohn Edward Broadbent if (retry > maxRetry)
52*d6071fc2SJohn Edward Broadbent {
53*d6071fc2SJohn Edward Broadbent lg2::error("Unable to make full write",
54*d6071fc2SJohn Edward Broadbent "REDFISH_MESSAGE_ID",
55*d6071fc2SJohn Edward Broadbent std::string("eStorageD.1.0.EraseFailure"));
56*d6071fc2SJohn Edward Broadbent throw InternalFailure();
57*d6071fc2SJohn Edward Broadbent }
58*d6071fc2SJohn Edward Broadbent std::this_thread::sleep_for(delay);
59*d6071fc2SJohn Edward Broadbent }
604bc8a10cSJohn Edward Broadbent }
614bc8a10cSJohn Edward Broadbent catch (...)
624bc8a10cSJohn Edward Broadbent {
634bc8a10cSJohn Edward Broadbent lg2::error("Estoraged erase zeros unable to write size",
644bc8a10cSJohn Edward Broadbent "REDFISH_MESSAGE_ID",
654bc8a10cSJohn Edward Broadbent std::string("eStorageD.1.0.EraseFailure"));
664bc8a10cSJohn Edward Broadbent throw InternalFailure();
674bc8a10cSJohn Edward Broadbent }
684bc8a10cSJohn Edward Broadbent currentIndex += writeSize;
694bc8a10cSJohn Edward Broadbent }
704bc8a10cSJohn Edward Broadbent }
714bc8a10cSJohn Edward Broadbent
verifyZero(uint64_t driveSize,Fd & fd)72*d6071fc2SJohn Edward Broadbent void Zero::verifyZero(uint64_t driveSize, Fd& fd)
734bc8a10cSJohn Edward Broadbent {
744bc8a10cSJohn Edward Broadbent uint64_t currentIndex = 0;
7582897c35SEd Tanous std::array<std::byte, blockSize> readArr{};
764bc8a10cSJohn Edward Broadbent const std::array<const std::byte, blockSize> blockOfZeros{};
774bc8a10cSJohn Edward Broadbent
784bc8a10cSJohn Edward Broadbent while (currentIndex < driveSize)
794bc8a10cSJohn Edward Broadbent {
804bc8a10cSJohn Edward Broadbent uint32_t readSize = currentIndex + blockSize < driveSize
814bc8a10cSJohn Edward Broadbent ? blockSize
824bc8a10cSJohn Edward Broadbent : driveSize - currentIndex;
834bc8a10cSJohn Edward Broadbent try
844bc8a10cSJohn Edward Broadbent {
85*d6071fc2SJohn Edward Broadbent size_t read = 0;
86*d6071fc2SJohn Edward Broadbent size_t retry = 0;
87*d6071fc2SJohn Edward Broadbent while (read < readSize)
88*d6071fc2SJohn Edward Broadbent {
89*d6071fc2SJohn Edward Broadbent read +=
90*d6071fc2SJohn Edward Broadbent fd.read({readArr.data() + read, readSize - read}).size();
91*d6071fc2SJohn Edward Broadbent if (read == readSize)
92*d6071fc2SJohn Edward Broadbent {
93*d6071fc2SJohn Edward Broadbent break;
94*d6071fc2SJohn Edward Broadbent }
95*d6071fc2SJohn Edward Broadbent if (read > readSize)
96*d6071fc2SJohn Edward Broadbent {
97*d6071fc2SJohn Edward Broadbent throw InternalFailure();
98*d6071fc2SJohn Edward Broadbent }
99*d6071fc2SJohn Edward Broadbent retry++;
100*d6071fc2SJohn Edward Broadbent if (retry > maxRetry)
101*d6071fc2SJohn Edward Broadbent {
102*d6071fc2SJohn Edward Broadbent lg2::error("Unable to make full read", "REDFISH_MESSAGE_ID",
103*d6071fc2SJohn Edward Broadbent std::string("eStorageD.1.0.EraseFailure"));
104*d6071fc2SJohn Edward Broadbent throw InternalFailure();
105*d6071fc2SJohn Edward Broadbent }
106*d6071fc2SJohn Edward Broadbent std::this_thread::sleep_for(delay);
107*d6071fc2SJohn Edward Broadbent }
1084bc8a10cSJohn Edward Broadbent }
1094bc8a10cSJohn Edward Broadbent catch (...)
1104bc8a10cSJohn Edward Broadbent {
1114bc8a10cSJohn Edward Broadbent lg2::error("Estoraged erase zeros block unable to read size",
1124bc8a10cSJohn Edward Broadbent "REDFISH_MESSAGE_ID",
1134bc8a10cSJohn Edward Broadbent std::string("eStorageD.1.0.EraseFailure"));
1144bc8a10cSJohn Edward Broadbent throw InternalFailure();
1154bc8a10cSJohn Edward Broadbent }
11682897c35SEd Tanous if (memcmp(readArr.data(), blockOfZeros.data(), readSize) != 0)
1174bc8a10cSJohn Edward Broadbent {
1184bc8a10cSJohn Edward Broadbent lg2::error("Estoraged erase zeros block is not zero",
1194bc8a10cSJohn Edward Broadbent "REDFISH_MESSAGE_ID",
1204bc8a10cSJohn Edward Broadbent std::string("eStorageD.1.0.EraseFailure"));
1214bc8a10cSJohn Edward Broadbent throw InternalFailure();
1224bc8a10cSJohn Edward Broadbent }
1234bc8a10cSJohn Edward Broadbent currentIndex += readSize;
1244bc8a10cSJohn Edward Broadbent }
1254bc8a10cSJohn Edward Broadbent }
1264bc8a10cSJohn Edward Broadbent
1274bc8a10cSJohn Edward Broadbent } // namespace estoraged
128