From: Matan Breizman Date: Sun, 6 Aug 2023 13:04:11 +0000 (+0000) Subject: tools/ceph_monstore_tool: add get-key command X-Git-Tag: v19.0.0~102^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=23c7d1e749022f7a15c92296f5367bc651cecc5d;p=ceph.git tools/ceph_monstore_tool: add get-key command Signed-off-by: Matan Breizman --- diff --git a/src/tools/ceph_monstore_tool.cc b/src/tools/ceph_monstore_tool.cc index 437b45cd676..f6b0dc62ae5 100644 --- a/src/tools/ceph_monstore_tool.cc +++ b/src/tools/ceph_monstore_tool.cc @@ -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(&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(&prefix),"prefix") + ("key", po::value(&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 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