]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tool/ceph-kvstore-tool: add --pretty-binary-key option 68425/head
authordheart <dheart_joe@163.com>
Thu, 16 Apr 2026 12:34:42 +0000 (20:34 +0800)
committerdheart <dheart_joe@163.com>
Tue, 12 May 2026 15:25:10 +0000 (23:25 +0800)
Signed-off-by: dheart <dheart_joe@163.com>
src/test/cli/ceph-kvstore-tool/help.t
src/tools/ceph_kvstore_tool.cc
src/tools/kvstore_tool.cc
src/tools/kvstore_tool.h

index f8fb009ca5980360a5291e3f9ab4a77de17dd518..67db2e87e116259c5da6f1c71208d1eae906a351 100644 (file)
@@ -1,6 +1,8 @@
   $ ceph-kvstore-tool --help
   Usage: ceph-kvstore-tool <rocksdb|bluestore-kv> <store path> command [args...]
   
+  Options:
+    --pretty-binary-key    Use/dump binary keys in a print pretty format
   Commands:
     list [prefix]
     list-crc [prefix]
index 0029c3804b3006b1bf361b4642b2348eccaf88bb..fa4afc66d7618cac70ec61254304e2c9cfa63c23 100644 (file)
@@ -26,6 +26,7 @@
 #include "global/global_context.h"
 #include "global/global_init.h"
 
+#include "common/pretty_binary.h"
 #include "kvstore_tool.h"
 
 using namespace std;
@@ -34,6 +35,8 @@ void usage(const char *pname)
 {
   std::cout << "Usage: " << pname << " <rocksdb|bluestore-kv> <store path> command [args...]\n"
     << "\n"
+    << "Options:\n"
+    << "  --pretty-binary-key    Use/dump binary keys in a print pretty format\n"
     << "Commands:\n"
     << "  list [prefix]\n"
     << "  list-crc [prefix]\n"
@@ -56,6 +59,33 @@ void usage(const char *pname)
     << std::endl;
 }
 
+std::string format_key(const std::string &key, bool pretty_binary_key = false)
+{
+  if (pretty_binary_key) {
+    return pretty_binary_string(key);
+  }
+  return url_escape(key);
+}
+
+std::string parse_key(const std::string &key, bool pretty_binary_key, std::string &err)
+{
+  err.clear();
+  try {
+    if (pretty_binary_key)
+      return pretty_binary_string_reverse(key);
+    return url_unescape(key);
+  } catch (const std::invalid_argument &e) {
+    std::ostringstream oss;
+    oss << "invalid pretty binary string: " << e.what();
+    err = oss.str();
+  } catch (const std::runtime_error &e)
+  {
+    err = e.what();
+  }
+
+  return "";
+}
+
 int main(int argc, const char *argv[])
 {
   auto args = argv_to_vec(argc, argv);
@@ -63,6 +93,17 @@ int main(int argc, const char *argv[])
     cerr << argv[0] << ": -h or --help for usage" << std::endl;
     exit(1);
   }
+
+  bool pretty_binary_key = [&args] { //pick --pretty-binary-key from args
+    auto arg_it = std::find_if(args.begin(), args.end(),
+        [](const char* val) {return strcmp(val, "--pretty-binary-key") == 0;});
+    if (arg_it != args.end()) {
+      args.erase(arg_it);
+      return true;
+    }
+    return false;
+  }();
+  
   if (ceph_argparse_need_usage(args)) {
     usage(argv[0]);
     exit(0);
@@ -131,13 +172,13 @@ int main(int argc, const char *argv[])
       prefix = url_unescape(argv[4]);
 
     bool do_crc = (cmd == "list-crc");
-    st.list(prefix, do_crc, false);
+    st.list(prefix, do_crc, pretty_binary_key, false);
 
   } else if (cmd == "dump") {
     string prefix;
     if (argc > 4)
       prefix = url_unescape(argv[4]);
-    st.list(prefix, false, true);
+    st.list(prefix, false, pretty_binary_key, true);
 
   } else if (cmd == "exists") {
     string key;
@@ -146,11 +187,17 @@ int main(int argc, const char *argv[])
       return 1;
     }
     string prefix(url_unescape(argv[4]));
-    if (argc > 5)
-      key = url_unescape(argv[5]);
+    if (argc > 5) {
+      std::string err;
+      key = parse_key(argv[5], pretty_binary_key, err);
+      if (!err.empty()) {
+        std::cerr << err << std::endl;
+        return 1;
+      }
+    }
 
     bool ret = st.exists(prefix, key);
-    std::cout << "(" << url_escape(prefix) << ", " << url_escape(key) << ") "
+    std::cout << "(" << url_escape(prefix) << ", " << format_key(key, pretty_binary_key) << ") "
       << (ret ? "exists" : "does not exist")
       << std::endl;
     return (ret ? 0 : 1);
@@ -161,11 +208,16 @@ int main(int argc, const char *argv[])
       return 1;
     }
     string prefix(url_unescape(argv[4]));
-    string key(url_unescape(argv[5]));
+    std::string err;
+    std::string key = parse_key(argv[5], pretty_binary_key, err);
+    if (!err.empty()) {
+      std::cerr << err << std::endl;
+      return 1;
+    }
 
     bool exists = false;
     bufferlist bl = st.get(prefix, key, exists);
-    std::cout << "(" << url_escape(prefix) << ", " << url_escape(key) << ")";
+    std::cout << "(" << url_escape(prefix) << ", " << format_key(key, pretty_binary_key) << ")";
     if (!exists) {
       std::cout << " does not exist" << std::endl;
       return 1;
@@ -208,11 +260,16 @@ int main(int argc, const char *argv[])
       return 1;
     }
     string prefix(url_unescape(argv[4]));
-    string key(url_unescape(argv[5]));
+    std::string err;
+    string key = parse_key(argv[5], pretty_binary_key, err);
+    if (!err.empty()) {
+      std::cerr << err << std::endl;
+      return 1;
+    }
 
     bool exists = false;
     bufferlist bl = st.get(prefix, key, exists);
-    std::cout << "(" << url_escape(prefix) << ", " << url_escape(key) << ") ";
+    std::cout << "(" << url_escape(prefix) << ", " << format_key(key, pretty_binary_key) << ") ";
     if (!exists) {
       std::cout << " does not exist" << std::endl;
       return 1;
@@ -230,16 +287,21 @@ int main(int argc, const char *argv[])
       return 1;
     }
     string prefix(url_unescape(argv[4]));
-    string key(url_unescape(argv[5]));
+    std::string err;
+    string key = parse_key(argv[5], pretty_binary_key, err);
+    if (!err.empty()) {
+      std::cerr << err << std::endl;
+      return 1;
+    }
 
     bool exists = false;
     bufferlist bl = st.get(prefix, key, exists);
     if (!exists) {
-      std::cerr << "(" << url_escape(prefix) << "," << url_escape(key)
+      std::cerr << "(" << url_escape(prefix) << "," << format_key(key, pretty_binary_key)
                 << ") does not exist" << std::endl;
       return 1;
     }
-    std::cout << "(" << url_escape(prefix) << "," << url_escape(key)
+    std::cout << "(" << url_escape(prefix) << "," << format_key(key, pretty_binary_key)
               << ") size " << byte_u_t(bl.length()) << std::endl;
 
   } else if (cmd == "set") {
@@ -248,7 +310,12 @@ int main(int argc, const char *argv[])
       return 1;
     }
     string prefix(url_unescape(argv[4]));
-    string key(url_unescape(argv[5]));
+    std::string err;
+    string key = parse_key(argv[5], pretty_binary_key, err);
+    if (!err.empty()) {
+      std::cerr << err << std::endl;
+      return 1;
+    }
     string subcmd(argv[6]);
 
     bufferlist val;
@@ -275,7 +342,7 @@ int main(int argc, const char *argv[])
     bool ret = st.set(prefix, key, val);
     if (!ret) {
       std::cerr << "error setting ("
-                << url_escape(prefix) << "," << url_escape(key) << ")" << std::endl;
+                << url_escape(prefix) << "," << format_key(key, pretty_binary_key) << ")" << std::endl;
       return 1;
     }
   } else if (cmd == "rm") {
@@ -284,12 +351,17 @@ int main(int argc, const char *argv[])
       return 1;
     }
     string prefix(url_unescape(argv[4]));
-    string key(url_unescape(argv[5]));
+    std::string err;
+    string key = parse_key(argv[5], pretty_binary_key, err);
+    if (!err.empty()) {
+      std::cerr << err << std::endl;
+      return 1;
+    }
 
     bool ret = st.rm(prefix, key);
     if (!ret) {
       std::cerr << "error removing ("
-                << url_escape(prefix) << "," << url_escape(key) << ")"
+                << url_escape(prefix) << "," << format_key(key, pretty_binary_key) << ")"
                << std::endl;
       return 1;
     }
@@ -338,7 +410,7 @@ int main(int argc, const char *argv[])
       return 1;
     }
     std::ofstream fs(argv[4]);
-    uint32_t crc = st.traverse(string(), true, false, &fs);
+    uint32_t crc = st.traverse(string(), true, pretty_binary_key, false, &fs);
     std::cout << "store at '" << argv[4] << "' crc " << crc << std::endl;
 
   } else if (cmd == "compact") {
@@ -356,8 +428,19 @@ int main(int argc, const char *argv[])
       return 1;
     }
     string prefix(url_unescape(argv[4]));
-    string start(url_unescape(argv[5]));
-    string end(url_unescape(argv[6]));
+    std::string err;
+    string start = parse_key(argv[5], pretty_binary_key, err);
+    if (!err.empty()) {
+      std::cerr << err << std::endl;
+      return 1;
+    }
+    string end = parse_key(argv[6], pretty_binary_key, err);
+    if (!err.empty()) {
+      std::cerr << err << std::endl;
+      return 1;
+    }
+    std::cout << "(" << url_escape(prefix) << "," << format_key(start, pretty_binary_key)
+              << " ~ " << format_key(end, pretty_binary_key) << ")" << std::endl;
     st.compact_range(prefix, start, end);
   } else if (cmd == "stats") {
     st.print_stats();
index 7d9a9fb3f8ece52ede36a4a920df5203a84c4a9c..a1970b903b294e50056e11ab33a633f4fa40c92d 100644 (file)
@@ -83,6 +83,7 @@ int StoreTool::load_bluestore(const string& path, bool read_only, bool to_repair
 
 uint32_t StoreTool::traverse(const string& prefix,
                              const bool do_crc,
+                             const bool pretty_binary_key,
                              const bool do_value_dump,
                              ostream *out)
 {
@@ -100,8 +101,13 @@ uint32_t StoreTool::traverse(const string& prefix,
     if (!prefix.empty() && (rk.first != prefix))
       break;
 
-    if (out)
-      *out << url_escape(rk.first) << "\t" << url_escape(rk.second);
+    if (out) {
+      if (pretty_binary_key) {
+        *out << url_escape(rk.first) << "\t" << pretty_binary_string(rk.second);
+      } else {
+        *out << url_escape(rk.first) << "\t" << url_escape(rk.second);
+      }
+    }
     if (do_crc) {
       bufferlist bl;
       bl.append(rk.first);
@@ -130,9 +136,9 @@ uint32_t StoreTool::traverse(const string& prefix,
 }
 
 void StoreTool::list(const string& prefix, const bool do_crc,
-                     const bool do_value_dump)
+                     const bool pretty_binary_key, const bool do_value_dump)
 {
-  traverse(prefix, do_crc, do_value_dump,& std::cout);
+  traverse(prefix, do_crc, pretty_binary_key, do_value_dump,& std::cout);
 }
 
 bool StoreTool::exists(const string& prefix)
index 11ad30b5f1fda98a028f416d29b94781d690a746..ea5e7dc79be9af38e3edc4cb12553e25728f3f60 100644 (file)
@@ -42,10 +42,12 @@ public:
            bool need_stats = false);
   uint32_t traverse(const std::string& prefix,
                     const bool do_crc,
+                    const bool pretty_binary_key,
                     const bool do_value_dump,
                     std::ostream *out);
   void list(const std::string& prefix,
            const bool do_crc,
+           const bool pretty_binary_key,
            const bool do_value_dump);
   bool exists(const std::string& prefix);
   bool exists(const std::string& prefix, const std::string& key);