The MgrMap stores a list of RADOS clients' addresses registered by the
mgr modules. During failover of ceph-mgr, the list is used to blocklist
clients belonging to the failed ceph-mgr.
Store the names of the mgr modules that registered the RADOS clients
along with the clients' addresses in the MgrMap. During debugging, this
allows easy identification of the mgr module that registered a
particular RADOS client by just dumping the MgrMap (`ceph mgr dump`).
Following is the MgrMap output with a module's client name displayed
along with its client addrvec,
$ ceph mgr dump | jq '.active_clients[0]'
{
"name": "devicehealth",
"addrvec": [
{
"type": "v2",
"addr": "10.0.0.148:0",
"nonce":
612376578
}
]
}
Fixes: https://tracker.ceph.com/issues/58691
Signed-off-by: Ramana Raja <rraja@redhat.com>
* `ceph mgr dump` command now outputs `last_failure_osd_epoch` and
`active_clients` fields at the top level. Previously, these fields were
output under `always_on_modules` field.
+* `ceph mgr dump` command now displays the name of the mgr module that
+ registered a RADOS client in the `name` field added to elements of the
+ `active_clients` array. Previously, only the address of a module's RADOS
+ client was shown in the `active_clients` array.
>=17.2.1
ceph mgr stat
ceph mgr dump
+ ceph mgr dump | jq -e '.active_clients[0].name'
ceph mgr module ls
ceph mgr module enable restful
expect_false ceph mgr module enable foodne
class MMgrBeacon final : public PaxosServiceMessage {
private:
- static constexpr int HEAD_VERSION = 10;
+ static constexpr int HEAD_VERSION = 11;
static constexpr int COMPAT_VERSION = 8;
protected:
std::map<std::string,std::string> metadata; ///< misc metadata about this osd
- std::vector<entity_addrvec_t> clients;
+ std::multimap<std::string, entity_addrvec_t> clients;
uint64_t mgr_features = 0; ///< reporting mgr's features
entity_addrvec_t server_addrs_, bool available_,
std::vector<MgrMap::ModuleInfo>&& modules_,
std::map<std::string,std::string>&& metadata_,
- std::vector<entity_addrvec_t> clients,
+ std::multimap<std::string, entity_addrvec_t>&& clients_,
uint64_t feat)
: PaxosServiceMessage{MSG_MGR_BEACON, 0, HEAD_VERSION, COMPAT_VERSION},
gid(gid_), server_addrs(server_addrs_), available(available_), name(name_),
fsid(fsid_), modules(std::move(modules_)), metadata(std::move(metadata_)),
- clients(std::move(clients)),
+ clients(std::move(clients_)),
mgr_features(feat)
{
}
encode(modules, payload);
encode(mgr_features, payload);
- encode(clients, payload, features);
+
+ std::vector<std::string> clients_names;
+ std::vector<entity_addrvec_t> clients_addrs;
+ for (const auto& i : clients) {
+ clients_names.push_back(i.first);
+ clients_addrs.push_back(i.second);
+ }
+ // The address vector needs to be encoded first to produce a
+ // backwards compatible messsage for older monitors.
+ encode(clients_addrs, payload, features);
+ encode(clients_names, payload, features);
}
void decode_payload() override {
using ceph::decode;
decode(mgr_features, p);
}
if (header.version >= 10) {
- decode(clients, p);
+ std::vector<entity_addrvec_t> clients_addrs;
+ decode(clients_addrs, p);
+ clients.clear();
+ if (header.version >= 11) {
+ std::vector<std::string> clients_names;
+ decode(clients_names, p);
+ if (clients_names.size() != clients_addrs.size()) {
+ throw ceph::buffer::malformed_input(
+ "clients_names.size() != clients_addrs.size()");
+ }
+ auto cn = clients_names.begin();
+ auto ca = clients_addrs.begin();
+ for(; cn != clients_names.end(); ++cn, ++ca) {
+ clients.emplace(*cn, *ca);
+ }
+ } else {
+ for (const auto& i : clients_addrs) {
+ clients.emplace("", i);
+ }
+ }
}
}
private:
auto get_clients() const
{
- std::scoped_lock l(lock);
- std::vector<entity_addrvec_t> v;
- for (const auto& p : clients) {
- v.push_back(p.second);
- }
- return v;
+ return clients;
}
// <<< (end of ActivePyModules cheeky call-throughs)
/// features
uint64_t active_mgr_features = 0;
- std::vector<entity_addrvec_t> clients; // for blocklist
+ std::multimap<std::string, entity_addrvec_t> clients; // for blocklist
std::map<uint64_t, StandbyInfo> standbys;
ENCODE_FINISH(bl);
return;
}
- ENCODE_START(11, 6, bl);
+ ENCODE_START(12, 6, bl);
encode(epoch, bl);
encode(active_addrs, bl, features);
encode(active_gid, bl);
encode(always_on_modules, bl);
encode(active_mgr_features, bl);
encode(last_failure_osd_epoch, bl);
- encode(clients, bl, features);
+ std::vector<std::string> clients_names;
+ std::vector<entity_addrvec_t> clients_addrs;
+ for (const auto& i : clients) {
+ clients_names.push_back(i.first);
+ clients_addrs.push_back(i.second);
+ }
+ // The address vector needs to be encoded first to produce a
+ // backwards compatible messsage for older monitors.
+ encode(clients_addrs, bl, features);
+ encode(clients_names, bl, features);
ENCODE_FINISH(bl);
return;
}
void decode(ceph::buffer::list::const_iterator& p)
{
- DECODE_START(11, p);
+ DECODE_START(12, p);
decode(epoch, p);
decode(active_addrs, p);
decode(active_gid, p);
decode(last_failure_osd_epoch, p);
}
if (struct_v >= 11) {
- decode(clients, p);
+ std::vector<entity_addrvec_t> clients_addrs;
+ decode(clients_addrs, p);
+ clients.clear();
+ if (struct_v >= 12) {
+ std::vector<std::string> clients_names;
+ decode(clients_names, p);
+ if (clients_names.size() != clients_addrs.size()) {
+ throw ceph::buffer::malformed_input(
+ "clients_names.size() != clients_addrs.size()");
+ }
+ auto cn = clients_names.begin();
+ auto ca = clients_addrs.begin();
+ for(; cn != clients_names.end(); ++cn, ++ca) {
+ clients.emplace(*cn, *ca);
+ }
+ } else {
+ for (const auto& i : clients_addrs) {
+ clients.emplace("", i);
+ }
+ }
}
DECODE_FINISH(p);
}
f->close_section(); // always_on_modules
f->dump_int("last_failure_osd_epoch", last_failure_osd_epoch);
f->open_array_section("active_clients");
- for (const auto &c : clients) {
- f->dump_object("client", c);
+ for (const auto& i : clients) {
+ f->open_object_section("client");
+ f->dump_string("name", i.first);
+ i.second.dump(f);
+ f->close_section();
}
f->close_section(); // active_clients
}
/* blocklist RADOS clients in use by the mgr */
for (const auto& a : pending_map.clients) {
- mon.osdmon()->blocklist(a, until);
+ mon.osdmon()->blocklist(a.second, until);
}
request_proposal(mon.osdmon());