Add Erase verifyGeometry
This confirms specified amount of the drive is accessible. The min and
max expected drive size are set as a build configuration, and compared
against the drive size (found by using the linux ioctl). Also adds
testing build files, testing options, and verifyGeometry test.
Tested: Ran eStoraged on a machine with an eMMC, using the following
$ ./eStoraged -b /dev/mmcblk0 &
$ busctl call xyz.openbmc_project.eStoraged.mmcblk0 \
/xyz/openbmc_project/storage/mmcblk0 \
xyz.openbmc_project.eStoraged Erase ays 1 1 \
xyz.openbmc_project.eStoraged.EraseMethod.VerifyGeometry
Signed-off-by: John Edward Broadbent <jebr@google.com>
Change-Id: Ie47f8666996a6085a115d1b86f2643bc278638c5
diff --git a/include/erase.hpp b/include/erase.hpp
new file mode 100644
index 0000000..699d430
--- /dev/null
+++ b/include/erase.hpp
@@ -0,0 +1,23 @@
+#include <string>
+
+/** @class Erase
+ * @brief Erase object provides a base class for the specific erase types
+ */
+class Erase
+{
+ public:
+ /** @brief creates an erase object
+ * @param inDevPath the linux path for the block device
+ */
+ Erase(std::string_view inDevPath) : devPath(inDevPath)
+ {}
+
+ /** @brief finds the size of the linux block device in bytes
+ * @return size of a block device using the devPath
+ */
+ uint64_t findSizeOfBlockDevice();
+
+ protected:
+ /* The linux path for the block device */
+ std::string devPath;
+};
diff --git a/include/meson.build b/include/meson.build
index da1595b..b879ead 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -1,2 +1,13 @@
eStoraged_headers = include_directories('.')
+
+conf_data = configuration_data()
+# If the number of drives increases we plan to switch to a config file design
+# in which, the max and min size are read and parsed for a config file at
+# verification time.
+conf_data.set('ERASE_MAX_GEOMETRY', get_option('erase_max_geometry'))
+conf_data.set('ERASE_MIN_GEOMETRY', get_option('erase_min_geometry'))
+
+configure_file(
+ output: 'estoraged_conf.hpp',
+ configuration: conf_data)
diff --git a/include/verifyDriveGeometry.hpp b/include/verifyDriveGeometry.hpp
new file mode 100644
index 0000000..3b16641
--- /dev/null
+++ b/include/verifyDriveGeometry.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "erase.hpp"
+
+#include <string_view>
+
+class VerifyDriveGeometry : public Erase
+{
+ public:
+ /** @brief Creates a verifyDriveGeomentry erase object.
+ *
+ * @param[in] inDevPath - the linux device path for the block device.
+ */
+ VerifyDriveGeometry(std::string_view inDevPath) : Erase(inDevPath)
+ {}
+
+ /** @brief Test if input is in between the max and min expected sizes,
+ * and throws errors accordingly.
+ *
+ * @param[in] bytes - Size of the block device
+ */
+ void geometryOkay(uint64_t bytes);
+};
diff --git a/meson.build b/meson.build
index 224b6ea..1a61027 100644
--- a/meson.build
+++ b/meson.build
@@ -12,6 +12,6 @@
eStoraged_root = meson.current_source_dir()
eStoraged_dbus_headers = include_directories('.')
-subdir('include/')
+subdir('include')
subdir('xyz/openbmc_project/eStoraged')
-subdir('src/')
+subdir('src')
diff --git a/meson_options.txt b/meson_options.txt
index 0fc2767..c0c3b2b 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1 +1,3 @@
+option ('erase_min_geometry', type : 'integer', min : 0, max : 18446744073709551615, value : 10, description : 'The min size allowed in bytes, used by the geometry check')
+option ('erase_max_geometry', type : 'integer', min : 0, max : 18446744073709551615, value : 5368709120, description : 'the max size allowed in bytes, used by the geometry check')
option('tests', type: 'feature', description: 'Build tests')
diff --git a/src/erase/erase.cpp b/src/erase/erase.cpp
new file mode 100644
index 0000000..3b6ce17
--- /dev/null
+++ b/src/erase/erase.cpp
@@ -0,0 +1,33 @@
+#include "erase.hpp"
+
+#include <linux/fs.h>
+
+#include <phosphor-logging/lg2.hpp>
+#include <stdplus/fd/create.hpp>
+#include <stdplus/fd/managed.hpp>
+#include <stdplus/handle/managed.hpp>
+#include <xyz/openbmc_project/eStoraged/error.hpp>
+
+using sdbusplus::xyz::openbmc_project::eStoraged::Error::EraseError;
+using stdplus::fd::ManagedFd;
+
+uint64_t Erase::findSizeOfBlockDevice()
+{
+ ManagedFd fd;
+ uint64_t bytes;
+ try
+ {
+ // open block dev
+ fd = stdplus::fd::open(devPath, stdplus::fd::OpenAccess::ReadOnly);
+ // get block size
+ fd.ioctl(BLKGETSIZE64, &bytes);
+ }
+ catch (...)
+ {
+ lg2::error("erase unable to open blockdev", "REDFISH_MESSAGE_ID",
+ std::string("OpenBMC.0.1.DriveEraseFailure"),
+ "REDFISH_MESSAGE_ARGS", std::to_string(fd.get()));
+ throw EraseError();
+ }
+ return bytes;
+}
diff --git a/src/erase/meson.build b/src/erase/meson.build
new file mode 100644
index 0000000..3c90ab9
--- /dev/null
+++ b/src/erase/meson.build
@@ -0,0 +1,14 @@
+libeStoragedErase_lib = static_library(
+ 'libeStoragedErase-lib',
+ 'verifyDriveGeometry.cpp',
+ 'erase.cpp',
+ include_directories : eStoraged_headers,
+ implicit_include_directories: false,
+ dependencies: [eStoraged_dbus, dependency('stdplus'),],
+)
+
+libeStoragedErase_dep = declare_dependency(
+ include_directories: eStoraged_headers,
+ link_with: libeStoragedErase_lib,
+)
+
diff --git a/src/erase/verifyDriveGeometry.cpp b/src/erase/verifyDriveGeometry.cpp
new file mode 100644
index 0000000..2996912
--- /dev/null
+++ b/src/erase/verifyDriveGeometry.cpp
@@ -0,0 +1,38 @@
+#include "verifyDriveGeometry.hpp"
+
+#include "estoraged_conf.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/eStoraged/error.hpp>
+
+#include <string>
+
+using sdbusplus::xyz::openbmc_project::eStoraged::Error::EraseError;
+
+void VerifyDriveGeometry::geometryOkay(uint64_t bytes)
+{
+ if (bytes > ERASE_MAX_GEOMETRY)
+ {
+ lg2::error("Erase verify Geometry too large", "REDFISH_MESSAGE_ID",
+ std::string("OpenBMC.0.1.DriveEraseFailure"),
+ "REDFISH_MESSAGE_ARGS",
+ std::to_string(bytes) + ">" +
+ std::to_string(ERASE_MAX_GEOMETRY));
+ throw EraseError();
+ }
+ else if (bytes < ERASE_MIN_GEOMETRY)
+ {
+ lg2::error(
+ "eStorageD erase verify Geometry too small", "REDFISH_MESSAGE_ID",
+ std::string("OpenBMC.0.1.DriveEraseFailure"),
+ "REDFISH_MESSAGE_ARGS",
+ std::to_string(bytes) + "<" + std::to_string(ERASE_MIN_GEOMETRY));
+ throw EraseError();
+ }
+ else
+ {
+ lg2::info("eStorageD erase verify Geometry in range",
+ "REDFISH_MESSAGE_ID",
+ std::string("OpenBMC.0.1.DriveEraseSuccess"));
+ }
+}
diff --git a/src/estoraged.cpp b/src/estoraged.cpp
index dcbb524..4e64ca6 100644
--- a/src/estoraged.cpp
+++ b/src/estoraged.cpp
@@ -2,6 +2,7 @@
#include "estoraged.hpp"
#include "cryptsetupInterface.hpp"
+#include "verifyDriveGeometry.hpp"
#include <libcryptsetup.h>
#include <openssl/rand.h>
@@ -15,6 +16,8 @@
#include <string_view>
#include <vector>
+using sdbusplus::xyz::openbmc_project::eStoraged::Error::EraseError;
+
namespace estoraged
{
@@ -42,11 +45,49 @@
mountFilesystem();
}
-void eStoraged::erase(std::vector<uint8_t>, EraseMethod)
+void eStoraged::erase(std::vector<uint8_t>, EraseMethod inEraseMethod)
{
std::cerr << "Erasing encrypted eMMC" << std::endl;
- std::string msg = "OpenBMC.0.1.DriveErase";
- lg2::info("Starting erase", "REDFISH_MESSAGE_ID", msg);
+ lg2::info("Starting erase", "REDFISH_MESSAGE_ID",
+ std::string("OpenBMC.0.1.DriveErase"));
+ switch (inEraseMethod)
+ {
+ case EraseMethod::CryptoErase:
+ {
+ break;
+ }
+ case EraseMethod::VerifyGeometry:
+ {
+ VerifyDriveGeometry myVerifyGeometry(devPath);
+ uint64_t size = myVerifyGeometry.findSizeOfBlockDevice();
+ myVerifyGeometry.geometryOkay(size);
+ break;
+ }
+ case EraseMethod::LogicalOverWrite:
+ {
+ break;
+ }
+ case EraseMethod::LogicalVerify:
+ {
+ break;
+ }
+ case EraseMethod::VendorSanitize:
+ {
+ break;
+ }
+ case EraseMethod::ZeroOverWrite:
+ {
+ break;
+ }
+ case EraseMethod::ZeroVerify:
+ {
+ break;
+ }
+ case EraseMethod::SecuredLocked:
+ {
+ break;
+ }
+ }
}
void eStoraged::lock(std::vector<uint8_t>)
@@ -79,8 +120,8 @@
void eStoraged::changePassword(std::vector<uint8_t>, std::vector<uint8_t>)
{
std::cerr << "Changing password for encrypted eMMC" << std::endl;
- std::string msg = "OpenBMC.0.1.DrivePasswordChanged";
- lg2::info("Starting change password", "REDFISH_MESSAGE_ID", msg);
+ lg2::info("Starting change password", "REDFISH_MESSAGE_ID",
+ std::string("OpenBMC.0.1.DrivePasswordChanged"));
}
bool eStoraged::isLocked() const
diff --git a/src/main.cpp b/src/main.cpp
index 318ecda..c23ff19 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -70,9 +70,8 @@
/* Create an eStoraged object. */
estoraged::eStoraged esObject{b, path.c_str(), physicalBlockDev,
containerBlockDev};
- std::string msg = "OpenBMC.1.0.ServiceStarted";
lg2::info("Storage management service is running", "REDFISH_MESSAGE_ID",
- msg);
+ std::string("OpenBMC.1.0.ServiceStarted"));
while (true)
{
diff --git a/src/meson.build b/src/meson.build
index 50a5c7c..1390536 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,4 +1,6 @@
+subdir('erase')
+
libeStoraged_deps = [
dependency('sdbusplus'),
dependency('phosphor-logging',
@@ -16,13 +18,14 @@
'estoraged.cpp',
include_directories : eStoraged_headers,
implicit_include_directories: false,
- dependencies: libeStoraged_deps,
+ dependencies: [libeStoraged_deps, libeStoragedErase_dep],
)
libeStoraged = declare_dependency(
dependencies: libeStoraged_deps,
include_directories: eStoraged_headers,
- link_with: libeStoraged_lib)
+ link_with: libeStoraged_lib,
+)
executable(
'eStoraged',
diff --git a/src/test/erase/verifyGeometry_test.cpp b/src/test/erase/verifyGeometry_test.cpp
new file mode 100644
index 0000000..1731e75
--- /dev/null
+++ b/src/test/erase/verifyGeometry_test.cpp
@@ -0,0 +1,27 @@
+#include "estoraged_conf.hpp"
+#include "verifyDriveGeometry.hpp"
+
+#include <xyz/openbmc_project/eStoraged/error.hpp>
+
+#include <gmock/gmock-matchers.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+using sdbusplus::xyz::openbmc_project::eStoraged::Error::EraseError;
+
+TEST(VerifyGeometry, TooBigFail)
+{
+ VerifyDriveGeometry maxVerify("");
+ EXPECT_THROW(maxVerify.geometryOkay(ERASE_MAX_GEOMETRY + 1), EraseError);
+}
+
+TEST(VerifyGeometry, TooSmallFail)
+{
+ VerifyDriveGeometry minVerify("");
+ EXPECT_THROW(minVerify.geometryOkay(ERASE_MIN_GEOMETRY - 1), EraseError);
+}
+
+TEST(VerifyGeometry, pass)
+{
+ VerifyDriveGeometry passVerify("");
+ EXPECT_NO_THROW(passVerify.geometryOkay(ERASE_MIN_GEOMETRY + 1));
+}
diff --git a/src/test/meson.build b/src/test/meson.build
index a4c23f7..8f05182 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -2,6 +2,7 @@
gmock = dependency('gmock', disabler: true, required: build_tests)
tests = [
+ 'erase/verifyGeometry_test',
'estoraged_test',
]