libdm: Add helpers for getting the device number of a dm device.
device-mapper will accept a "major:minor" string in place of a path for
any target parameter that specifies another block devie. This is useful
to have a helper for, since it lets us avoid a call to WaitForFile().
Bug: 134536978
Test: manual test
Change-Id: I13fd6699dd5d405bfa676830825b006b7810aa0f
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index c8c2d83..21255df 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -46,6 +46,7 @@
static_libs: [
"libdm",
"libbase",
+ "libfs_mgr",
"liblog",
],
srcs: [
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index c2917a4..788039d 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -302,6 +302,26 @@
return true;
}
+bool DeviceMapper::GetDeviceNumber(const std::string& name, dev_t* dev) {
+ struct dm_ioctl io;
+ InitIo(&io, name);
+ if (ioctl(fd_, DM_DEV_STATUS, &io) < 0) {
+ PLOG(WARNING) << "DM_DEV_STATUS failed for " << name;
+ return false;
+ }
+ *dev = io.dev;
+ return true;
+}
+
+bool DeviceMapper::GetDeviceString(const std::string& name, std::string* dev) {
+ dev_t num;
+ if (!GetDeviceNumber(name, &num)) {
+ return false;
+ }
+ *dev = std::to_string(major(num)) + ":" + std::to_string(minor(num));
+ return true;
+}
+
bool DeviceMapper::GetTableStatus(const std::string& name, std::vector<TargetInfo>* table) {
return GetTable(name, 0, table);
}
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index dc47c33..6219923 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -132,8 +132,8 @@
// Define a 2-sector device, with each sector mapping to the first sector
// of one of our loop devices.
DmTable table;
- ASSERT_TRUE(table.AddTarget(make_unique<DmTargetLinear>(0, 1, loop_a.device(), 0)));
- ASSERT_TRUE(table.AddTarget(make_unique<DmTargetLinear>(1, 1, loop_b.device(), 0)));
+ ASSERT_TRUE(table.Emplace<DmTargetLinear>(0, 1, loop_a.device(), 0));
+ ASSERT_TRUE(table.Emplace<DmTargetLinear>(1, 1, loop_b.device(), 0));
ASSERT_TRUE(table.valid());
TempDevice dev("libdm-test-dm-linear", table);
@@ -141,6 +141,16 @@
ASSERT_FALSE(dev.path().empty());
ASSERT_TRUE(dev.WaitForUdev());
+ auto& dm = DeviceMapper::Instance();
+
+ dev_t dev_number;
+ ASSERT_TRUE(dm.GetDeviceNumber(dev.name(), &dev_number));
+ ASSERT_NE(dev_number, 0);
+
+ std::string dev_string;
+ ASSERT_TRUE(dm.GetDeviceString(dev.name(), &dev_string));
+ ASSERT_FALSE(dev_string.empty());
+
// Note: a scope is needed to ensure that there are no open descriptors
// when we go to close the device.
{
@@ -157,7 +167,6 @@
}
// Test GetTableStatus.
- DeviceMapper& dm = DeviceMapper::Instance();
vector<DeviceMapper::TargetInfo> targets;
ASSERT_TRUE(dm.GetTableStatus(dev.name(), &targets));
ASSERT_EQ(targets.size(), 2);
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index d7e8aa9..3d223e3 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -20,6 +20,7 @@
#include <fcntl.h>
#include <linux/dm-ioctl.h>
#include <linux/kdev_t.h>
+#include <linux/types.h>
#include <stdint.h>
#include <sys/sysmacros.h>
#include <unistd.h>
@@ -111,6 +112,13 @@
// parameter is not set.
bool GetDmDevicePathByName(const std::string& name, std::string* path);
+ // Returns the dev_t for the named device-mapper node.
+ bool GetDeviceNumber(const std::string& name, dev_t* dev);
+
+ // Returns a major:minor string for the named device-mapper node, that can
+ // be used as inputs to DmTargets that take a block device.
+ bool GetDeviceString(const std::string& name, std::string* dev);
+
// The only way to create a DeviceMapper object.
static DeviceMapper& Instance();