]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools/ceph_monstore_tool: add get-key command
authorMatan Breizman <mbreizma@redhat.com>
Sun, 6 Aug 2023 13:04:11 +0000 (13:04 +0000)
committerMatan Breizman <mbreizma@redhat.com>
Mon, 9 Oct 2023 13:46:59 +0000 (13:46 +0000)
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
src/tools/ceph_monstore_tool.cc

index 437b45cd67600933c6fbe23e667ef40eccf7ccd0..f6b0dc62ae550fcb910cf0bc0dcea34eef7640a0 100644 (file)
@@ -210,6 +210,7 @@ void usage(const char *n, po::options_description &d)
   << "                                  (default: last committed)\n"
   << "  get crushmap [-- options]       get crushmap (version VER if specified)\n"
   << "                                  (default: last committed)\n"
+  << "  get-key PREFIX KEY [-- options] get key\n"
   << "  show-versions [-- options]      show the first&last committed version of map\n"
   << "                                  (show-versions -- --help for more info)\n"
   << "  dump-keys                       dumps store keys to FILE\n"
@@ -999,6 +1000,103 @@ int main(int argc, char **argv) {
                 << " version " << v << " to " << outpath
                 << std::endl;
     }
+} else if (cmd == "get-key") {
+    string outpath;
+    string prefix;
+    string key;
+
+    // visible options for this command
+    po::options_description op_desc("Allowed 'get-key' options");
+    op_desc.add_options()
+      ("help,h", "produce this help message")
+      ("out,o", po::value<string>(&outpath),
+       "output file (default: stdout)")
+      ("readable,r", "print the map information in human readable format")
+      ;
+    // this is going to be a positional argument; we don't want to show
+    // it as an option during --help, but we do want to have it captured
+    // when parsing.
+    po::options_description hidden_op_desc("Hidden 'get-key' options");
+    hidden_op_desc.add_options()
+      ("prefix", po::value<string>(&prefix),"prefix")
+      ("key", po::value<string>(&key),"key")
+      ;
+    po::positional_options_description op_positional;
+    op_positional.add("prefix", 1);
+    op_positional.add("key", 1);
+
+
+    po::variables_map op_vm;
+    int r = parse_cmd_args(&op_desc, &hidden_op_desc, &op_positional,
+                           subcmds, &op_vm);
+    if (r < 0) {
+      return -r;
+    }
+
+    if (op_vm.count("help") || prefix.empty()) {
+      usage(argv[0], op_desc);
+      return 0;
+    }
+
+    int fd = STDOUT_FILENO;
+    if (!outpath.empty()){
+      fd = ::open(outpath.c_str(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
+      if (fd < 0) {
+        std::cerr << "error opening output file: "
+          << cpp_strerror(errno) << std::endl;
+        return EINVAL;
+      }
+    }
+
+    auto close_fd = make_scope_guard([&] {
+      ::close(fd);
+      if (r < 0 && fd != STDOUT_FILENO) {
+        ::remove(outpath.c_str());
+      }
+    });
+    bufferlist bl;
+    r = 0;
+    std::cout << prefix << " " << key << std::endl;
+    r = st.get(prefix, key, bl);
+    if (r < 0) {
+      std::cerr << "Error getting key: " << cpp_strerror(r) << std::endl;
+      return EINVAL;
+    }
+
+    if (op_vm.count("readable")) {
+      try {
+        if (prefix == "osd_snap") {
+          auto p = bl.cbegin();
+          if (key.starts_with("purged_epoch_")) {
+            map<int64_t,snap_interval_set_t> val;
+            ceph::decode(val, p);
+            std::cout << val << std::endl;
+          } else if (key.starts_with("purged_snap_")) {
+            snapid_t first_snap, end_snap;
+            epoch_t epoch;
+            ceph::decode(first_snap, p);
+            ceph::decode(end_snap, p);
+            ceph::decode(epoch, p);
+            std::cout << "first_snap:" << first_snap
+                      << " end_snap: " << end_snap
+                      << " epoch: " << epoch
+                      << std::endl;
+          }
+        } else {
+          std::cerr << "This type of readable key does not exist: " << prefix
+                    << std::endl << "You can only specify[osd_snap]" << std::endl;
+        }
+      } catch (const buffer::error &err) {
+        std::cerr << "Could not decode for human readable output (you may still"
+         " use non-readable mode).  Detail: " << err.what() << std::endl;
+      }
+    }
+
+    bl.write_fd(fd);
+
+    if (!outpath.empty()) {
+      std::cout << "wrote " << prefix << " " <<  key <<  " to " << outpath << std::endl;
+    }
   } else if (cmd == "show-versions") {
     string map_type; //map type:osdmap,monmap...
     // visible options for this command