diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp index 8bd3b9de0..b96f4c1e2 100644 --- a/fs_mgr/libdm/dm.cpp +++ b/fs_mgr/libdm/dm.cpp @@ -17,6 +17,7 @@ #include "libdm/dm.h" #include +#include #include #include @@ -258,8 +259,17 @@ bool DeviceMapper::GetAvailableDevices(std::vector* devices) { // Accepts a device mapper device name (like system_a, vendor_b etc) and // returns the path to it's device node (or symlink to the device node) -std::string DeviceMapper::GetDmDevicePathByName(const std::string& /* name */) { - return ""; +bool DeviceMapper::GetDmDevicePathByName(const std::string& name, std::string* path) { + struct dm_ioctl io; + InitIo(&io, name); + if (ioctl(fd_, DM_DEV_STATUS, &io) < 0) { + PLOG(ERROR) << "DM_DEV_STATUS failed for " << name; + return false; + } + + uint32_t dev_num = minor(io.dev); + *path = "/dev/block/dm-" + std::to_string(dev_num); + return true; } // private methods of DeviceMapper diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h index 8d23b2cf0..60bceed94 100644 --- a/fs_mgr/libdm/include/libdm/dm.h +++ b/fs_mgr/libdm/include/libdm/dm.h @@ -104,8 +104,9 @@ class DeviceMapper final { bool GetAvailableDevices(std::vector* devices); // Returns the path to the device mapper device node in '/dev' corresponding to - // 'name'. - std::string GetDmDevicePathByName(const std::string& name); + // 'name'. If the device does not exist, false is returned, and the path + // parameter is not set. + bool GetDmDevicePathByName(const std::string& name, std::string* path); // The only way to create a DeviceMapper object. static DeviceMapper& Instance(); diff --git a/fs_mgr/tools/dmctl.cpp b/fs_mgr/tools/dmctl.cpp index c15173f45..9d48b8c61 100644 --- a/fs_mgr/tools/dmctl.cpp +++ b/fs_mgr/tools/dmctl.cpp @@ -49,6 +49,7 @@ static int Usage(void) { std::cerr << " create [-ro] " << std::endl; std::cerr << " delete " << std::endl; std::cerr << " list " << std::endl; + std::cerr << " getpath " << std::endl; std::cerr << " help" << std::endl; std::cerr << std::endl; std::cerr << "Target syntax:" << std::endl; @@ -241,11 +242,30 @@ static int HelpCmdHandler(int /* argc */, char** /* argv */) { return 0; } +static int GetPathCmdHandler(int argc, char** argv) { + if (argc != 1) { + std::cerr << "Invalid arguments, see \'dmctl help\'" << std::endl; + return -EINVAL; + } + + DeviceMapper& dm = DeviceMapper::Instance(); + std::string path; + if (!dm.GetDmDevicePathByName(argv[0], &path)) { + std::cerr << "Could not query path of device \"" << argv[0] << "\"." << std::endl; + return -EINVAL; + } + std::cout << path << std::endl; + return 0; +} + static std::map> cmdmap = { + // clang-format off {"create", DmCreateCmdHandler}, {"delete", DmDeleteCmdHandler}, {"list", DmListCmdHandler}, {"help", HelpCmdHandler}, + {"getpath", GetPathCmdHandler}, + // clang-format on }; int main(int argc, char** argv) {