Skip to content

Commit 2ab1415

Browse files
authored
Merge pull request ceph#49974 from neesingh-rh/wip-58619
mds: fix session/client evict command. Reviewed-by: Patrick Donnelly <[email protected]> Reviewed-by: Venky Shankar <[email protected]>
2 parents 62eb727 + f3e674d commit 2ab1415

File tree

5 files changed

+89
-5
lines changed

5 files changed

+89
-5
lines changed

qa/suites/fs/multiclient/clusters/1-mds-2-client.yaml

Lines changed: 0 additions & 1 deletion
This file was deleted.

qa/tasks/cephfs/test_misc.py

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from io import StringIO
22

33
from tasks.cephfs.fuse_mount import FuseMount
4-
from tasks.cephfs.cephfs_test_case import CephFSTestCase
4+
from tasks.cephfs.cephfs_test_case import CephFSTestCase, classhook
55
from teuthology.exceptions import CommandFailedError
66
from textwrap import dedent
77
from threading import Thread
@@ -521,6 +521,84 @@ def test_session_ls(self):
521521

522522
def test_client_ls(self):
523523
self._session_client_ls(['client', 'ls'])
524+
525+
526+
@classhook('_add_session_client_evictions')
527+
class TestSessionClientEvict(CephFSTestCase):
528+
CLIENTS_REQUIRED = 3
529+
530+
def _evict_without_filter(self, cmd):
531+
info_initial = self.fs.rank_asok(cmd + ['ls'])
532+
# without any filter or flags
533+
with self.assertRaises(CommandFailedError) as ce:
534+
self.fs.rank_asok(cmd + ['evict'])
535+
self.assertEqual(ce.exception.exitstatus, errno.EINVAL)
536+
# without any filter but with existing flag
537+
with self.assertRaises(CommandFailedError) as ce:
538+
self.fs.rank_asok(cmd + ['evict', '--help'])
539+
self.assertEqual(ce.exception.exitstatus, errno.EINVAL)
540+
info = self.fs.rank_asok(cmd + ['ls'])
541+
self.assertEqual(len(info), len(info_initial))
542+
# without any filter but with non-existing flag
543+
with self.assertRaises(CommandFailedError) as ce:
544+
self.fs.rank_asok(cmd + ['evict', '--foo'])
545+
self.assertEqual(ce.exception.exitstatus, errno.EINVAL)
546+
info = self.fs.rank_asok(cmd + ['ls'])
547+
self.assertEqual(len(info), len(info_initial))
548+
549+
def _evict_with_id_zero(self, cmd):
550+
# with id=0
551+
with self.assertRaises(CommandFailedError) as ce:
552+
self.fs.rank_tell(cmd + ['evict', 'id=0'])
553+
self.assertEqual(ce.exception.exitstatus, errno.EINVAL)
554+
555+
def _evict_with_invalid_id(self, cmd):
556+
# with invalid id
557+
with self.assertRaises(CommandFailedError) as ce:
558+
self.fs.rank_tell(cmd + ['evict', 'id=1'])
559+
self.assertEqual(ce.exception.exitstatus, errno.ESRCH)
560+
561+
def _evict_with_negative_id(self, cmd):
562+
# with negative id
563+
with self.assertRaises(CommandFailedError) as ce:
564+
self.fs.rank_tell(cmd + ['evict', 'id=-9'])
565+
self.assertEqual(ce.exception.exitstatus, errno.ESRCH)
566+
567+
def _evict_with_valid_id(self, cmd):
568+
info_initial = self.fs.rank_asok(cmd + ['ls'])
569+
mount_a_client_id = self.mount_a.get_global_id()
570+
# with a valid id
571+
self.fs.rank_asok(cmd + ['evict', f'id={mount_a_client_id}'])
572+
info = self.fs.rank_asok(cmd + ['ls'])
573+
self.assertEqual(len(info), len(info_initial) - 1) # client with id provided is evicted
574+
self.assertNotIn(mount_a_client_id, [val['id'] for val in info])
575+
576+
def _evict_all_clients(self, cmd):
577+
# with id=* to evict all clients
578+
info = self.fs.rank_asok(cmd + ['ls'])
579+
self.assertGreater(len(info), 0)
580+
self.fs.rank_asok(cmd + ['evict', 'id=*'])
581+
info = self.fs.rank_asok(cmd + ['ls'])
582+
self.assertEqual(len(info), 0) # multiple clients are evicted
583+
584+
@classmethod
585+
def _add_session_client_evictions(cls):
586+
tests = [
587+
"_evict_without_filter",
588+
"_evict_with_id_zero",
589+
"_evict_with_invalid_id",
590+
"_evict_with_negative_id",
591+
"_evict_with_valid_id",
592+
"_evict_all_clients",
593+
]
594+
def create_test(t, cmd):
595+
def test(self):
596+
getattr(self, t)(cmd)
597+
return test
598+
for t in tests:
599+
setattr(cls, 'test_session' + t, create_test(t, ['session']))
600+
setattr(cls, 'test_client' + t, create_test(t, ['client']))
601+
524602

525603
class TestCacheDrop(CephFSTestCase):
526604
CLIENTS_REQUIRED = 1

src/mds/MDSDaemon.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,11 @@ void MDSDaemon::set_up_admin_socket()
408408
asok_hook,
409409
"List client sessions based on a filter");
410410
ceph_assert(r == 0);
411-
r = admin_socket->register_command("session evict name=filters,type=CephString,n=N,req=false",
411+
r = admin_socket->register_command("session evict name=filters,type=CephString,n=N,req=true",
412412
asok_hook,
413413
"Evict client session(s) based on a filter");
414414
ceph_assert(r == 0);
415-
r = admin_socket->register_command("client evict name=filters,type=CephString,n=N,req=false",
415+
r = admin_socket->register_command("client evict name=filters,type=CephString,n=N,req=true",
416416
asok_hook,
417417
"Evict client session(s) based on a filter");
418418
ceph_assert(r == 0);

src/mds/MDSRank.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3137,7 +3137,7 @@ void MDSRankDispatcher::evict_clients(
31373137
dout(20) << __func__ << " matched " << victims.size() << " sessions" << dendl;
31383138

31393139
if (victims.empty()) {
3140-
on_finish(0, {}, outbl);
3140+
on_finish(-ESRCH, "no hosts match", outbl);
31413141
return;
31423142
}
31433143

src/mds/SessionMap.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,13 @@ int SessionFilter::parse(
12171217
state = v;
12181218
} else if (k == "id") {
12191219
std::string err;
1220+
if (v == "*") {
1221+
// evict all clients , by default id set to 0
1222+
return 0;
1223+
} else if (v == "0") {
1224+
*ss << "Invalid value";
1225+
return -CEPHFS_EINVAL;
1226+
}
12201227
id = strict_strtoll(v.c_str(), 10, &err);
12211228
if (!err.empty()) {
12221229
*ss << err;

0 commit comments

Comments
 (0)