qa: reproduce the crash when exporting unlinked dir

Signed-off-by: 胡玮文 <huww98@outlook.com>
This commit is contained in:
胡玮文 2022-01-18 18:02:10 +08:00
parent fcdee48669
commit 9558a6ada2
2 changed files with 65 additions and 1 deletions

View File

@ -846,6 +846,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:

View File

@ -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