]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds/MDBalancer: add an arg to limit depth when dump loads for dirfrags 46685/head
authorhaoyixing <haoyixing@kuaishou.com>
Tue, 14 Jun 2022 08:45:13 +0000 (08:45 +0000)
committerhaoyixing <haoyixing@kuaishou.com>
Mon, 27 Jun 2022 09:27:18 +0000 (09:27 +0000)
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>
qa/tasks/cephfs/test_admin.py
src/mds/MDBalancer.cc
src/mds/MDBalancer.h
src/mds/MDSDaemon.cc
src/mds/MDSRank.cc

index ff6cd761e3ca6cac980f4bb8cb1c5e8004bcae7e..5d69c1fbef5add5a18c49d4718a70ca0c4105b31 100644 (file)
@@ -1097,3 +1097,23 @@ class TestAdminCommandDumpTree(CephFSTestCase):
         self.fs.mds_asok(['dump', 'tree', '/'])
         log.info("  subtree: '~mdsdir'")
         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)
index cb63f60544426e43c351e85beccf11ca832cd603..a7e2cc45c1f680ab4004e8183458e879f88aa9e3 100644 (file)
@@ -1404,11 +1404,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;
   }
@@ -1417,13 +1423,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())
@@ -1431,9 +1442,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 c31c86d37633a935e9bd45c19893eeebc46981d8..91440f11e95803705d0159dec5d551a201ac6553 100644 (file)
@@ -340,7 +340,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 10fd2feeaa8df19c2ce4d12093c257262e9af802..e5238a943d510ab9a34fadcd3edb3c5f9d054ff5 100644 (file)
@@ -2835,7 +2835,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;