From 47a9c9ba671a8b023aaa1a76a3ecf94199ce87ea Mon Sep 17 00:00:00 2001 From: John Spray Date: Tue, 21 Mar 2017 10:38:47 -0400 Subject: [PATCH] qa: add test_filelock_eviction To check that eviction is releasing flocks. Signed-off-by: John Spray --- qa/tasks/cephfs/mount.py | 22 ++++++++++++- qa/tasks/cephfs/test_client_recovery.py | 44 +++++++++++++++++++++---- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/qa/tasks/cephfs/mount.py b/qa/tasks/cephfs/mount.py index a86640ebef10c..4f96e6cdc2174 100644 --- a/qa/tasks/cephfs/mount.py +++ b/qa/tasks/cephfs/mount.py @@ -230,11 +230,31 @@ class CephFSMount(object): pyscript = dedent(script_builder).format(path=path) - log.info("lock file {0}".format(basename)) + log.info("lock_background file {0}".format(basename)) rproc = self._run_python(pyscript) self.background_procs.append(rproc) return rproc + def lock_and_release(self, basename="background_file"): + assert(self.is_mounted()) + + path = os.path.join(self.mountpoint, basename) + + script = """ + import time + import fcntl + import struct + f1 = open("{path}-1", 'w') + fcntl.flock(f1, fcntl.LOCK_EX) + f2 = open("{path}-2", 'w') + lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) + fcntl.fcntl(f2, fcntl.F_SETLK, lockdata) + """ + pyscript = dedent(script).format(path=path) + + log.info("lock_and_release file {0}".format(basename)) + return self._run_python(pyscript) + def check_filelock(self, basename="background_file", do_flock=True): assert(self.is_mounted()) diff --git a/qa/tasks/cephfs/test_client_recovery.py b/qa/tasks/cephfs/test_client_recovery.py index 4b4085a915704..f3cc34d8516e6 100644 --- a/qa/tasks/cephfs/test_client_recovery.py +++ b/qa/tasks/cephfs/test_client_recovery.py @@ -331,10 +331,7 @@ class TestClientRecovery(CephFSTestCase): count, num_caps )) - def test_filelock(self): - """ - Check that file lock doesn't get lost after an MDS restart - """ + def _is_flockable(self): a_version_str = get_package_version(self.mount_a.client_remote, "fuse") b_version_str = get_package_version(self.mount_b.client_remote, "fuse") flock_version_str = "2.9" @@ -348,14 +345,20 @@ class TestClientRecovery(CephFSTestCase): b_version = version.StrictVersion(b_result.group()) flock_version=version.StrictVersion(flock_version_str) - flockable = False if (a_version >= flock_version and b_version >= flock_version): - log.info("testing flock locks") - flockable = True + log.info("flock locks are available") + return True else: log.info("not testing flock locks, machines have versions {av} and {bv}".format( av=a_version_str,bv=b_version_str)) + return False + + def test_filelock(self): + """ + Check that file lock doesn't get lost after an MDS restart + """ + flockable = self._is_flockable() lock_holder = self.mount_a.lock_background(do_flock=flockable) self.mount_b.wait_for_visible("background_file-2") @@ -374,6 +377,33 @@ class TestClientRecovery(CephFSTestCase): # We killed it, so it raises an error pass + def test_filelock_eviction(self): + """ + Check that file lock held by evicted client is given to + waiting client. + """ + if not self._is_flockable(): + self.skipTest("flock is not available") + + lock_holder = self.mount_a.lock_background() + self.mount_b.wait_for_visible("background_file-2") + self.mount_b.check_filelock() + + lock_taker = self.mount_b.lock_and_release() + # Check the taker is waiting (doesn't get it immediately) + time.sleep(2) + self.assertFalse(lock_holder.finished) + self.assertFalse(lock_taker.finished) + + mount_a_client_id = self.mount_a.get_global_id() + self.fs.mds_asok(['session', 'evict', "%s" % mount_a_client_id]) + + # Evicting mount_a should let mount_b's attepmt to take the lock + # suceed + self.wait_until_true( + lambda: lock_taker.finished, + timeout=10) + def test_dir_fsync(self): self._test_fsync(True); -- 2.39.5