From: Zhansong Gao Date: Mon, 16 Jan 2023 09:50:29 +0000 (+0800) Subject: mds: add a command to dump directory information X-Git-Tag: v17.2.8~438^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3ca4185dfd18309ef5106df7e0012b51e8460f56;p=ceph.git mds: add a command to dump directory information Signed-off-by: Zhansong Gao (cherry picked from commit 42492d5058f6b61be0bbc355d9205db836c45af1) --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 2a1277d9e0ec..e6b92c509f82 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -13324,6 +13324,12 @@ bool MDCache::dump_inode(Formatter *f, uint64_t number) { return true; } +void MDCache::dump_dir(Formatter *f, CDir *dir, bool dentry_dump) { + f->open_object_section("dir"); + dir->dump(f, dentry_dump ? CDir::DUMP_ALL : CDir::DUMP_DEFAULT); + f->close_section(); +} + void MDCache::handle_mdsmap(const MDSMap &mdsmap, const MDSMap &oldmap) { const mds_rank_t max_mds = mdsmap.get_max_mds(); diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index f1a6d37b1ba0..758dac6eb82e 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -520,6 +520,7 @@ class MDCache { void clean_open_file_lists(); void dump_openfiles(Formatter *f); bool dump_inode(Formatter *f, uint64_t number); + void dump_dir(Formatter *f, CDir *dir, bool dentry_dump=false); void rejoin_start(MDSContext *rejoin_done_); void rejoin_gather_finish(); diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index cd7b2e35fc22..126a9a668e16 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -440,6 +440,12 @@ void MDSDaemon::set_up_admin_socket() asok_hook, "dump inode by inode number"); ceph_assert(r == 0); + r = admin_socket->register_command("dump dir " + "name=path,type=CephString,req=true " + "name=dentry_dump,type=CephBool,req=false", + asok_hook, + "dump directory by path"); + ceph_assert(r == 0); r = admin_socket->register_command("exit", asok_hook, "Terminate this MDS"); diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 890b1013892e..f28b1ff4b3ec 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -2905,6 +2905,8 @@ void MDSRankDispatcher::handle_asok_command( command_openfiles_ls(f); } else if (command == "dump inode") { command_dump_inode(f, cmdmap, *css); + } else if (command == "dump dir") { + command_dump_dir(f, cmdmap, *css); } else if (command == "damage ls") { std::lock_guard l(mds_lock); damage_table.dump(f); @@ -3345,6 +3347,36 @@ void MDSRank::command_dump_inode(Formatter *f, const cmdmap_t &cmdmap, std::ostr } } +void MDSRank::command_dump_dir(Formatter *f, const cmdmap_t &cmdmap, std::ostream &ss) +{ + std::lock_guard l(mds_lock); + std::string path; + bool got = cmd_getval(cmdmap, "path", path); + if (!got) { + ss << "missing path argument"; + return; + } + + bool dentry_dump = false; + cmd_getval(cmdmap, "dentry_dump", dentry_dump); + + CInode *in = mdcache->cache_traverse(filepath(path.c_str())); + if (!in) { + ss << "directory inode not in cache"; + return; + } + + f->open_array_section("dirs"); + frag_vec_t leaves; + in->dirfragtree.get_leaves_under(frag_t(), leaves); + for (const auto& leaf : leaves) { + CDir *dir = in->get_dirfrag(leaf); + if (dir) + mdcache->dump_dir(f, dir, dentry_dump); + } + f->close_section(); +} + void MDSRank::dump_status(Formatter *f) const { f->dump_string("fs_name", std::string(mdsmap->get_fs_name())); diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index e3f7c785199c..8b294902cc41 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -542,6 +542,7 @@ class MDSRank { void command_openfiles_ls(Formatter *f); void command_dump_tree(const cmdmap_t &cmdmap, std::ostream &ss, Formatter *f); void command_dump_inode(Formatter *f, const cmdmap_t &cmdmap, std::ostream &ss); + void command_dump_dir(Formatter *f, const cmdmap_t &cmdmap, std::ostream &ss); void command_cache_drop(uint64_t timeout, Formatter *f, Context *on_finish); // FIXME the state machine logic should be separable from the dispatch