From 878463ef3a26f49b9ccad9696ad130fb5aee47e7 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 --- qa/tasks/mgr/dashboard/test_cephfs.py | 14 ++++++++++++++ src/client/Client.cc | 5 +++++ src/pybind/mgr/dashboard/controllers/cephfs.py | 3 ++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/qa/tasks/mgr/dashboard/test_cephfs.py b/qa/tasks/mgr/dashboard/test_cephfs.py index d8e00fe60d9d..7a6b912a3fb8 100644 --- a/qa/tasks/mgr/dashboard/test_cephfs.py +++ b/qa/tasks/mgr/dashboard/test_cephfs.py @@ -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) diff --git a/src/client/Client.cc b/src/client/Client.cc index 8966bf60adb0..6af4d24cae53 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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; diff --git a/src/pybind/mgr/dashboard/controllers/cephfs.py b/src/pybind/mgr/dashboard/controllers/cephfs.py index fca5ddc95ee1..84af1b9e2f2e 100644 --- a/src/pybind/mgr/dashboard/controllers/cephfs.py +++ b/src/pybind/mgr/dashboard/controllers/cephfs.py @@ -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) -- 2.47.3