import os
from teuthology.orchestra.run import CommandFailedError, ConnectionLostError
+from tasks.cephfs.fuse_mount import FuseMount
from tasks.cephfs.cephfs_test_case import CephFSTestCase
from teuthology.packaging import get_package_version
+from unittest import SkipTest
log = logging.getLogger(__name__)
self.mount_b.mount()
self.mount_b.wait_until_mounted()
self.mount_b.run_shell(["ls", "subdir/childfile"])
+
+ def test_stale_renew(self):
+ if not isinstance(self.mount_a, FuseMount):
+ raise SkipTest("Require FUSE client to handle signal STOP/CONT")
+
+ self.mount_a.run_shell(["mkdir", "testdir"])
+ self.mount_a.run_shell(["touch", "testdir/file1"])
+ # populate readdir cache
+ self.mount_a.run_shell(["ls", "testdir"])
+ self.mount_b.run_shell(["ls", "testdir"])
+
+ # check if readdir cache is effective
+ initial_readdirs = self.fs.mds_asok(['perf', 'dump', 'mds_server', 'req_readdir_latency'])
+ self.mount_b.run_shell(["ls", "testdir"])
+ current_readdirs = self.fs.mds_asok(['perf', 'dump', 'mds_server', 'req_readdir_latency'])
+ self.assertEqual(current_readdirs, initial_readdirs);
+
+ mount_b_gid = self.mount_b.get_global_id()
+ mount_b_pid = self.mount_b.get_client_pid()
+ # stop ceph-fuse process of mount_b
+ self.mount_b.client_remote.run(args=["sudo", "kill", "-STOP", mount_b_pid])
+
+ self.assert_session_state(mount_b_gid, "open")
+ time.sleep(self.mds_session_timeout * 1.5) # Long enough for MDS to consider session stale
+ self.assert_session_state(mount_b_gid, "stale")
+
+ self.mount_a.run_shell(["touch", "testdir/file2"])
+
+ # resume ceph-fuse process of mount_b
+ self.mount_b.client_remote.run(args=["sudo", "kill", "-CONT", mount_b_pid])
+ # Is the new file visible from mount_b? (caps become invalid after session stale)
+ self.mount_b.run_shell(["ls", "testdir/file2"])
+
+ def test_unmount_for_evicted_client(self):
+ """Test if client hangs on unmount after evicting the client."""
+ mount_a_client_id = self.mount_a.get_global_id()
+ self.fs.mds_asok(['session', 'evict', "%s" % mount_a_client_id])
+
+ self.mount_a.umount_wait(require_clean=True, timeout=30)