From 87263832d89b49f1665a21f7ae770a1de3a7066c Mon Sep 17 00:00:00 2001 From: "yite.gu" Date: Mon, 29 Jan 2024 18:26:20 +0800 Subject: [PATCH] client: check mds down status bofore getting mds_gid_t from mdsmap 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 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 (cherry picked from commit 878463ef3a26f49b9ccad9696ad130fb5aee47e7) --- qa/tasks/mgr/dashboard/test_cephfs.py | 14 ++++++++++++++ src/client/Client.cc | 8 +++++++- src/pybind/mgr/dashboard/controllers/cephfs.py | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/qa/tasks/mgr/dashboard/test_cephfs.py b/qa/tasks/mgr/dashboard/test_cephfs.py index 4295b580f74b..413ae6e4af91 100644 --- a/qa/tasks/mgr/dashboard/test_cephfs.py +++ b/qa/tasks/mgr/dashboard/test_cephfs.py @@ -290,3 +290,17 @@ class CephfsTest(DashboardTestCase): ui_api_ls = self.ui_ls_dir('/pictures', 0) self.assertEqual(api_ls, ui_api_ls) self.rm_dir('/pictures') + + 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) diff --git a/src/client/Client.cc b/src/client/Client.cc index a84e69f38f2f..214aaa513cb1 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -6247,7 +6247,13 @@ int Client::resolve_mds( int role_r = fsmap->parse_role(mds_spec, &role, *css); if (role_r == 0) { // We got a role, resolve it to a GID - auto& info = fsmap->get_filesystem(role.fscid)->mds_map.get_info(role.rank); + 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; targets->push_back(info.global_id); diff --git a/src/pybind/mgr/dashboard/controllers/cephfs.py b/src/pybind/mgr/dashboard/controllers/cephfs.py index f753f9caec4d..4210746fbd1f 100644 --- a/src/pybind/mgr/dashboard/controllers/cephfs.py +++ b/src/pybind/mgr/dashboard/controllers/cephfs.py @@ -134,7 +134,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) -- 2.47.3