|
3 | 3 | from tasks.cephfs.fuse_mount import FuseMount |
4 | 4 | from tasks.cephfs.cephfs_test_case import CephFSTestCase |
5 | 5 | from teuthology.exceptions import CommandFailedError |
| 6 | +from textwrap import dedent |
| 7 | +from threading import Thread |
6 | 8 | import errno |
7 | 9 | import platform |
8 | 10 | import time |
9 | 11 | import json |
10 | 12 | import logging |
| 13 | +import os |
11 | 14 |
|
12 | 15 | log = logging.getLogger(__name__) |
13 | 16 |
|
@@ -235,6 +238,128 @@ def test_fs_lsflags(self): |
235 | 238 | self.assertEqual(lsflags["allow_multimds_snaps"], True) |
236 | 239 | self.assertEqual(lsflags["allow_standby_replay"], True) |
237 | 240 |
|
| 241 | + def _test_sync_stuck_for_around_5s(self, dir_path, file_sync=False): |
| 242 | + self.mount_a.run_shell(["mkdir", dir_path]) |
| 243 | + |
| 244 | + sync_dir_pyscript = dedent(""" |
| 245 | + import os |
| 246 | +
|
| 247 | + path = "{path}" |
| 248 | + dfd = os.open(path, os.O_DIRECTORY) |
| 249 | + os.fsync(dfd) |
| 250 | + os.close(dfd) |
| 251 | + """.format(path=dir_path)) |
| 252 | + |
| 253 | + # run create/delete directories and test the sync time duration |
| 254 | + for i in range(300): |
| 255 | + for j in range(5): |
| 256 | + self.mount_a.run_shell(["mkdir", os.path.join(dir_path, f"{i}_{j}")]) |
| 257 | + start = time.time() |
| 258 | + if file_sync: |
| 259 | + self.mount_a.run_shell(['python3', '-c', sync_dir_pyscript]) |
| 260 | + else: |
| 261 | + self.mount_a.run_shell(["sync"]) |
| 262 | + duration = time.time() - start |
| 263 | + log.info(f"sync mkdir i = {i}, duration = {duration}") |
| 264 | + self.assertLess(duration, 4) |
| 265 | + |
| 266 | + for j in range(5): |
| 267 | + self.mount_a.run_shell(["rm", "-rf", os.path.join(dir_path, f"{i}_{j}")]) |
| 268 | + start = time.time() |
| 269 | + if file_sync: |
| 270 | + self.mount_a.run_shell(['python3', '-c', sync_dir_pyscript]) |
| 271 | + else: |
| 272 | + self.mount_a.run_shell(["sync"]) |
| 273 | + duration = time.time() - start |
| 274 | + log.info(f"sync rmdir i = {i}, duration = {duration}") |
| 275 | + self.assertLess(duration, 4) |
| 276 | + |
| 277 | + self.mount_a.run_shell(["rm", "-rf", dir_path]) |
| 278 | + |
| 279 | + def test_filesystem_sync_stuck_for_around_5s(self): |
| 280 | + """ |
| 281 | + To check whether the fsync will be stuck to wait for the mdlog to be |
| 282 | + flushed for at most 5 seconds. |
| 283 | + """ |
| 284 | + |
| 285 | + dir_path = "filesystem_sync_do_not_wait_mdlog_testdir" |
| 286 | + self._test_sync_stuck_for_around_5s(dir_path) |
| 287 | + |
| 288 | + def test_file_sync_stuck_for_around_5s(self): |
| 289 | + """ |
| 290 | + To check whether the filesystem sync will be stuck to wait for the |
| 291 | + mdlog to be flushed for at most 5 seconds. |
| 292 | + """ |
| 293 | + |
| 294 | + dir_path = "file_sync_do_not_wait_mdlog_testdir" |
| 295 | + self._test_sync_stuck_for_around_5s(dir_path, True) |
| 296 | + |
| 297 | + def test_file_filesystem_sync_crash(self): |
| 298 | + """ |
| 299 | + To check whether the kernel crashes when doing the file/filesystem sync. |
| 300 | + """ |
| 301 | + |
| 302 | + stop_thread = False |
| 303 | + dir_path = "file_filesystem_sync_crash_testdir" |
| 304 | + self.mount_a.run_shell(["mkdir", dir_path]) |
| 305 | + |
| 306 | + def mkdir_rmdir_thread(mount, path): |
| 307 | + #global stop_thread |
| 308 | + |
| 309 | + log.info(" mkdir_rmdir_thread starting...") |
| 310 | + num = 0 |
| 311 | + while not stop_thread: |
| 312 | + n = num |
| 313 | + m = num |
| 314 | + for __ in range(10): |
| 315 | + mount.run_shell(["mkdir", os.path.join(path, f"{n}")]) |
| 316 | + n += 1 |
| 317 | + for __ in range(10): |
| 318 | + mount.run_shell(["rm", "-rf", os.path.join(path, f"{m}")]) |
| 319 | + m += 1 |
| 320 | + num += 10 |
| 321 | + log.info(" mkdir_rmdir_thread stopped") |
| 322 | + |
| 323 | + def filesystem_sync_thread(mount, path): |
| 324 | + #global stop_thread |
| 325 | + |
| 326 | + log.info(" filesystem_sync_thread starting...") |
| 327 | + while not stop_thread: |
| 328 | + mount.run_shell(["sync"]) |
| 329 | + log.info(" filesystem_sync_thread stopped") |
| 330 | + |
| 331 | + def file_sync_thread(mount, path): |
| 332 | + #global stop_thread |
| 333 | + |
| 334 | + log.info(" file_sync_thread starting...") |
| 335 | + pyscript = dedent(""" |
| 336 | + import os |
| 337 | +
|
| 338 | + path = "{path}" |
| 339 | + dfd = os.open(path, os.O_DIRECTORY) |
| 340 | + os.fsync(dfd) |
| 341 | + os.close(dfd) |
| 342 | + """.format(path=path)) |
| 343 | + |
| 344 | + while not stop_thread: |
| 345 | + mount.run_shell(['python3', '-c', pyscript]) |
| 346 | + log.info(" file_sync_thread stopped") |
| 347 | + |
| 348 | + td1 = Thread(target=mkdir_rmdir_thread, args=(self.mount_a, dir_path,)) |
| 349 | + td2 = Thread(target=filesystem_sync_thread, args=(self.mount_a, dir_path,)) |
| 350 | + td3 = Thread(target=file_sync_thread, args=(self.mount_a, dir_path,)) |
| 351 | + |
| 352 | + td1.start() |
| 353 | + td2.start() |
| 354 | + td3.start() |
| 355 | + time.sleep(1200) # run 20 minutes |
| 356 | + stop_thread = True |
| 357 | + td1.join() |
| 358 | + td2.join() |
| 359 | + td3.join() |
| 360 | + self.mount_a.run_shell(["rm", "-rf", dir_path]) |
| 361 | + |
| 362 | + |
238 | 363 | class TestCacheDrop(CephFSTestCase): |
239 | 364 | CLIENTS_REQUIRED = 1 |
240 | 365 |
|
|
0 commit comments