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},