xref: /openbmc/estoraged/src/erase/zero.cpp (revision d6071fc25a9880e8b622792b1e48d83fb5010e5e)
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