]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: check mds down status bofore getting mds_gid_t from mdsmap 52258/head
authoryite.gu <yitegu0@gmail.com>
Mon, 29 Jan 2024 10:26:20 +0000 (18:26 +0800)
committeryite.gu <yitegu0@gmail.com>
Mon, 26 Feb 2024 11:54:10 +0000 (19:54 +0800)
Get mds_gid_t from up of MDSMap, will cause to core dump if target
mds_rank_t does not exist up map:

from: src/mds/MDSMap.h
  const auto& get_info(mds_rank_t m) const {
    return mds_info.at(up.at(m));
  }

reproduct:
1. ceph fs fail <fs_name>
2. curl -X GET "example.com:8080/api/cephfs/1/clients" ...
up.at(m) will cause to core dump.

Fixes: https://tracker.ceph.com/issues/61844
Signed-off-by: Yite Gu <yitegu0@gmail.com>
qa/tasks/mgr/dashboard/test_cephfs.py
src/client/Client.cc
src/pybind/mgr/dashboard/controllers/cephfs.py

index d8e00fe60d9d92916f3ff904be7d8e4fe5592a09..7a6b912a3fb8c12d7d148fa56ff7e2099e68d6aa 100644 (file)
@@ -347,3 +347,17 @@ class CephfsTest(DashboardTestCase):
         self.assertEqual(stats['subdirs'], 1)
 
         self.rm_dir('/animal')
+
+    def test_cephfs_clients_get_after_mds_down(self):
+        fs_id = self.get_fs_id()
+        self._get(f"/api/cephfs/{fs_id}/clients")
+        self.assertStatus(200)
+
+        self.fs.fail()
+        params = {'suppress_client_ls_errors': 'False'}
+        self._get(f"/api/cephfs/{fs_id}/clients", params=params)
+        self.assertStatus(500)
+
+        self.fs.set_joinable()
+        self._get(f"/api/cephfs/{fs_id}/clients")
+        self.assertStatus(200)
index 8966bf60adb02df48c08a0df9f254c0165a1aa37..6af4d24cae53f5f99b29a39473b615bde0fc639a 100644 (file)
@@ -6273,6 +6273,11 @@ int Client::resolve_mds(
   if (role_r == 0) {
     // We got a role, resolve it to a GID
     const auto& mdsmap = fsmap->get_filesystem(role.fscid).get_mds_map();
+    if (mdsmap.is_down(role.rank)) {
+      lderr(cct) << __func__ << ": targets rank: " << role.rank
+                 << " is down" << dendl;
+      return -CEPHFS_EAGAIN;
+    }
     auto& info = mdsmap.get_info(role.rank);
     ldout(cct, 10) << __func__ << ": resolved " << mds_spec << " to role '"
       << role << "' aka " << info.human_name() << dendl;
index fca5ddc95ee1d1e75135a9ddc666f59e48e36956..84af1b9e2f2ea96f94b7ba9455910f66f17f62f7 100644 (file)
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+# pylint: disable=too-many-lines
 import errno
 import json
 import logging
@@ -110,7 +111,7 @@ class CephFS(RESTController):
         if flag not in ('True', 'False'):
             raise DashboardException(msg='suppress_client_ls_errors value '
                                          'needs to be either True or False '
-                                         f'but provided {flag}',
+                                         f'but provided "{flag}"',
                                      component='cephfs')
 
         fs_id = self.fs_id_to_int(fs_id)