From: 胡玮文 Date: Tue, 18 Jan 2022 10:02:10 +0000 (+0800) Subject: qa: reproduce the crash when exporting unlinked dir X-Git-Tag: v17.2.4~80^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8abe63b6673150529afb93d1a68934d67f5dff70;p=ceph.git qa: reproduce the crash when exporting unlinked dir Signed-off-by: 胡玮文 (cherry picked from commit 9558a6ada253db889bad9d0d0236b00de662eae0) --- diff --git a/qa/tasks/cephfs/mount.py b/qa/tasks/cephfs/mount.py index 41ebcba8587f..4a83cb432390 100644 --- a/qa/tasks/cephfs/mount.py +++ b/qa/tasks/cephfs/mount.py @@ -837,6 +837,31 @@ class CephFSMount(object): return rproc + def open_dir_background(self, basename): + """ + Create and hold a capability to a directory. + """ + assert(self.is_mounted()) + + path = os.path.join(self.hostfs_mntpt, basename) + + pyscript = dedent(""" + import time + import os + + os.mkdir("{path}") + fd = os.open("{path}", os.O_RDONLY) + while True: + time.sleep(1) + """).format(path=path) + + rproc = self._run_python(pyscript) + self.background_procs.append(rproc) + + self.wait_for_visible(basename) + + return rproc + def wait_for_dir_empty(self, dirname, timeout=30): dirpath = os.path.join(self.hostfs_mntpt, dirname) with safe_while(sleep=5, tries=(timeout//5)) as proceed: diff --git a/qa/tasks/cephfs/test_strays.py b/qa/tasks/cephfs/test_strays.py index 582f1a81bcd4..8bdc126e2b64 100644 --- a/qa/tasks/cephfs/test_strays.py +++ b/qa/tasks/cephfs/test_strays.py @@ -602,7 +602,6 @@ class TestStrays(CephFSTestCase): """ :param to_id: MDS id to move it to :param path: Filesystem path (string) to move - :param watch_ino: Inode number to look for at destination to confirm move :return: None """ self.mount_a.run_shell(["setfattr", "-n", "ceph.dir.pin", "-v", str(rank), path]) @@ -700,6 +699,46 @@ ln dir_1/original dir_2/linkto # See that the stray counter on rank 0 has incremented self.assertEqual(self.get_mdc_stat("strays_created", rank_0_id), 1) + def test_migrate_unlinked_dir(self): + """ + Reproduce https://tracker.ceph.com/issues/53597 + """ + rank_0_id, rank_1_id = self._setup_two_ranks() + + self.mount_a.run_shell_payload(""" +mkdir pin +touch pin/placeholder +""") + + self._force_migrate("pin") + + # Hold the dir open so it cannot be purged + p = self.mount_a.open_dir_background("pin/to-be-unlinked") + + # Unlink the dentry + self.mount_a.run_shell(["rmdir", "pin/to-be-unlinked"]) + + # Wait to see the stray count increment + self.wait_until_equal( + lambda: self.get_mdc_stat("num_strays", mds_id=rank_1_id), + expect_val=1, timeout=60, reject_fn=lambda x: x > 1) + # but not purged + self.assertEqual(self.get_mdc_stat("strays_created", mds_id=rank_1_id), 1) + self.assertEqual(self.get_mdc_stat("strays_enqueued", mds_id=rank_1_id), 0) + + # Test loading unlinked dir into cache + self.fs.mds_asok(['flush', 'journal'], rank_1_id) + self.fs.mds_asok(['cache', 'drop'], rank_1_id) + + # Shut down rank 1 + self.fs.set_max_mds(1) + self.fs.wait_for_daemons(timeout=120) + # Now the stray should be migrated to rank 0 + # self.assertEqual(self.get_mdc_stat("strays_created", mds_id=rank_0_id), 1) + # https://github.com/ceph/ceph/pull/44335#issuecomment-1125940158 + + self.mount_a.kill_background(p) + def assert_backtrace(self, ino, expected_path): """ Assert that the backtrace in the data pool for an inode matches