From e4f6e6a7e0eeedd60a02e80ab97f7d0524c79e90 Mon Sep 17 00:00:00 2001 From: Vallari Agrawal Date: Thu, 25 Sep 2025 10:21:03 +0530 Subject: [PATCH] mon: Add command "nvme-gw listeners" This command will help to list all existing listeners, even when they are not in OMAP (eg, auto-listeners). Fixes: https://tracker.ceph.com/issues/73782 Signed-off-by: Vallari Agrawal (cherry picked from commit 7e106fd9612b032058167f20fb8723ffc3bf5a46) --- src/mon/MonCommands.h | 6 ++++ src/mon/NVMeofGwMon.cc | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 62a709c5f1f..b2ee4836794 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -1451,6 +1451,12 @@ COMMAND("nvme-gw show" " show nvmeof gateways within (pool, group)", "mon", "r") +COMMAND("nvme-gw listeners" + " name=pool,type=CephString" + " name=group,type=CephString", + " show all nvmeof gateways listeners within (pool, group)", + "mon", "r") + // these are tell commands that were implemented as CLI commands in // the broken pre-octopus way that we want to allow to work when a // monitor has upgraded to octopus+ but the monmap min_mon_release is diff --git a/src/mon/NVMeofGwMon.cc b/src/mon/NVMeofGwMon.cc index 84becd7d1da..bd7b1bdfb9b 100644 --- a/src/mon/NVMeofGwMon.cc +++ b/src/mon/NVMeofGwMon.cc @@ -537,10 +537,73 @@ bool NVMeofGwMon::preprocess_command(MonOpRequestRef op) getline(sstrm, rs); mon.reply_command(op, err, rs, rdata, get_last_committed()); return true; + } else if (prefix == "nvme-gw listeners") { + std::string pool, group; + if (!f) { + f.reset(Formatter::create(format, "json-pretty", "json-pretty")); + } + cmd_getval(cmdmap, "pool", pool); + cmd_getval(cmdmap, "group", group); + auto group_key = std::make_pair(pool, group); + dout(10) << "nvme-gw listeners pool " << pool << " group " << group << dendl; + + f->open_object_section("common"); + f->dump_unsigned("epoch", map.epoch); + f->dump_string("pool", pool); + f->dump_string("group", group); + + f->dump_unsigned("num gws", map.created_gws[group_key].size()); + if (map.gw_epoch.find(group_key) != map.gw_epoch.end()) + f->dump_unsigned("GW-epoch", map.gw_epoch[group_key]); + if (map.created_gws[group_key].size() == 0) { + f->close_section(); + f->flush(rdata); + sstrm.str(""); + } else { + get_gw_listeners(f.get(), group_key); + f->close_section(); + f->flush(rdata); + sstrm.str(""); + } + getline(sstrm, rs); + mon.reply_command(op, err, rs, rdata, get_last_committed()); + return true; } return false; } +void NVMeofGwMon::get_gw_listeners(Formatter *f, std::pair& group_key){ + std::map>> subsystem_listeners; + for (auto& gw_created_pair: map.created_gws[group_key]) { + auto& gw_id = gw_created_pair.first; + auto& state = gw_created_pair.second; + if (state.availability == gw_availability_t::GW_AVAILABLE) { + for (auto &subs: state.subsystems) { + auto& lst = subsystem_listeners[subs.nqn]; + for (auto& listener : subs.listeners) { + lst.push_back({listener, gw_id}); + } + } + } + } + f->open_object_section("Created listeners"); + for (auto& listener_pair: subsystem_listeners) { + auto& subsystem_nqn = listener_pair.first; + auto& listeners = listener_pair.second; + f->open_array_section(subsystem_nqn); + for (auto& [listener, gw_id] : listeners) { + f->open_object_section("stat"); + f->dump_string("address_family", listener.address_family); + f->dump_string("address", listener.address); + f->dump_string("svcid", listener.svcid); + f->dump_string("gw_id", gw_id); + f->close_section(); + } + f->close_section(); + } + f->close_section(); +} + bool NVMeofGwMon::prepare_command(MonOpRequestRef op) { dout(10) << dendl; -- 2.47.3