diff options
author | David Zafman <david.zafman@inktank.com> | 2013-01-14 16:37:09 -0800 |
---|---|---|
committer | David Zafman <david.zafman@inktank.com> | 2013-01-22 15:57:01 -0800 |
commit | db48caf693192b9266abe3c38d8faa7b9272d6e6 (patch) | |
tree | 034579bdf4c9daf1f48614ae4d8f34461cbc8f28 | |
parent | 509a93e89f04d7e9393090563cf7be8e0ea53891 (diff) | |
download | ceph-db48caf693192b9266abe3c38d8faa7b9272d6e6.tar.gz |
osd: debug support for omap deep-scrub
Deep-scrub test support through admin socket
Signed-off-by: David Zafman <david.zafman@inktank.com>
Reviewed-by: Samuel Just <sam.just@inktank.com>
-rw-r--r-- | src/common/ceph_argparse.cc | 11 | ||||
-rw-r--r-- | src/common/ceph_argparse.h | 1 | ||||
-rw-r--r-- | src/osd/OSD.cc | 151 | ||||
-rw-r--r-- | src/osd/OSD.h | 4 | ||||
-rw-r--r-- | src/osd/OSDMap.h | 4 |
5 files changed, 171 insertions, 0 deletions
diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc index 646931acdc9..f26fe93b656 100644 --- a/src/common/ceph_argparse.cc +++ b/src/common/ceph_argparse.cc @@ -45,6 +45,17 @@ #undef generic_dout #undef dendl +void string_to_vec(std::vector<std::string>& args, std::string argstr) +{ + istringstream iss(argstr); + while(iss) { + string sub; + iss >> sub; + if (sub == "") break; + args.push_back(sub); + } +} + void env_to_vec(std::vector<const char*>& args, const char *name) { if (!name) diff --git a/src/common/ceph_argparse.h b/src/common/ceph_argparse.h index fd9439c5627..3ef0251abeb 100644 --- a/src/common/ceph_argparse.h +++ b/src/common/ceph_argparse.h @@ -43,6 +43,7 @@ public: }; /////////////////////// Functions /////////////////////// +extern void string_to_vec(std::vector<std::string>& args, std::string argstr); extern void env_to_vec(std::vector<const char*>& args, const char *name=NULL); extern void argv_to_vec(int argc, const char **argv, std::vector<const char*>& args); diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 0d289f6c875..34ec3678f08 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -17,6 +17,7 @@ #include <errno.h> #include <sys/stat.h> #include <signal.h> +#include <ctype.h> #include <boost/scoped_ptr.hpp> #if defined(DARWIN) || defined(__FreeBSD__) @@ -869,6 +870,22 @@ public: } }; +class TestOpsSocketHook : public AdminSocketHook { + OSDService *service; + ObjectStore *store; +public: + TestOpsSocketHook(OSDService *s, ObjectStore *st) : service(s), store(st) {} + bool call(std::string command, std::string args, bufferlist& out) { + stringstream ss; + test_ops(service, store, command, args, ss); + out.append(ss); + return true; + } + void test_ops(OSDService *service, ObjectStore *store, std::string command, + std::string args, ostream &ss); + +}; + int OSD::init() { Mutex::Locker lock(osd_lock); @@ -966,10 +983,24 @@ int OSD::init() AdminSocket *admin_socket = cct->get_admin_socket(); r = admin_socket->register_command("dump_ops_in_flight", admin_ops_hook, "show the ops currently in flight"); + assert(r == 0); historic_ops_hook = new HistoricOpsSocketHook(this); r = admin_socket->register_command("dump_historic_ops", historic_ops_hook, "show slowest recent ops"); assert(r == 0); + test_ops_hook = new TestOpsSocketHook(&(this->service), this->store); + r = admin_socket->register_command("setomapval", test_ops_hook, + "setomap <pool-id> <obj-name> <key> <val>"); + assert(r == 0); + r = admin_socket->register_command("rmomapkey", test_ops_hook, + "rmomapkey <pool-id> <obj-name> <key>"); + assert(r == 0); + r = admin_socket->register_command("setomapheader", test_ops_hook, + "setomapheader <pool-id> <obj-name> <header>"); + assert(r == 0); + r = admin_socket->register_command("getomap", test_ops_hook, + "getomap <pool-id> <obj-name>"); + assert(r == 0); service.init(); service.publish_map(osdmap); @@ -1125,6 +1156,12 @@ int OSD::shutdown() delete historic_ops_hook; admin_ops_hook = NULL; historic_ops_hook = NULL; + cct->get_admin_socket()->unregister_command("setomapval"); + cct->get_admin_socket()->unregister_command("rmomapkey"); + cct->get_admin_socket()->unregister_command("setomapheader"); + cct->get_admin_socket()->unregister_command("getomap"); + delete test_ops_hook; + test_ops_hook = NULL; recovery_tp.stop(); dout(10) << "recovery tp stopped" << dendl; @@ -2292,6 +2329,120 @@ void OSD::dump_ops_in_flight(ostream& ss) op_tracker.dump_ops_in_flight(ss); } +// Usage: +// setomapval <pool-id> <obj-name> <key> <val> +// rmomapkey <pool-id> <obj-name> <key> +// setomapheader <pool-id> <obj-name> <header> +void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store, + std::string command, std::string args, ostream &ss) +{ + //Test support + //Support changing the omap on a single osd by using the Admin Socket to + //directly request the osd make a change. + if (command == "setomapval" || command == "rmomapkey" || + command == "setomapheader" || command == "getomap") { + std::vector<std::string> argv; + pg_t rawpg, pgid; + int64_t pool; + OSDMapRef curmap = service->get_osdmap(); + int r; + + argv.push_back(command); + string_to_vec(argv, args); + int argc = argv.size(); + + if (argc < 3) { + ss << "Illegal request"; + return; + } + + pool = curmap->const_lookup_pg_pool_name(argv[1].c_str()); + //If we can't find it my name then maybe id specified + if (pool < 0 && isdigit(argv[1].c_str()[0])) + pool = atoll(argv[1].c_str()); + r = -1; + if (pool >= 0) + r = curmap->object_locator_to_pg(object_t(argv[2]), + object_locator_t(pool), rawpg); + if (r < 0) { + ss << "Invalid pool " << argv[1]; + return; + } + pgid = curmap->raw_pg_to_pg(rawpg); + + hobject_t obj(object_t(argv[2]), string(""), CEPH_NOSNAP, rawpg.ps(), pool); + ObjectStore::Transaction t; + + if (command == "setomapval") { + if (argc != 5) { + ss << "usage: setomapval <pool> <obj-name> <key> <val>"; + return; + } + map<string, bufferlist> newattrs; + bufferlist val; + string key(argv[3]); + + val.append(argv[4]); + newattrs[key] = val; + t.omap_setkeys(coll_t(pgid), obj, newattrs); + r = store->apply_transaction(t); + if (r < 0) + ss << "error=" << r; + else + ss << "ok"; + } else if (command == "rmomapkey") { + if (argc != 4) { + ss << "usage: rmomapkey <pool> <obj-name> <key>"; + return; + } + set<string> keys; + + keys.insert(string(argv[3])); + t.omap_rmkeys(coll_t(pgid), obj, keys); + r = store->apply_transaction(t); + if (r < 0) + ss << "error=" << r; + else + ss << "ok"; + } else if (command == "setomapheader") { + if (argc != 4) { + ss << "usage: setomapheader <pool> <obj-name> <header>"; + return; + } + bufferlist newheader; + + newheader.append(argv[3]); + t.omap_setheader(coll_t(pgid), obj, newheader); + r = store->apply_transaction(t); + if (r < 0) + ss << "error=" << r; + else + ss << "ok"; + } else if (command == "getomap") { + if (argc != 3) { + ss << "usage: getomap <pool> <obj-name>"; + return; + } + //Debug: Output entire omap + bufferlist hdrbl; + map<string, bufferlist> keyvals; + r = store->omap_get(coll_t(pgid), obj, &hdrbl, &keyvals); + if (r >= 0) { + ss << "header=" << string(hdrbl.c_str(), hdrbl.length()); + for (map<string, bufferlist>::iterator it = keyvals.begin(); + it != keyvals.end(); it++) + ss << " key=" << (*it).first << " val=" + << string((*it).second.c_str(), (*it).second.length()); + } else { + ss << "error=" << r; + } + } + return; + } + ss << "Internal error - command=" << command; + return; +} + // ========================================= void OSD::RemoveWQ::_process(boost::tuple<coll_t, SequencerRef, DeletingStateRef> *item) { diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 83308486f0f..be4ed11791e 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -133,6 +133,7 @@ class AuthAuthorizeHandlerRegistry; class OpsFlightSocketHook; class HistoricOpsSocketHook; +class TestOpsSocketHook; struct C_CompleteSplits; extern const coll_t meta_coll; @@ -617,11 +618,14 @@ private: void dump_historic_ops(ostream& ss) { return op_tracker.dump_historic_ops(ss); } + void test_ops(std::string command, std::string args, ostream& ss); friend class OpsFlightSocketHook; friend class HistoricOpsSocketHook; + friend class TestOpsSocketHook; friend class C_CompleteSplits; OpsFlightSocketHook *admin_ops_hook; HistoricOpsSocketHook *historic_ops_hook; + TestOpsSocketHook *test_ops_hook; // -- op queue -- diff --git a/src/osd/OSDMap.h b/src/osd/OSDMap.h index 4d4bbd0b031..5105fc7ab0e 100644 --- a/src/osd/OSDMap.h +++ b/src/osd/OSDMap.h @@ -450,6 +450,10 @@ public: return -ENOENT; } + int64_t const_lookup_pg_pool_name(const char *name) const { + return const_cast<OSDMap *>(this)->lookup_pg_pool_name(name); + } + int64_t get_pool_max() const { return pool_max; } |