Merge PR #52258 into main

* refs/pull/52258/head:
	client: check mds down status bofore getting mds_gid_t from mdsmap
	mgr/dashboard: allow sending back error status code fetching clients fails

Reviewed-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Venky Shankar <vshankar@redhat.com>
Reviewed-by: Rishabh Dave <ridave@redhat.com>
Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
Reviewed-by: Nizamudeen A <nia@redhat.com>
Reviewed-by: Dhairya Parmar <dparmar@redhat.com>
This commit is contained in:
Venky Shankar 2024-02-28 09:32:42 +05:30
commit 5dbd3bfdea
3 changed files with 41 additions and 6 deletions

View 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)

View 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;

View File

@ -106,10 +106,17 @@ class CephFS(RESTController):
return self.fs_status(fs_id)
@RESTController.Resource('GET')
def clients(self, fs_id):
def clients(self, fs_id, **kwargs):
flag = kwargs.pop('suppress_client_ls_errors', 'True')
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}"',
component='cephfs')
fs_id = self.fs_id_to_int(fs_id)
return self._clients(fs_id)
return self._clients(fs_id, suppress_client_ls_errors=flag)
@RESTController.Resource('DELETE', path='/client/{client_id}')
def evict(self, fs_id, client_id):
@ -352,17 +359,23 @@ class CephFS(RESTController):
"versions": mds_versions
}
def _clients(self, fs_id):
def _clients(self, fs_id, **kwargs):
suppress_get_errors = kwargs.pop('suppress_client_ls_errors', 'True')
cephfs_clients = self.cephfs_clients.get(fs_id, None)
if cephfs_clients is None:
cephfs_clients = CephFSClients(mgr, fs_id)
self.cephfs_clients[fs_id] = cephfs_clients
try:
status, clients = cephfs_clients.get()
status, clients = cephfs_clients.get(suppress_get_errors)
except AttributeError:
raise cherrypy.HTTPError(404,
"No cephfs with id {0}".format(fs_id))
except RuntimeError:
raise cherrypy.HTTPError(500,
f"Could not fetch client(s), maybe there "
f"is no active MDS on CephFS {fs_id} or "
"the FS is in failed state.")
if clients is None:
raise cherrypy.HTTPError(404,
@ -610,11 +623,14 @@ class CephFSClients(object):
self.fscid = fscid
@ViewCache()
def get(self):
def get(self, suppress_errors='True'):
try:
ret = CephService.send_command('mds', 'session ls', srv_spec='{0}:0'.format(self.fscid))
except RuntimeError:
ret = []
if suppress_errors == 'True':
ret = []
else:
raise
return ret