]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson: add pg subcommands support in CLI
authorKautilya Tripathi <knrt@li-4c4c4544-0046-4210-804e-b1c04f423534.ibm.com>
Tue, 20 Jan 2026 13:24:38 +0000 (18:54 +0530)
committerKautilya Tripathi <kautilya.tripathi@ibm.com>
Mon, 27 Apr 2026 04:14:49 +0000 (09:44 +0530)
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 <pgid> <cmd>` JSON form
(e.g. `{"prefix":"pg","pgid":"1.0","cmd":"query",...}`), so `ceph pg <pgid> 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 <kautilya.tripathi@ibm.com>
src/crimson/admin/admin_socket.cc
src/crimson/admin/pg_commands.cc
src/crimson/admin/pg_commands.h
src/crimson/osd/osd.cc

index 5a676d9214c10088364831e8c768d2b780af0fa3..b4c454f08d506b7c9fe575d86142ad30600c4824 100644 (file)
@@ -95,7 +95,18 @@ auto AdminSocket::parse_cmd(const std::vector<std::string>& cmd)
     cmd_getval(cmdmap, "prefix", prefix);
     // tolerate old-style pg <pgid> command <args> 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<std::string>(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);
index ffe34cf31850d47dcec7e5fc844ab2909874bc80..77439a8e74689e851c548d88c6d23b13690db596 100644 (file)
@@ -6,6 +6,7 @@
 #include <memory>
 #include <string>
 #include <string_view>
+#include <utility>
 
 #include <fmt/format.h>
 #include <seastar/core/future.hh>
@@ -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<tell_result_t> 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<AdminSocketHook> make_asok_hook(Args&&... args)
   return std::make_unique<Hook>(std::forward<Args>(args)...);
 }
 
+template std::unique_ptr<AdminSocketHook>
+make_asok_hook<crimson::admin::pg::PGOldFormCommand>(crimson::osd::OSD& osd);
+
 template std::unique_ptr<AdminSocketHook>
 make_asok_hook<crimson::admin::pg::QueryCommand>(crimson::osd::OSD& osd);
 
index 958d411a66bb04ce859d4a12f29c2277f455f558..79989a676f22bdead68d0569d5e40c1409e0b2cd 100644 (file)
@@ -5,6 +5,7 @@
 
 namespace crimson::admin::pg {
 
+class PGOldFormCommand;
 class QueryCommand;
 class MarkUnfoundLostCommand;
 template <bool deep>
index dcef1746f89402f490f8c2ab53749475526d224e..ccd5b535e33e02dcecc2317bbeee222d2b330f3d 100644 (file)
@@ -831,6 +831,7 @@ seastar::future<> OSD::start_asok_admin()
     asok->register_command(make_asok_hook<InjectDataErrorHook>(get_shard_services()));
     asok->register_command(make_asok_hook<InjectMDataErrorHook>(get_shard_services()));
     // PG commands
+    asok->register_command(make_asok_hook<pg::PGOldFormCommand>(*this));
     asok->register_command(make_asok_hook<pg::QueryCommand>(*this));
     asok->register_command(make_asok_hook<pg::MarkUnfoundLostCommand>(*this));
     asok->register_command(make_asok_hook<pg::ScrubCommand<true>>(*this));