From 7dd8fe8e7019b161b9b0bdca20be6897203d2438 Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Wed, 12 Aug 2020 12:49:44 -0700 Subject: [PATCH] Add "dmctl uuid" command This makes looking up device UUIDs a bit easier, as rather than depending on the device mapper's sysfs layout we can depend on dmctl. There's some associated libdm plumbing, but the UUID was already pretty much availiable. Test: I just ran this by hand. Signed-off-by: Palmer Dabbelt Change-Id: I7028eec6ab04601308047b67057e51a0ff44c0a7 --- fs_mgr/libdm/dm.cpp | 14 ++++++++++++++ fs_mgr/libdm/include/libdm/dm.h | 7 +++++++ fs_mgr/tools/dmctl.cpp | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp index 791268849..78a9005a1 100644 --- a/fs_mgr/libdm/dm.cpp +++ b/fs_mgr/libdm/dm.cpp @@ -427,6 +427,20 @@ bool DeviceMapper::GetDmDevicePathByName(const std::string& name, std::string* p return true; } +// Accepts a device mapper device name (like system_a, vendor_b etc) and +// returns its UUID. +bool DeviceMapper::GetDmDeviceUUIDByName(const std::string& name, std::string* uuid) { + 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; + } + + *uuid = std::string(io.uuid); + return true; +} + bool DeviceMapper::GetDeviceNumber(const std::string& name, dev_t* dev) { struct dm_ioctl io; InitIo(&io, name); diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h index abe9c4cda..0b2553fc7 100644 --- a/fs_mgr/libdm/include/libdm/dm.h +++ b/fs_mgr/libdm/include/libdm/dm.h @@ -172,6 +172,13 @@ class DeviceMapper final { // could race with ueventd. bool GetDmDevicePathByName(const std::string& name, std::string* path); + // Returns the device mapper UUID for a given name. If the device does not + // exist, false is returned, and the path parameter is not set. + // + // WaitForFile() should not be used in conjunction with this call, since it + // could race with ueventd. + bool GetDmDeviceUUIDByName(const std::string& name, std::string* path); + // Returns a device's unique path as generated by ueventd. This will return // true as long as the device has been created, even if ueventd has not // processed it yet. diff --git a/fs_mgr/tools/dmctl.cpp b/fs_mgr/tools/dmctl.cpp index 7a3d9a930..1bfd9b2c5 100644 --- a/fs_mgr/tools/dmctl.cpp +++ b/fs_mgr/tools/dmctl.cpp @@ -49,6 +49,7 @@ static int Usage(void) { std::cerr << " delete " << std::endl; std::cerr << " list [-v]" << std::endl; std::cerr << " getpath " << std::endl; + std::cerr << " getuuid " << std::endl; std::cerr << " info " << std::endl; std::cerr << " status " << std::endl; std::cerr << " resume " << std::endl; @@ -391,6 +392,22 @@ static int GetPathCmdHandler(int argc, char** argv) { return 0; } +static int GetUUIDCmdHandler(int argc, char** argv) { + if (argc != 1) { + std::cerr << "Invalid arguments, see \'dmctl help\'" << std::endl; + return -EINVAL; + } + + DeviceMapper& dm = DeviceMapper::Instance(); + std::string uuid; + if (!dm.GetDmDeviceUUIDByName(argv[0], &uuid)) { + std::cerr << "Could not query uuid of device \"" << argv[0] << "\"." << std::endl; + return -EINVAL; + } + std::cout << uuid << std::endl; + return 0; +} + static int InfoCmdHandler(int argc, char** argv) { if (argc != 1) { std::cerr << "Invalid arguments, see \'dmctl help\'" << std::endl; @@ -504,6 +521,7 @@ static std::map> cmdmap = { {"list", DmListCmdHandler}, {"help", HelpCmdHandler}, {"getpath", GetPathCmdHandler}, + {"getuuid", GetUUIDCmdHandler}, {"info", InfoCmdHandler}, {"table", TableCmdHandler}, {"status", StatusCmdHandler},