mappertool: add getancestors subcommand
Add a 'getancestors' subcommand that wraps the mapper's GetAncestors
D-Bus method. Given an object path, it prints each ancestor object
found in the mapper, along with the services that own it and the
interfaces each service implements there.
An optional -i/--interface flag (repeatable) restricts the output
to ancestors that implement a specific interface.
Usage: mappertool getancestors <path>
mappertool getancestors <path> -i <interface>
Change-Id: I1c5d70b4fdc4a922835aba6f0a0eaa90936c7fdb
Signed-off-by: Yash Patel <yash.pateltx@gmail.com>
diff --git a/src/mappertool.cpp b/src/mappertool.cpp
index a17acfe..f90851b 100644
--- a/src/mappertool.cpp
+++ b/src/mappertool.cpp
@@ -18,6 +18,8 @@
* mappertool getsubtree <subtree> list objects with services/ifaces
* mappertool getsubtree <subtree> -d N limit depth
* mappertool getsubtree <subtree> -i <if> filter by interface
+ * mappertool getancestors <path> list ancestor objects
+ * mappertool getancestors <path> -i <if> filter by interface
*/
#include <CLI/CLI.hpp>
@@ -351,6 +353,47 @@
}
}
+static void getAncestors(const std::string& path,
+ const std::vector<std::string>& interfaces)
+{
+ auto bus = sdbusplus::bus::new_default();
+
+ auto req = bus.new_method_call(mapperService, mapperObj, mapperIface,
+ "GetAncestors");
+ req.append(path, interfaces);
+
+ SubTreeType result;
+ try
+ {
+ auto reply = bus.call(req);
+ reply.read(result);
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ std::println(stderr, "GetAncestors failed: {}", e.what());
+ return;
+ }
+
+ bool firstObj = true;
+ for (const auto& [objPath, services] : result)
+ {
+ if (!firstObj)
+ {
+ std::println("");
+ }
+ firstObj = false;
+ std::println("{}", objPath);
+ for (const auto& [service, ifaces] : services)
+ {
+ std::println(" {}", service);
+ for (const auto& iface : ifaces)
+ {
+ std::println(" {}", iface);
+ }
+ }
+ }
+}
+
int main(int argc, char** argv)
{
CLI::App app{"mappertool - OpenBMC mapper inspection utility"};
@@ -429,6 +472,22 @@
getst->callback([&]() { getSubTree(stRoot, stDepth, stIfaces); });
+ // getancestors subcommand
+ auto* getanc = app.add_subcommand(
+ "getancestors",
+ "List ancestor objects of a path with their services and interfaces");
+
+ std::string ancPath;
+ getanc->add_option("path", ancPath, "D-Bus object path to look up")
+ ->required();
+
+ std::vector<std::string> ancIfaces;
+ getanc->add_option(
+ "-i,--interface", ancIfaces,
+ "Restrict to ancestors implementing this interface (repeatable)");
+
+ getanc->callback([&]() { getAncestors(ancPath, ancIfaces); });
+
CLI11_PARSE(app, argc, argv);
return 0;
}