]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
qa: add test_filelock_eviction
authorJohn Spray <john.spray@redhat.com>
Tue, 21 Mar 2017 14:38:47 +0000 (10:38 -0400)
committerJohn Spray <john.spray@redhat.com>
Tue, 23 May 2017 09:22:17 +0000 (05:22 -0400)
To check that eviction is releasing flocks.

Signed-off-by: John Spray <john.spray@redhat.com>
qa/tasks/cephfs/mount.py
qa/tasks/cephfs/test_client_recovery.py

index a86640ebef10c6628925a40f6f40b7a8be072bf1..4f96e6cdc21742c70ebb1450c37e8148354f5fb6 100644 (file)
@@ -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())
 
index 4b4085a915704553da119b5ffd49a5f7659c37a2..f3cc34d8516e6efdccad40b33844e9283e444124 100644 (file)
@@ -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);