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: v19.0.0~1647^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=42492d5058f6b61be0bbc355d9205db836c45af1;p=ceph.git mds: add a command to dump directory information Signed-off-by: Zhansong Gao --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 101b0b55b37a..38ca143bbe3c 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -13488,6 +13488,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 7b544998b3c1..4c2e85e23386 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -514,6 +514,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 ca8c3b656785..80caf1499e85 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -446,6 +446,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 d1294c8ce971..888a0062e204 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -2875,6 +2875,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); @@ -3311,6 +3313,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 fb2061eb548a..d28933c6aaf1 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -508,6 +508,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