]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds/MDBalancer: add an arg to limit depth when dump loads for dirfrags 54188/head
authorhaoyixing <haoyixing@kuaishou.com>
Tue, 14 Jun 2022 08:45:13 +0000 (08:45 +0000)
committerRishabh Dave <ridave@redhat.com>
Fri, 12 Apr 2024 14:22:27 +0000 (19:52 +0530)
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 <haoyixing@kuaishou.com>
(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.

qa/tasks/cephfs/test_admin.py
src/mds/MDBalancer.cc
src/mds/MDBalancer.h
src/mds/MDSDaemon.cc
src/mds/MDSRank.cc

index 340dde80e343062d1a108ae38d482a5784af3bc0..9a98a3fcedf4ae252b799b8a05925a43ac0b929c 100644 (file)
@@ -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'
index 389d216e28734682b155d040d22f30dcb7494012..61854b2e83f677d6acb8f2bc4d11ddb84fd50d1e 100644 (file)
@@ -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<CDir*> dfs;
+  std::deque<pair<CDir*, int>> dfs;
+  std::deque<CDir*> 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));
       }
     }
   }
index e3ee3deabcff8ec78b6e7456fe5844baf72e1168..b1a4b1ec66a4c3cccd876ae4b31e944286dc1416 100644 (file)
@@ -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 {
index 126a9a668e1682b64b97bbb7e789ce9a621559d3..2a1f932a69d856dcc64af4a143f070b705d70962 100644 (file)
@@ -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);
index a3adb19936335f12580b8d75f1b250efbe394259..3baf24f17c6be8b4e616f835283bf2d8a37d3bc4 100644 (file)
@@ -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;