diff options
| author | Sandeep Patil <sspatil@google.com> | 2018-12-18 09:36:53 -0800 |
|---|---|---|
| committer | Sandeep Patil <sspatil@google.com> | 2018-12-19 08:51:59 -0800 |
| commit | 2d04ce3b5ab2f0ce80cdff54936b5b89cbeec5d6 (patch) | |
| tree | 1cf5e08a065fb472f55347faa47ec5e1ca0af391 | |
| parent | 958a669e58ebd9ac6eed1e9423c020cb23a4a746 (diff) | |
| download | system_core-2d04ce3b5ab2f0ce80cdff54936b5b89cbeec5d6.tar.gz system_core-2d04ce3b5ab2f0ce80cdff54936b5b89cbeec5d6.tar.bz2 system_core-2d04ce3b5ab2f0ce80cdff54936b5b89cbeec5d6.zip | |
dmctl: Add verbose 'dmctl list devices'
This adds an option to list device mapper devices including their
current target table. Useful to be included in bugreport to
map the logical partitions metadata with actual device mapper setup.
Bug: 120916687
Test: dmctl list devices -v
Change-Id: I091666506d24372d1e111ffa1c0256c8bbff0c5e
Signed-off-by: Sandeep Patil <sspatil@google.com>
| -rw-r--r-- | fs_mgr/libdm/dm.cpp | 15 | ||||
| -rw-r--r-- | fs_mgr/libdm/include/libdm/dm.h | 6 | ||||
| -rw-r--r-- | fs_mgr/tools/dmctl.cpp | 35 |
3 files changed, 49 insertions, 7 deletions
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp index c4b57c778..d9786add1 100644 --- a/fs_mgr/libdm/dm.cpp +++ b/fs_mgr/libdm/dm.cpp @@ -203,7 +203,8 @@ bool DeviceMapper::GetAvailableTargets(std::vector<DmTargetTypeInfo>* targets) { } next += vers->next; data_size -= vers->next; - vers = reinterpret_cast<struct dm_target_versions*>(static_cast<char*>(buffer.get()) + next); + vers = reinterpret_cast<struct dm_target_versions*>(static_cast<char*>(buffer.get()) + + next); } return true; @@ -288,12 +289,23 @@ bool DeviceMapper::GetDmDevicePathByName(const std::string& name, std::string* p } bool DeviceMapper::GetTableStatus(const std::string& name, std::vector<TargetInfo>* table) { + return GetTable(name, 0, table); +} + +bool DeviceMapper::GetTableInfo(const std::string& name, std::vector<TargetInfo>* table) { + return GetTable(name, DM_STATUS_TABLE_FLAG, table); +} + +// private methods of DeviceMapper +bool DeviceMapper::GetTable(const std::string& name, uint32_t flags, + std::vector<TargetInfo>* table) { char buffer[4096]; struct dm_ioctl* io = reinterpret_cast<struct dm_ioctl*>(buffer); InitIo(io, name); io->data_size = sizeof(buffer); io->data_start = sizeof(*io); + io->flags = flags; if (ioctl(fd_, DM_TABLE_STATUS, io) < 0) { PLOG(ERROR) << "DM_TABLE_STATUS failed for " << name; return false; @@ -327,7 +339,6 @@ bool DeviceMapper::GetTableStatus(const std::string& name, std::vector<TargetInf return true; } -// private methods of DeviceMapper void DeviceMapper::InitIo(struct dm_ioctl* io, const std::string& name) const { CHECK(io != nullptr) << "nullptr passed to dm_ioctl initialization"; memset(io, 0, sizeof(*io)); diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h index 91f8bb422..28e6e011c 100644 --- a/fs_mgr/libdm/include/libdm/dm.h +++ b/fs_mgr/libdm/include/libdm/dm.h @@ -128,6 +128,10 @@ class DeviceMapper final { }; bool GetTableStatus(const std::string& name, std::vector<TargetInfo>* table); + // Identical to GetTableStatus, except also retrives the active table for the device + // mapper device from the kernel. + bool GetTableInfo(const std::string& name, std::vector<TargetInfo>* table); + private: // Maximum possible device mapper targets registered in the kernel. // This is only used to read the list of targets from kernel so we allocate @@ -140,6 +144,8 @@ class DeviceMapper final { // limit we are imposing here of 256. static constexpr uint32_t kMaxPossibleDmDevices = 256; + bool GetTable(const std::string& name, uint32_t flags, std::vector<TargetInfo>* table); + void InitIo(struct dm_ioctl* io, const std::string& name = std::string()) const; DeviceMapper(); diff --git a/fs_mgr/tools/dmctl.cpp b/fs_mgr/tools/dmctl.cpp index f78093bdf..3b6ff9b95 100644 --- a/fs_mgr/tools/dmctl.cpp +++ b/fs_mgr/tools/dmctl.cpp @@ -36,6 +36,8 @@ #include <string> #include <vector> +using namespace std::literals::string_literals; + using DeviceMapper = ::android::dm::DeviceMapper; using DmTable = ::android::dm::DmTable; using DmTarget = ::android::dm::DmTarget; @@ -51,7 +53,7 @@ static int Usage(void) { std::cerr << "commands:" << std::endl; std::cerr << " create <dm-name> [-ro] <targets...>" << std::endl; std::cerr << " delete <dm-name>" << std::endl; - std::cerr << " list <devices | targets>" << std::endl; + std::cerr << " list <devices | targets> [-v]" << std::endl; std::cerr << " getpath <dm-name>" << std::endl; std::cerr << " table <dm-name>" << std::endl; std::cerr << " help" << std::endl; @@ -197,7 +199,8 @@ static int DmDeleteCmdHandler(int argc, char** argv) { return 0; } -static int DmListTargets(DeviceMapper& dm) { +static int DmListTargets(DeviceMapper& dm, [[maybe_unused]] int argc, + [[maybe_unused]] char** argv) { std::vector<DmTargetTypeInfo> targets; if (!dm.GetAvailableTargets(&targets)) { std::cerr << "Failed to read available device mapper targets" << std::endl; @@ -218,7 +221,7 @@ static int DmListTargets(DeviceMapper& dm) { return 0; } -static int DmListDevices(DeviceMapper& dm) { +static int DmListDevices(DeviceMapper& dm, int argc, char** argv) { std::vector<DmBlockDevice> devices; if (!dm.GetAvailableDevices(&devices)) { std::cerr << "Failed to read available device mapper devices" << std::endl; @@ -230,15 +233,37 @@ static int DmListDevices(DeviceMapper& dm) { return 0; } + bool verbose = (argc && (argv[0] == "-v"s)); for (const auto& dev : devices) { std::cout << std::left << std::setw(20) << dev.name() << " : " << dev.Major() << ":" << dev.Minor() << std::endl; + if (verbose) { + std::vector<DeviceMapper::TargetInfo> table; + if (!dm.GetTableInfo(dev.name(), &table)) { + std::cerr << "Could not query table status for device \"" << dev.name() << "\"." + << std::endl; + return -EINVAL; + } + + uint32_t target_num = 1; + for (const auto& target : table) { + std::cout << " target#" << target_num << ": "; + std::cout << target.spec.sector_start << "-" + << (target.spec.sector_start + target.spec.length) << ": " + << target.spec.target_type; + if (!target.data.empty()) { + std::cout << ", " << target.data; + } + std::cout << std::endl; + target_num++; + } + } } return 0; } -static const std::map<std::string, std::function<int(DeviceMapper&)>> listmap = { +static const std::map<std::string, std::function<int(DeviceMapper&, int, char**)>> listmap = { {"targets", DmListTargets}, {"devices", DmListDevices}, }; @@ -251,7 +276,7 @@ static int DmListCmdHandler(int argc, char** argv) { DeviceMapper& dm = DeviceMapper::Instance(); for (const auto& l : listmap) { - if (l.first == argv[0]) return l.second(dm); + if (l.first == argv[0]) return l.second(dm, argc - 1, argv + 1); } std::cerr << "Invalid argument to \'dmctl list\': " << argv[0] << std::endl; |
