From 946e1803453a08db7f78962a8bf8c40fac5a0dcc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 5 Jun 2018 08:47:45 -0500 Subject: [PATCH] mgr: implement 'device {ls,ls-by-daemon,ls-by-host,info}' commands Signed-off-by: Sage Weil --- src/mgr/DaemonServer.cc | 115 ++++++++++++++++++++++++++++++++++++++++ src/mgr/DaemonState.h | 30 +++++++++++ src/mgr/MgrCommands.h | 13 +++++ 3 files changed, 158 insertions(+) diff --git a/src/mgr/DaemonServer.cc b/src/mgr/DaemonServer.cc index 06c55a78722..111c7883d10 100644 --- a/src/mgr/DaemonServer.cc +++ b/src/mgr/DaemonServer.cc @@ -351,6 +351,19 @@ static DaemonKey key_from_service( } } +static bool key_from_string( + const std::string& name, + DaemonKey *out) +{ + auto p = name.find('.'); + if (p == std::string::npos) { + return false; + } + out->first = name.substr(0, p); + out->second = name.substr(p + 1); + return true; +} + bool DaemonServer::handle_open(MMgrOpen *m) { Mutex::Locker l(lock); @@ -1643,6 +1656,108 @@ bool DaemonServer::handle_command(MCommand *m) } cmdctx->reply(r, ss); return true; + } else if (prefix == "device ls") { + set devids; + if (f) { + f->open_array_section("devices"); + daemon_state.with_devices([&f](const DeviceState& dev) { + f->dump_string("device", dev.devid); + }); + f->close_section(); + f->flush(cmdctx->odata); + } else { + ostringstream rs; + daemon_state.with_devices([&rs](const DeviceState& dev) { + rs << dev.devid << "\n"; + }); + cmdctx->odata.append(rs.str()); + } + cmdctx->reply(0, ss); + return true; + } else if (prefix == "device ls-by-daemon") { + string who; + cmd_getval(g_ceph_context, cmdctx->cmdmap, "who", who); + DaemonKey k; + if (!key_from_string(who, &k)) { + ss << who << " is not a valid daemon name"; + r = -EINVAL; + } else { + auto dm = daemon_state.get(k); + if (dm) { + if (f) { + f->open_array_section("devices"); + for (auto& i : dm->devids) { + f->dump_string("device", i); + } + f->close_section(); + f->flush(cmdctx->odata); + } else { + ostringstream rs; + for (auto& i : dm->devids) { + rs << i << "\n"; + } + cmdctx->odata.append(rs.str()); + } + } else { + r = -ENOENT; + ss << "daemon " << who << " not found"; + } + cmdctx->reply(r, ss); + } + } else if (prefix == "device ls-by-host") { + string host; + cmd_getval(g_ceph_context, cmdctx->cmdmap, "host", host); + set devids; + daemon_state.list_devids_by_server(host, &devids); + if (f) { + f->open_array_section("devices"); + for (auto& i : devids) { + f->dump_string("device", i); + } + f->close_section(); + f->flush(cmdctx->odata); + } else { + ostringstream rs; + for (auto& i : devids) { + rs << i << "\n"; + } + cmdctx->odata.append(rs.str()); + } + cmdctx->reply(0, ss); + return true; + } else if (prefix == "device info") { + string devid; + cmd_getval(g_ceph_context, cmdctx->cmdmap, "devid", devid); + int r = 0; + ostringstream rs; + if (!daemon_state.with_device(devid, [&f, &rs] (const DeviceState& dev) { + if (f) { + f->open_object_section("device"); + f->dump_string("devid", dev.devid); + f->dump_string("host", dev.server); + f->open_array_section("daemons"); + for (auto& i : dev.daemons) { + f->dump_string("daemon", to_string(i)); + } + f->close_section(); + f->close_section(); + } else { + rs << "device " << dev.devid << "\n"; + rs << "host " << dev.server << "\n"; + rs << "daemons " << dev.daemons << "\n"; + } + })) { + ss << "device " << devid << " not found"; + r = -ENOENT; + } else { + if (f) { + f->flush(cmdctx->odata); + } else { + cmdctx->odata.append(rs.str()); + } + } + cmdctx->reply(r, ss); + return true; } else { // fall back to feeding command to PGMap r = cluster_state.with_pgmap([&](const PGMap& pg_map) { diff --git a/src/mgr/DaemonState.h b/src/mgr/DaemonState.h index 8eda23ec94e..8dc1cf922c2 100644 --- a/src/mgr/DaemonState.h +++ b/src/mgr/DaemonState.h @@ -253,6 +253,36 @@ public: return std::forward(cb)(by_server, std::forward(args)...); } + template + auto with_device(const std::string& dev, + Callback&& cb, Args&&... args) const { + RWLock::RLocker l(lock); + auto p = devices.find(dev); + if (p == devices.end()) { + return false; + } + std::forward(cb)(*p->second, std::forward(args)...); + return true; + } + + template + void with_devices(Callback&& cb, Args&&... args) const { + RWLock::RLocker l(lock); + for (auto& i : devices) { + std::forward(cb)(*i.second, std::forward(args)...); + } + } + + void list_devids_by_server(const std::string& server, + std::set *ls) { + auto m = get_by_server(server); + for (auto& i : m) { + Mutex::Locker l(i.second->lock); + ls->insert(i.second->devids.begin(), + i.second->devids.end()); + } + } + void notify_updating(const DaemonKey &k) { RWLock::WLocker l(lock); updating.insert(k); diff --git a/src/mgr/MgrCommands.h b/src/mgr/MgrCommands.h index 3aeef49bfea..4415aff00d2 100644 --- a/src/mgr/MgrCommands.h +++ b/src/mgr/MgrCommands.h @@ -140,3 +140,16 @@ COMMAND("config show-with-defaults " \ "name=who,type=CephString", "Show running configuration (including compiled-in defaults)", "mgr", "r", "cli,rest") + +COMMAND("device ls", + "Show devices", + "mgr", "r", "cli,rest") +COMMAND("device info name=devid,type=CephString", + "Show information about a device", + "mgr", "r", "cli,rest") +COMMAND("device ls-by-daemon name=who,type=CephString", + "Show devices associated with a daemon", + "mgr", "r", "cli,rest") +COMMAND("device ls-by-host name=host,type=CephString", + "Show devices on a host", + "mgr", "r", "cli,rest") -- 2.39.5