Add zero write and verify
This code implements the zero verify and zero write dbus interface. The
goal is to fill the whole block device with zeros, then check to make
sure the operation worked correctly.
Tested:
$ systemctl stop emmc.service
$ ./eStoraged -b /dev/mmcblk0 &
$ time busctl call xyz.openbmc_project.eStoraged.mmcblk0 /xyz/openbmc_project/storage/mmcblk0 xyz.openbmc_project.Inventory.Item.Volume Erase s
xyz.openbmc_project.Inventory.Item.Volume.EraseMethod.ZeroOverWrite --timeout=1200
Erasing encrypted eMMC <6> Starting erase
real 5m59.695s
user 0m0.000s
sys 0m0.030s
root@ytbaz20-nfd01:~/jebr# hexdump /dev/mmcblk0
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
$ time busctl call xyz.openbmc_project.eStoraged.mmcblk0 /xyz/openbmc_project/storage/mmcblk0 xyz.openbmc_project.Inventory.Item.Volume Erase s
xyz.openbmc_project.Inventory.Item.Volume.EraseMethod.ZeroVerify --timeout=1200
Erasing encrypted eMMC
<6> Starting erase
real 5m46.920s
user 0m0.010s
sys 0m0.010s
$ echo "not zero" > /dev/mmcblk0
$ time busctl call xyz.openbmc_project.eStoraged.mmcblk0 /xyz/openbmc_project/storage/mmcblk0 xyz.openbmc_project.Inventory.Item.Volume Erase s
xyz.openbmc_project.Inventory.Item.Volume.EraseMethod.ZeroVerify --timeout=1200
Erasing encrypted eMMC
<6> Starting erase
<3> Estoraged erase zeros block is not zero
Call failed: The operation failed internally.
real 0m0.022s
user 0m0.000s
sys 0m0.020s
Change-Id: Ie78ad427de1aa75472fc7ddd72d094866fe14b66
Signed-off-by: John Edward Broadbent <jebr@google.com>
diff --git a/src/erase/zero.cpp b/src/erase/zero.cpp
new file mode 100644
index 0000000..accb8c8
--- /dev/null
+++ b/src/erase/zero.cpp
@@ -0,0 +1,78 @@
+#include "zero.hpp"
+
+#include "erase.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <stdplus/fd/create.hpp>
+#include <stdplus/fd/managed.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <array>
+#include <span>
+
+namespace estoraged
+{
+
+using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+using stdplus::fd::ManagedFd;
+
+void Zero::writeZero(const uint64_t driveSize, ManagedFd& fd)
+{
+
+ uint64_t currentIndex = 0;
+ const std::array<const std::byte, blockSize> blockOfZeros{};
+
+ while (currentIndex < driveSize)
+ {
+ uint32_t writeSize = currentIndex + blockSize < driveSize
+ ? blockSize
+ : driveSize - currentIndex;
+ try
+ {
+ fd.write({blockOfZeros.data(), writeSize});
+ }
+ catch (...)
+ {
+ lg2::error("Estoraged erase zeros unable to write size",
+ "REDFISH_MESSAGE_ID",
+ std::string("eStorageD.1.0.EraseFailure"));
+ throw InternalFailure();
+ }
+ currentIndex += writeSize;
+ }
+}
+
+void Zero::verifyZero(uint64_t driveSize, ManagedFd& fd)
+{
+ uint64_t currentIndex = 0;
+ std::array<std::byte, blockSize> readArr;
+ const std::array<const std::byte, blockSize> blockOfZeros{};
+
+ while (currentIndex < driveSize)
+ {
+ uint32_t readSize = currentIndex + blockSize < driveSize
+ ? blockSize
+ : driveSize - currentIndex;
+ try
+ {
+ fd.read({readArr.data(), readSize});
+ }
+ catch (...)
+ {
+ lg2::error("Estoraged erase zeros block unable to read size",
+ "REDFISH_MESSAGE_ID",
+ std::string("eStorageD.1.0.EraseFailure"));
+ throw InternalFailure();
+ }
+ if (memcmp(readArr.data(), blockOfZeros.data(), readSize))
+ {
+ lg2::error("Estoraged erase zeros block is not zero",
+ "REDFISH_MESSAGE_ID",
+ std::string("eStorageD.1.0.EraseFailure"));
+ throw InternalFailure();
+ }
+ currentIndex += readSize;
+ }
+}
+
+} // namespace estoraged