From: Kautilya Tripathi Date: Tue, 20 Jan 2026 13:24:38 +0000 (+0530) Subject: crimson: add pg subcommands support in CLI X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a95886b8bb37f4983afd23bce78e4397ebf24ffc;p=ceph.git crimson: add pg subcommands support in CLI Crimson OSD was missing the PG admin/tell hooks that classic OSD exposes, and it did not accept the legacy `rados_pg_command()` / `ceph pg ` JSON form (e.g. `{"prefix":"pg","pgid":"1.0","cmd":"query",...}`), so `ceph pg query` failed. Adds a `pg` old-form wrapper hook that exists to advertise that exists to advertise the classic `pgid` + `cmd` + optional `arg` signature. The runtime dispatch rewrites this to the real subcommand. This updates parse_cmd to rewrite `prefix=pg` requests to the requested subcommand and remap the generic `arg` field to the concrete parameter names (`offset` for `list_unfound`, `mulcmd` for `mark_unfound_lost`) so validation/parsing is unambiguous. Fixes: https://tracker.ceph.com/issues/73266 Signed-off-by: Kautilya Tripathi --- diff --git a/src/crimson/admin/admin_socket.cc b/src/crimson/admin/admin_socket.cc index 5a676d9214c1..b4c454f08d50 100644 --- a/src/crimson/admin/admin_socket.cc +++ b/src/crimson/admin/admin_socket.cc @@ -95,7 +95,18 @@ auto AdminSocket::parse_cmd(const std::vector& cmd) cmd_getval(cmdmap, "prefix", prefix); // tolerate old-style pg command style formatting if (prefix == "pg") { - cmd_getval(cmdmap, "cmd", prefix); + std::string pg_subcmd; + cmd_getval(cmdmap, "cmd", pg_subcmd); + prefix = pg_subcmd; + + if (auto arg = cmd_getval(cmdmap, "arg"); arg) { + if (pg_subcmd == "list_unfound") { + cmdmap["offset"] = std::move(*arg); + } else if (pg_subcmd == "mark_unfound_lost") { + cmdmap["mulcmd"] = std::move(*arg); + } + cmdmap.erase("arg"); + } } } catch (const bad_cmd_get& e) { ERROR("invalid syntax: {}", cmd); diff --git a/src/crimson/admin/pg_commands.cc b/src/crimson/admin/pg_commands.cc index ffe34cf31850..77439a8e7468 100644 --- a/src/crimson/admin/pg_commands.cc +++ b/src/crimson/admin/pg_commands.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,6 @@ using crimson::osd::PG; using namespace crimson::common; using ceph::common::cmd_getval; - namespace crimson::admin::pg { class PGCommand : public AdminSocketHook { @@ -88,13 +88,33 @@ private: OSD& osd; }; +class PGOldFormCommand final : public AdminSocketHook { +public: + explicit PGOldFormCommand(crimson::osd::OSD&) : + AdminSocketHook{"pg", + "name=pgid,type=CephPgid " + "name=cmd,type=CephChoices,strings=query|log|scrub|deep-scrub|list_unfound|mark_unfound_lost " + "name=arg,type=CephString,req=false", + "old-form wrapper for pg subcommands (query, log, scrub, deep-scrub, list_unfound, mark_unfound_lost)"} + {} + + seastar::future call(const cmdmap_t&, + std::string_view, + ceph::bufferlist&&) const final + { + // This hook exists only for schema advertisement via get_command_descriptions. + // parse_cmd() always rewrites prefix away from "pg" before dispatch. + std::unreachable(); + } +}; + class QueryCommand final : public PGCommand { public: // TODO: const correctness of osd explicit QueryCommand(crimson::osd::OSD& osd) : PGCommand{osd, "query", - "", + "name=pgid,type=CephPgid", "show details of a specific pg"} {} private: @@ -197,6 +217,9 @@ std::unique_ptr make_asok_hook(Args&&... args) return std::make_unique(std::forward(args)...); } +template std::unique_ptr +make_asok_hook(crimson::osd::OSD& osd); + template std::unique_ptr make_asok_hook(crimson::osd::OSD& osd); diff --git a/src/crimson/admin/pg_commands.h b/src/crimson/admin/pg_commands.h index 958d411a66bb..79989a676f22 100644 --- a/src/crimson/admin/pg_commands.h +++ b/src/crimson/admin/pg_commands.h @@ -5,6 +5,7 @@ namespace crimson::admin::pg { +class PGOldFormCommand; class QueryCommand; class MarkUnfoundLostCommand; template diff --git a/src/crimson/osd/osd.cc b/src/crimson/osd/osd.cc index dcef1746f894..ccd5b535e33e 100644 --- a/src/crimson/osd/osd.cc +++ b/src/crimson/osd/osd.cc @@ -831,6 +831,7 @@ seastar::future<> OSD::start_asok_admin() asok->register_command(make_asok_hook(get_shard_services())); asok->register_command(make_asok_hook(get_shard_services())); // PG commands + asok->register_command(make_asok_hook(*this)); asok->register_command(make_asok_hook(*this)); asok->register_command(make_asok_hook(*this)); asok->register_command(make_asok_hook>(*this));