From: Joao Eduardo Luis Date: Sun, 13 Oct 2013 12:40:57 +0000 (+0100) Subject: tools: move 'test_store_tool' to 'tools/ceph-kvstore-tool' X-Git-Tag: v0.71~3^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=da69fa09c8274585225471c68c1acc788a3881f4;p=ceph.git tools: move 'test_store_tool' to 'tools/ceph-kvstore-tool' ceph-kvstore-tool allows for lower-level access to leveldb stores. Signed-off-by: Joao Eduardo Luis --- diff --git a/src/test/Makefile.am b/src/test/Makefile.am index 59b4d89e930..84a228f1d4b 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -856,11 +856,6 @@ ceph_test_keyvaluedb_iterators_LDADD = $(LIBOS) $(UNITTEST_LDADD) $(CEPH_GLOBAL) ceph_test_keyvaluedb_iterators_CXXFLAGS = $(UNITTEST_CXXFLAGS) bin_DEBUGPROGRAMS += ceph_test_keyvaluedb_iterators -ceph_test_store_tool_SOURCES = test/ObjectMap/test_store_tool/test_store_tool.cc -ceph_test_store_tool_LDADD = $(LIBOS) $(CEPH_GLOBAL) -ceph_test_store_tool_CXXFLAGS = $(UNITTEST_CXXFLAGS) -bin_DEBUGPROGRAMS += ceph_test_store_tool - ceph_test_cfuse_cache_invalidate_SOURCES = test/test_cfuse_cache_invalidate.cc bin_DEBUGPROGRAMS += ceph_test_cfuse_cache_invalidate diff --git a/src/test/ObjectMap/test_store_tool/test_store_tool.cc b/src/test/ObjectMap/test_store_tool/test_store_tool.cc deleted file mode 100644 index 8fcf3f30e82..00000000000 --- a/src/test/ObjectMap/test_store_tool/test_store_tool.cc +++ /dev/null @@ -1,270 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* -* Ceph - scalable distributed file system -* -* Copyright (C) 2012 Inktank, Inc. -* -* This is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License version 2.1, as published by the Free Software -* Foundation. See file COPYING. -*/ -#include -#include -#include -#include -#include -#include - -#include "os/LevelDBStore.h" - -#include "common/ceph_argparse.h" -#include "global/global_init.h" -#include "common/errno.h" -#include "common/safe_io.h" -#include "common/config.h" -#include "common/strtol.h" - -using namespace std; - -class StoreTool -{ - boost::scoped_ptr db; - - public: - StoreTool(const string &path) { - LevelDBStore *db_ptr = new LevelDBStore(g_ceph_context, path); - assert(!db_ptr->open(std::cerr)); - db.reset(db_ptr); - } - - void list(const string &prefix, const bool do_crc) { - KeyValueDB::WholeSpaceIterator iter = db->get_iterator(); - - if (prefix.empty()) - iter->seek_to_first(); - else - iter->seek_to_first(prefix); - - while (iter->valid()) { - pair rk = iter->raw_key(); - if (!prefix.empty() && (rk.first != prefix)) - break; - - std::cout << rk.first << ":" << rk.second; - if (do_crc) { - std::cout << " (" << iter->value().crc32c(0) << ")"; - } - std::cout << std::endl; - iter->next(); - } - } - - bool exists(const string &prefix) { - assert(!prefix.empty()); - KeyValueDB::WholeSpaceIterator iter = db->get_iterator(); - iter->seek_to_first(prefix); - return (iter->valid() && (iter->raw_key().first == prefix)); - } - - bool exists(const string &prefix, const string &key) { - assert(!prefix.empty()); - - if (key.empty()) { - return exists(prefix); - } - - bool exists = false; - get(prefix, key, exists); - return exists; - } - - bufferlist get(const string &prefix, const string &key, bool &exists) { - assert(!prefix.empty() && !key.empty()); - - map result; - std::set keys; - keys.insert(key); - db->get(prefix, keys, &result); - - if (result.count(key) > 0) { - exists = true; - return result[key]; - } - exists = false; - return bufferlist(); - } - - uint64_t get_size() { - map extras; - uint64_t s = db->get_estimated_size(extras); - for (map::iterator p = extras.begin(); - p != extras.end(); ++p) { - std::cout << p->first << " - " << p->second << std::endl; - } - std::cout << "total: " << s << std::endl; - return s; - } - - bool set(const string &prefix, const string &key, bufferlist &val) { - assert(!prefix.empty()); - assert(!key.empty()); - assert(val.length() > 0); - - KeyValueDB::Transaction tx = db->get_transaction(); - tx->set(prefix, key, val); - int ret = db->submit_transaction_sync(tx); - - return (ret == 0); - } -}; - -void usage(const char *pname) -{ - std::cerr << "Usage: " << pname << " command [args...]\n" - << "\n" - << "Commands:\n" - << " list [prefix]\n" - << " list-crc [prefix]\n" - << " exists [key]\n" - << " get \n" - << " crc \n" - << " get-size\n" - << " set [ver |in ]\n" - << std::endl; -} - -int main(int argc, const char *argv[]) -{ - vector args; - argv_to_vec(argc, argv, args); - env_to_vec(args); - - global_init( - NULL, args, - CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0); - common_init_finish(g_ceph_context); - - - if (args.size() < 2) { - usage(argv[0]); - return 1; - } - - string path(args[0]); - string cmd(args[1]); - - std::cout << "path: " << path << " cmd " << cmd << std::endl; - - StoreTool st(path); - - if (cmd == "list" || cmd == "list-crc") { - string prefix; - if (argc > 3) - prefix = argv[3]; - - bool do_crc = (cmd == "list-crc"); - - st.list(prefix, do_crc); - - } else if (cmd == "exists") { - string key; - if (argc < 4) { - usage(argv[0]); - return 1; - } - string prefix(argv[3]); - if (argc > 4) - key = argv[4]; - - bool ret = st.exists(prefix, key); - std::cout << "(" << prefix << ", " << key << ") " - << (ret ? "exists" : "does not exist") - << std::endl; - return (ret ? 0 : 1); - - } else if (cmd == "get") { - if (argc < 5) { - usage(argv[0]); - return 1; - } - string prefix(argv[3]); - string key(argv[4]); - - bool exists = false; - bufferlist bl = st.get(prefix, key, exists); - std::cout << "(" << prefix << ", " << key << ")"; - if (!exists) { - std::cout << " does not exist" << std::endl; - return 1; - } - std::cout << std::endl; - ostringstream os; - bl.hexdump(os); - std::cout << os.str() << std::endl; - - } else if (cmd == "crc") { - if (argc < 5) { - usage(argv[0]); - return 1; - } - string prefix(argv[3]); - string key(argv[4]); - - bool exists = false; - bufferlist bl = st.get(prefix, key, exists); - std::cout << "(" << prefix << ", " << key << ") "; - if (!exists) { - std::cout << " does not exist" << std::endl; - return 1; - } - std::cout << " crc " << bl.crc32c(0) << std::endl; - - } else if (cmd == "get-size") { - std::cout << "estimated store size: " << st.get_size() << std::endl; - - } else if (cmd == "set") { - if (argc < 7) { - usage(argv[0]); - return 1; - } - string prefix(argv[3]); - string key(argv[4]); - string subcmd(argv[5]); - - bufferlist val; - string errstr; - if (subcmd == "ver") { - version_t v = (version_t) strict_strtoll(argv[6], 10, &errstr); - if (!errstr.empty()) { - std::cerr << "error reading version: " << errstr << std::endl; - return 1; - } - ::encode(v, val); - } else if (subcmd == "in") { - int ret = val.read_file(argv[6], &errstr); - if (ret < 0 || !errstr.empty()) { - std::cerr << "error reading file: " << errstr << std::endl; - return 1; - } - } else { - std::cerr << "unrecognized subcommand '" << subcmd << "'" << std::endl; - usage(argv[0]); - return 1; - } - - bool ret = st.set(prefix, key, val); - if (!ret) { - std::cerr << "error setting (" - << prefix << "," << key << ")" << std::endl; - return 1; - } - - } else { - std::cerr << "Unrecognized command: " << cmd << std::endl; - return 1; - } - - return 0; -} diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 4b8da77951a..89417014dd4 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -6,6 +6,12 @@ ceph_monstore_tool_SOURCES = tools/ceph-monstore-tool.cc ceph_monstore_tool_LDADD = $(LIBOS) $(CEPH_GLOBAL) -lboost_program_options bin_DEBUGPROGRAMS += ceph-monstore-tool +ceph_kvstore_tool_SOURCES = tools/ceph-kvstore-tool.cc +ceph_kvstore_tool_LDADD = $(LIBOS) $(CEPH_GLOBAL) +ceph_kvstore_tool_CXXFLAGS = $(UNITTEST_CXXFLAGS) +bin_DEBUGPROGRAMS += ceph-kvstore-tool + + ceph_filestore_dump_SOURCES = tools/ceph-filestore-dump.cc ceph_filestore_dump_LDADD = $(LIBOSD) $(LIBOS) $(CEPH_GLOBAL) -lboost_program_options if LINUX diff --git a/src/tools/ceph-kvstore-tool.cc b/src/tools/ceph-kvstore-tool.cc new file mode 100644 index 00000000000..8fcf3f30e82 --- /dev/null +++ b/src/tools/ceph-kvstore-tool.cc @@ -0,0 +1,270 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* +* Ceph - scalable distributed file system +* +* Copyright (C) 2012 Inktank, Inc. +* +* This is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +*/ +#include +#include +#include +#include +#include +#include + +#include "os/LevelDBStore.h" + +#include "common/ceph_argparse.h" +#include "global/global_init.h" +#include "common/errno.h" +#include "common/safe_io.h" +#include "common/config.h" +#include "common/strtol.h" + +using namespace std; + +class StoreTool +{ + boost::scoped_ptr db; + + public: + StoreTool(const string &path) { + LevelDBStore *db_ptr = new LevelDBStore(g_ceph_context, path); + assert(!db_ptr->open(std::cerr)); + db.reset(db_ptr); + } + + void list(const string &prefix, const bool do_crc) { + KeyValueDB::WholeSpaceIterator iter = db->get_iterator(); + + if (prefix.empty()) + iter->seek_to_first(); + else + iter->seek_to_first(prefix); + + while (iter->valid()) { + pair rk = iter->raw_key(); + if (!prefix.empty() && (rk.first != prefix)) + break; + + std::cout << rk.first << ":" << rk.second; + if (do_crc) { + std::cout << " (" << iter->value().crc32c(0) << ")"; + } + std::cout << std::endl; + iter->next(); + } + } + + bool exists(const string &prefix) { + assert(!prefix.empty()); + KeyValueDB::WholeSpaceIterator iter = db->get_iterator(); + iter->seek_to_first(prefix); + return (iter->valid() && (iter->raw_key().first == prefix)); + } + + bool exists(const string &prefix, const string &key) { + assert(!prefix.empty()); + + if (key.empty()) { + return exists(prefix); + } + + bool exists = false; + get(prefix, key, exists); + return exists; + } + + bufferlist get(const string &prefix, const string &key, bool &exists) { + assert(!prefix.empty() && !key.empty()); + + map result; + std::set keys; + keys.insert(key); + db->get(prefix, keys, &result); + + if (result.count(key) > 0) { + exists = true; + return result[key]; + } + exists = false; + return bufferlist(); + } + + uint64_t get_size() { + map extras; + uint64_t s = db->get_estimated_size(extras); + for (map::iterator p = extras.begin(); + p != extras.end(); ++p) { + std::cout << p->first << " - " << p->second << std::endl; + } + std::cout << "total: " << s << std::endl; + return s; + } + + bool set(const string &prefix, const string &key, bufferlist &val) { + assert(!prefix.empty()); + assert(!key.empty()); + assert(val.length() > 0); + + KeyValueDB::Transaction tx = db->get_transaction(); + tx->set(prefix, key, val); + int ret = db->submit_transaction_sync(tx); + + return (ret == 0); + } +}; + +void usage(const char *pname) +{ + std::cerr << "Usage: " << pname << " command [args...]\n" + << "\n" + << "Commands:\n" + << " list [prefix]\n" + << " list-crc [prefix]\n" + << " exists [key]\n" + << " get \n" + << " crc \n" + << " get-size\n" + << " set [ver |in ]\n" + << std::endl; +} + +int main(int argc, const char *argv[]) +{ + vector args; + argv_to_vec(argc, argv, args); + env_to_vec(args); + + global_init( + NULL, args, + CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0); + common_init_finish(g_ceph_context); + + + if (args.size() < 2) { + usage(argv[0]); + return 1; + } + + string path(args[0]); + string cmd(args[1]); + + std::cout << "path: " << path << " cmd " << cmd << std::endl; + + StoreTool st(path); + + if (cmd == "list" || cmd == "list-crc") { + string prefix; + if (argc > 3) + prefix = argv[3]; + + bool do_crc = (cmd == "list-crc"); + + st.list(prefix, do_crc); + + } else if (cmd == "exists") { + string key; + if (argc < 4) { + usage(argv[0]); + return 1; + } + string prefix(argv[3]); + if (argc > 4) + key = argv[4]; + + bool ret = st.exists(prefix, key); + std::cout << "(" << prefix << ", " << key << ") " + << (ret ? "exists" : "does not exist") + << std::endl; + return (ret ? 0 : 1); + + } else if (cmd == "get") { + if (argc < 5) { + usage(argv[0]); + return 1; + } + string prefix(argv[3]); + string key(argv[4]); + + bool exists = false; + bufferlist bl = st.get(prefix, key, exists); + std::cout << "(" << prefix << ", " << key << ")"; + if (!exists) { + std::cout << " does not exist" << std::endl; + return 1; + } + std::cout << std::endl; + ostringstream os; + bl.hexdump(os); + std::cout << os.str() << std::endl; + + } else if (cmd == "crc") { + if (argc < 5) { + usage(argv[0]); + return 1; + } + string prefix(argv[3]); + string key(argv[4]); + + bool exists = false; + bufferlist bl = st.get(prefix, key, exists); + std::cout << "(" << prefix << ", " << key << ") "; + if (!exists) { + std::cout << " does not exist" << std::endl; + return 1; + } + std::cout << " crc " << bl.crc32c(0) << std::endl; + + } else if (cmd == "get-size") { + std::cout << "estimated store size: " << st.get_size() << std::endl; + + } else if (cmd == "set") { + if (argc < 7) { + usage(argv[0]); + return 1; + } + string prefix(argv[3]); + string key(argv[4]); + string subcmd(argv[5]); + + bufferlist val; + string errstr; + if (subcmd == "ver") { + version_t v = (version_t) strict_strtoll(argv[6], 10, &errstr); + if (!errstr.empty()) { + std::cerr << "error reading version: " << errstr << std::endl; + return 1; + } + ::encode(v, val); + } else if (subcmd == "in") { + int ret = val.read_file(argv[6], &errstr); + if (ret < 0 || !errstr.empty()) { + std::cerr << "error reading file: " << errstr << std::endl; + return 1; + } + } else { + std::cerr << "unrecognized subcommand '" << subcmd << "'" << std::endl; + usage(argv[0]); + return 1; + } + + bool ret = st.set(prefix, key, val); + if (!ret) { + std::cerr << "error setting (" + << prefix << "," << key << ")" << std::endl; + return 1; + } + + } else { + std::cerr << "Unrecognized command: " << cmd << std::endl; + return 1; + } + + return 0; +}