]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
qa/cephfs: update tests for stale session handling
authorYan, Zheng <zyan@redhat.com>
Tue, 5 Mar 2019 09:40:08 +0000 (17:40 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 21 Oct 2019 02:52:22 +0000 (10:52 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit 1c8be588e32f47ca712561711ad1ffdddc54b330)

 Conflicts:
qa/tasks/cephfs/test_client_recovery.py

qa/tasks/cephfs/mount.py
qa/tasks/cephfs/test_client_recovery.py
src/common/options.cc
src/mds/Server.cc

index 0e8059d505d2243925e9cc826c66e9e383d4d650..431fc2e004a66c61103e9b61c2615fdffc827d55 100644 (file)
@@ -175,7 +175,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.
@@ -187,16 +187,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 2a2fa0a31e3a09cf7142f6ee67eb1841609c81e1..b3532434fe62aefe5a36685237f178291bc67ab3 100644 (file)
@@ -45,6 +45,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()
@@ -213,12 +214,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
@@ -242,6 +253,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,
@@ -262,6 +278,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
         # ===================================
@@ -517,9 +539,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])
index 70af216ba13b9649a80ee227ce093d5f2949432a..2dc986f4153bbf0e5cf7db373037f4e2553ff1f5 100644 (file)
@@ -7163,6 +7163,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 a37f5b9c93a2e2b670a0833c77928488a9e6bd41..e0cd4c9265e21378ac140c1b2c9a8242bc6ed2e0 100644 (file)
@@ -781,6 +781,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;
 
@@ -813,7 +814,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;