Merge "dmctl: Add verbose 'dmctl list devices'" am: 16845e6c51
am: 6c21c66722
Change-Id: I6931551ee303e4cddbab8d37fbbae8a01a016327
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index c4b57c7..d9786ad 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -203,7 +203,8 @@
}
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::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 @@
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 91f8bb4..28e6e01 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -128,6 +128,10 @@
};
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 @@
// 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 f78093b..3b6ff9b 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 @@
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 @@
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 @@
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 @@
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 @@
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;