From d3c591ac5b77f24c7e5f85df3f69fe42c3eb324c Mon Sep 17 00:00:00 2001 From: Douglas Fuller Date: Fri, 17 Jun 2016 13:13:14 -0700 Subject: [PATCH] mds: Add path filtering for dump cache Add a new admin socket command, dump below, to filter cache dumps by path. An optional integer depth parameter limits the depth below the specified path. Fixes: http://tracker.ceph.com/issues/11171 Signed-off-by: Douglas Fuller --- src/mds/MDCache.cc | 29 ++++++++++++++++++++++++++--- src/mds/MDCache.h | 5 ++++- src/mds/MDSDaemon.cc | 8 ++++++++ src/mds/MDSRank.cc | 10 ++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 28691e016d7..4aabbdf2cbc 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -11601,11 +11601,17 @@ void MDCache::dump_cache(Formatter *f) dump_cache(NULL, f); } +void MDCache::dump_cache(const string& dump_root, int depth, Formatter *f) +{ + dump_cache(NULL, f, dump_root, depth); +} + /** * Dump the metadata cache, either to a Formatter, if * provided, else to a plain text file. */ -void MDCache::dump_cache(const char *fn, Formatter *f) +void MDCache::dump_cache(const char *fn, Formatter *f, + const string& dump_root, int depth) { int r = 0; int fd = -1; @@ -11627,11 +11633,28 @@ void MDCache::dump_cache(const char *fn, Formatter *f) return; } } - + for (ceph::unordered_map::iterator it = inode_map.begin(); it != inode_map.end(); ++it) { CInode *in = it->second; + + if (!dump_root.empty()) { + string ipath; + if (in->is_root()) + ipath = "/"; + else + in->make_path_string(ipath); + + if (dump_root.length() > ipath.length() || + !equal(dump_root.begin(), dump_root.end(), ipath.begin())) + continue; + + if (depth >= 0 && + count(ipath.begin() + dump_root.length(), ipath.end(), '/') > depth) + continue; + } + if (f) { f->open_object_section("inode"); in->dump(f); @@ -11641,7 +11664,7 @@ void MDCache::dump_cache(const char *fn, Formatter *f) std::string s = ss.str(); r = safe_write(fd, s.c_str(), s.length()); if (r < 0) { - goto out; + goto out; } } diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index ff3115e6227..582f495d553 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -1111,11 +1111,14 @@ public: void notify_osdmap_changed(); protected: - void dump_cache(const char *fn, Formatter *f); + void dump_cache(const char *fn, Formatter *f, + const std::string& dump_root = "", + int depth = -1); public: void dump_cache() {dump_cache(NULL, NULL);} void dump_cache(const std::string &filename); void dump_cache(Formatter *f); + void dump_cache(const std::string& dump_root, int depth, Formatter *f); void dump_resolve_status(Formatter *f) const; void dump_rejoin_status(Formatter *f) const; diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index ef9ade80fc8..13500210d82 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -273,6 +273,13 @@ void MDSDaemon::set_up_admin_socket() asok_hook, "dump metadata cache (optionally to a file)"); assert(r == 0); + r = admin_socket->register_command("dump tree", + "dump tree " + "name=root,type=CephString,req=true " + "name=depth,type=CephInt,req=false ", + asok_hook, + "dump metadata cache for subtree"); + assert(r == 0); r = admin_socket->register_command("session evict", "session evict name=client_id,type=CephString", asok_hook, @@ -339,6 +346,7 @@ void MDSDaemon::clean_up_admin_socket() admin_socket->unregister_command("flush_path"); admin_socket->unregister_command("export dir"); admin_socket->unregister_command("dump cache"); + admin_socket->unregister_command("dump tree"); admin_socket->unregister_command("session evict"); admin_socket->unregister_command("osdmap barrier"); admin_socket->unregister_command("session ls"); diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 16a93485b2b..8dd1c4f3978 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -1758,6 +1758,16 @@ bool MDSRankDispatcher::handle_asok_command( } else { mdcache->dump_cache(path); } + } else if (command == "dump tree") { + string root; + int64_t depth; + cmd_getval(g_ceph_context, cmdmap, "root", root); + if (!cmd_getval(g_ceph_context, cmdmap, "depth", depth)) + depth = -1; + { + Mutex::Locker l(mds_lock); + mdcache->dump_cache(root, depth, f); + } } else if (command == "force_readonly") { mds_lock.Lock(); mdcache->force_readonly(); -- 2.39.5