Check if mount point already exists
Typically, we create the mount point directory when we mount the
filesystem, and then we remove the directory when we unmount. Currently,
we aren't accounting for the case where the directory already exists,
e.g. if the BMC reboots while the filesystem is mounted.
This commit adds a check to see if the directory is already present. If
so, it won't try to create the directory again.
Tested:
1. Formatted an eMMC using the FormatLuks method, which also creates the
mount point and mounts the filesystem.
2. Rebooted the BMC
3. Ran the Unlock method to unlock the LUKS device and mount the
filesystem.
Signed-off-by: John Wedig <johnwedig@google.com>
Change-Id: I3e279c653b21f570b97e4d530a19e5ae30bf8719
diff --git a/src/estoraged.cpp b/src/estoraged.cpp
index 777232a..55a08a4 100644
--- a/src/estoraged.cpp
+++ b/src/estoraged.cpp
@@ -250,14 +250,22 @@
void eStoraged::mountFilesystem()
{
- /* Create directory for the filesystem. */
- bool success = fsIface->createDirectory(std::filesystem::path(mountPoint));
- if (!success)
+ /*
+ * Create directory for the filesystem, if it's not already present. It
+ * might already exist if, for example, the BMC reboots after creating the
+ * directory.
+ */
+ if (!fsIface->directoryExists(std::filesystem::path(mountPoint)))
{
- lg2::error("Failed to create mount point: {DIR}", "DIR", mountPoint,
- "REDFISH_MESSAGE_ID",
- std::string("OpenBMC.0.1.MountFilesystemFail"));
- throw InternalFailure();
+ bool success =
+ fsIface->createDirectory(std::filesystem::path(mountPoint));
+ if (!success)
+ {
+ lg2::error("Failed to create mount point: {DIR}", "DIR", mountPoint,
+ "REDFISH_MESSAGE_ID",
+ std::string("OpenBMC.0.1.MountFilesystemFail"));
+ throw InternalFailure();
+ }
}
/* Run the command to mount the filesystem. */
diff --git a/src/test/estoraged_test.cpp b/src/test/estoraged_test.cpp
index 6b93a88..3b23215 100644
--- a/src/test/estoraged_test.cpp
+++ b/src/test/estoraged_test.cpp
@@ -40,6 +40,9 @@
MOCK_METHOD(bool, removeDirectory, (const std::filesystem::path& p),
(override));
+
+ MOCK_METHOD(bool, directoryExists, (const std::filesystem::path& p),
+ (override));
};
class MockCryptsetupInterface : public estoraged::CryptsetupInterface
@@ -173,6 +176,9 @@
EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
+ EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
+ .WillOnce(Return(false));
+
EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
.WillOnce(Return(true));
@@ -197,6 +203,56 @@
EXPECT_TRUE(esObject->isLocked());
}
+/*
+ * Test case where the mount point directory already exists, so it shouldn't
+ * try to create it.
+ */
+TEST_F(eStoragedTest, MountPointExistsPass)
+{
+ EXPECT_CALL(sdbusMock,
+ sd_bus_emit_properties_changed_strv(
+ IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
+ .WillRepeatedly(Return(0));
+
+ EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
+
+ EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
+ .Times(1);
+
+ EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
+
+ EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
+ .Times(1);
+
+ EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
+
+ EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
+ .WillOnce(Return(true));
+
+ EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
+ .Times(0);
+
+ EXPECT_CALL(*mockFsIface,
+ doMount(ContainsRegex("/dev/mapper/"),
+ StrEq(esObject->getMountPoint()), _, _, _))
+ .WillOnce(Return(0));
+
+ EXPECT_CALL(*mockFsIface, doUnmount(StrEq(esObject->getMountPoint())))
+ .WillOnce(Return(0));
+
+ EXPECT_CALL(*mockFsIface, removeDirectory(path(esObject->getMountPoint())))
+ .WillOnce(Return(true));
+
+ EXPECT_CALL(*mockCryptIface, cryptDeactivate(_, _)).Times(1);
+
+ /* Format the encrypted device. */
+ esObject->formatLuks(password, Volume::FilesystemType::ext4);
+ EXPECT_FALSE(esObject->isLocked());
+
+ esObject->lock();
+ EXPECT_TRUE(esObject->isLocked());
+}
+
/* Test case where the device/file doesn't exist. */
TEST_F(eStoragedTest, FormatNoDeviceFail)
{
@@ -330,6 +386,9 @@
EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
+ EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
+ .WillOnce(Return(false));
+
EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
.WillOnce(Return(false));
@@ -358,6 +417,9 @@
EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
+ EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
+ .WillOnce(Return(false));
+
EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
.WillOnce(Return(true));
@@ -394,6 +456,9 @@
EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
+ EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
+ .WillOnce(Return(false));
+
EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
.WillOnce(Return(true));
@@ -432,6 +497,9 @@
EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
+ EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
+ .WillOnce(Return(false));
+
EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
.WillOnce(Return(true));
@@ -474,6 +542,9 @@
EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
+ EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
+ .WillOnce(Return(false));
+
EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
.WillOnce(Return(true));