]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
qa/cephfs: update tests for stale session handling 26737/head
authorYan, Zheng <zyan@redhat.com>
Tue, 5 Mar 2019 09:40:08 +0000 (17:40 +0800)
committerYan, Zheng <zyan@redhat.com>
Sat, 8 Jun 2019 13:15:14 +0000 (21:15 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
qa/tasks/cephfs/mount.py
qa/tasks/cephfs/test_client_recovery.py
src/common/options.cc
src/mds/Server.cc

index ca8a3a7d7e6b154fdae545aefbd758c437aed6c7..4a6917e39290bfcc2c8862b20d08360f66f42ce7 100644 (file)
@@ -205,7 +205,7 @@ class CephFSMount(object):
         ))
         p.wait()
 
-    def open_background(self, basename="background_file"):
+    def open_background(self, basename="background_file", write=True):
         """
         Open a file for writing, then block such that the client
         will hold a capability.
@@ -217,16 +217,25 @@ class CephFSMount(object):
 
         path = os.path.join(self.mountpoint, basename)
 
-        pyscript = dedent("""
-            import time
+        if write:
+            pyscript = dedent("""
+                import time
 
-            f = open("{path}", 'w')
-            f.write('content')
-            f.flush()
-            f.write('content2')
-            while True:
-                time.sleep(1)
-            """).format(path=path)
+                f = open("{path}", 'w')
+                f.write('content')
+                f.flush()
+                f.write('content2')
+                while True:
+                    time.sleep(1)
+                """).format(path=path)
+        else:
+            pyscript = dedent("""
+                import time
+
+                f = open("{path}", 'r')
+                while True:
+                    time.sleep(1)
+                """).format(path=path)
 
         rproc = self._run_python(pyscript)
         self.background_procs.append(rproc)
index d2ebaa30bc170610e5fc64f1712f448c925e1e29..3645d134238b2789d552ff17864a0eecc8d45b82 100644 (file)
@@ -43,6 +43,7 @@ class TestClientNetworkRecovery(CephFSTestCase):
         """
 
         session_timeout = self.fs.get_var("session_timeout")
+        self.fs.mds_asok(['config', 'set', 'mds_defer_session_stale', 'false'])
 
         # We only need one client
         self.mount_b.umount_wait()
@@ -211,12 +212,22 @@ class TestClientRecovery(CephFSTestCase):
         self.mount_a.wait_until_mounted()
         self.mount_a.create_destroy()
 
-    def test_stale_caps(self):
+    def _test_stale_caps(self, write):
         session_timeout = self.fs.get_var("session_timeout")
 
         # Capability release from stale session
         # =====================================
-        cap_holder = self.mount_a.open_background()
+        if write:
+            cap_holder = self.mount_a.open_background()
+        else:
+            self.mount_a.run_shell(["touch", "background_file"])
+            self.mount_a.umount_wait()
+            self.mount_a.mount()
+            self.mount_a.wait_until_mounted()
+            cap_holder = self.mount_a.open_background(write=False)
+
+        self.assert_session_count(2)
+        mount_a_gid = self.mount_a.get_global_id()
 
         # Wait for the file to be visible from another client, indicating
         # that mount_a has completed its network ops
@@ -237,6 +248,11 @@ class TestClientRecovery(CephFSTestCase):
             # Should have succeeded
             self.assertEqual(cap_waiter.exitstatus, 0)
 
+            if write:
+                self.assert_session_count(1)
+            else:
+                self.assert_session_state(mount_a_gid, "stale")
+
             cap_waited = b - a
             log.info("cap_waiter waited {0}s".format(cap_waited))
             self.assertTrue(session_timeout / 2.0 <= cap_waited <= session_timeout * 2.0,
@@ -257,6 +273,12 @@ class TestClientRecovery(CephFSTestCase):
         self.mount_a.mount()
         self.mount_a.wait_until_mounted()
 
+    def test_stale_read_caps(self):
+        self._test_stale_caps(False)
+
+    def test_stale_write_caps(self):
+        self._test_stale_caps(True)
+
     def test_evicted_caps(self):
         # Eviction while holding a capability
         # ===================================
@@ -509,9 +531,9 @@ class TestClientRecovery(CephFSTestCase):
 
         self.assert_session_state(mount_b_gid, "open")
         time.sleep(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"])
+        self.assert_session_state(mount_b_gid, "stale")
 
         # resume ceph-fuse process of mount_b
         self.mount_b.client_remote.run(args=["sudo", "kill", "-CONT", mount_b_pid])
@@ -525,6 +547,7 @@ class TestClientRecovery(CephFSTestCase):
         if not isinstance(self.mount_a, FuseMount):
             self.skipTest("Testing libcephfs function")
 
+        self.fs.mds_asok(['config', 'set', 'mds_defer_session_stale', 'false'])
         session_timeout = self.fs.get_var("session_timeout")
 
         self.mount_a.umount_wait()
index b1d6b2b7c737e7022585366588174e50fbd48d52..6f8f15f370a898d4efd0deefaa52e36bb43e7314 100644 (file)
@@ -7994,6 +7994,9 @@ std::vector<Option> get_mds_options() {
      .set_default(0)
      .set_description("INTENTIONALLY CAUSE DATA LOSS by bypasing checks for invalid metadata on disk. Allows testing repair tools."),
 
+    Option("mds_defer_session_stale", Option::TYPE_BOOL, Option::LEVEL_DEV)
+     .set_default(true),
+
     Option("mds_inject_migrator_session_race", Option::TYPE_BOOL, Option::LEVEL_DEV)
      .set_default(false),
 
index 476843da0e64614c587c71f76aec09d4241bd143..8651643e4744bd204f07a0e8ff14b0015799a818 100644 (file)
@@ -932,6 +932,7 @@ void Server::find_idle_sessions()
   //  (caps go stale, lease die)
   double queue_max_age = mds->get_dispatch_queue_max_age(ceph_clock_now());
   double cutoff = queue_max_age + mds->mdsmap->get_session_timeout();
+  bool defer_session_stale = g_conf().get_val<bool>("mds_defer_session_stale");
 
   std::vector<Session*> to_evict;
 
@@ -964,7 +965,8 @@ void Server::find_idle_sessions()
        continue;
       }
 
-      if (!session->is_any_flush_waiter() &&
+      if (defer_session_stale &&
+         !session->is_any_flush_waiter() &&
          !mds->locker->is_revoking_any_caps_from(session->get_client())) {
        dout(20) << "deferring marking session " << session->info.inst << " stale "
                    "since it holds no caps" << dendl;