From: haoyixing Date: Tue, 14 Jun 2022 08:45:13 +0000 (+0000) Subject: mds/MDBalancer: add an arg to limit depth when dump loads for dirfrags X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=643a1166d877e6ff0db18a7a95db6c03bde5a202;p=ceph.git mds/MDBalancer: add an arg to limit depth when dump loads for dirfrags Directory hierarchy may be deep for a large filesystem, dump loads would output a lot and take a long time. So add an arg to limit depth when dump loads of dirfrags. Fixes: https://tracker.ceph.com/issues/56058 Signed-off-by: haoyixing (cherry picked from commit a8f138cd3623e42c4f74a18d54ec7dfcc1e89e58) Conflicts: * qa/tasks/cephfs/test_admin.py Conflict occurred because test_admin.py on Quincy branch was updated by PR #54946. --- diff --git a/qa/tasks/cephfs/test_admin.py b/qa/tasks/cephfs/test_admin.py index 340dde80e3430..9a98a3fcedf4a 100644 --- a/qa/tasks/cephfs/test_admin.py +++ b/qa/tasks/cephfs/test_admin.py @@ -1124,6 +1124,27 @@ class TestAdminCommandDumpTree(CephFSTestCase): self.fs.mds_asok(['dump', 'tree', '~mdsdir']) +class TestAdminCommandDumpLoads(CephFSTestCase): + """ + Tests for administration command dump loads. + """ + + CLIENTS_REQUIRED = 0 + MDSS_REQUIRED = 1 + + def test_dump_loads(self): + """ + make sure depth limit param is considered when dump loads for a MDS daemon. + """ + + log.info("dumping loads") + loads = self.fs.mds_asok(['dump', 'loads', '1']) + self.assertIsNotNone(loads) + self.assertIn("dirfrags", loads) + for d in loads["dirfrags"]: + self.assertLessEqual(d["path"].count("/"), 1) + + class TestPermErrMsg(CephFSTestCase): CLIENT_NAME = 'client.testuser' diff --git a/src/mds/MDBalancer.cc b/src/mds/MDBalancer.cc index 389d216e28734..61854b2e83f67 100644 --- a/src/mds/MDBalancer.cc +++ b/src/mds/MDBalancer.cc @@ -1431,11 +1431,17 @@ void MDBalancer::handle_mds_failure(mds_rank_t who) } } -int MDBalancer::dump_loads(Formatter *f) const +int MDBalancer::dump_loads(Formatter *f, int64_t depth) const { - std::deque dfs; + std::deque> dfs; + std::deque dfs_root; if (mds->mdcache->get_root()) { - mds->mdcache->get_root()->get_dirfrags(dfs); + mds->mdcache->get_root()->get_dirfrags(dfs_root); + while (!dfs_root.empty()) { + CDir *dir = dfs_root.front(); + dfs_root.pop_front(); + dfs.push_back(make_pair(dir, 0)); + } } else { dout(10) << "no root" << dendl; } @@ -1444,13 +1450,18 @@ int MDBalancer::dump_loads(Formatter *f) const f->open_array_section("dirfrags"); while (!dfs.empty()) { - CDir *dir = dfs.front(); + auto [dir, cur_depth] = dfs.front(); dfs.pop_front(); f->open_object_section("dir"); dir->dump_load(f); f->close_section(); + //limit output dirfrags depth + if (depth >= 0 && (cur_depth + 1) > depth) { + continue; + } + for (auto it = dir->begin(); it != dir->end(); ++it) { CInode *in = it->second->get_linkage()->get_inode(); if (!in || !in->is_dir()) @@ -1458,9 +1469,10 @@ int MDBalancer::dump_loads(Formatter *f) const auto&& ls = in->get_dirfrags(); for (const auto& subdir : ls) { + if (subdir->pop_nested.meta_load() < .001) continue; - dfs.push_back(subdir); + dfs.push_back(make_pair(subdir, cur_depth+1)); } } } diff --git a/src/mds/MDBalancer.h b/src/mds/MDBalancer.h index e3ee3deabcff8..b1a4b1ec66a4c 100644 --- a/src/mds/MDBalancer.h +++ b/src/mds/MDBalancer.h @@ -74,7 +74,7 @@ public: void handle_mds_failure(mds_rank_t who); - int dump_loads(Formatter *f) const; + int dump_loads(Formatter *f, int64_t depth = -1) const; private: typedef struct { diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index 126a9a668e168..2a1f932a69d85 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -342,7 +342,8 @@ void MDSDaemon::set_up_admin_socket() asok_hook, "dump metadata cache for subtree"); ceph_assert(r == 0); - r = admin_socket->register_command("dump loads", + r = admin_socket->register_command("dump loads " + "name=depth,type=CephInt,range=0,req=false", asok_hook, "dump metadata loads"); ceph_assert(r == 0); diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index a3adb19936335..3baf24f17c6be 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -2879,7 +2879,12 @@ void MDSRankDispatcher::handle_asok_command( command_dump_tree(cmdmap, *css, f); } else if (command == "dump loads") { std::lock_guard l(mds_lock); - r = balancer->dump_loads(f); + int64_t depth = -1; + bool got = cmd_getval(cmdmap, "depth", depth); + if (!got || depth < 0) { + dout(10) << "no depth limit when dirfrags dump_load" << dendl; + } + r = balancer->dump_loads(f, depth); } else if (command == "dump snaps") { std::lock_guard l(mds_lock); string server;