@@ -101,6 +101,16 @@ def scrub(self):
101101 self .assert_equal (out_json ["return_code" ], 0 )
102102 self .assert_equal (self ._filesystem .wait_until_scrub_complete (tag = out_json ["scrub_tag" ]), True )
103103
104+ def mangle (self ):
105+ """
106+ Gives an opportunity to fiddle with metadata objects before bringing back
107+ the MDSs online. This is used in testing the lost+found case (when recovering
108+ a file without a backtrace) to verify if lost+found directory object can be
109+ removed via RADOS operation and the file system can be continued to be used
110+ as expected.
111+ """
112+ pass
113+
104114class SimpleWorkload (Workload ):
105115 """
106116 Single file, single directory, check that it gets recovered and so does its size
@@ -190,6 +200,23 @@ def validate(self):
190200
191201 return self ._errors
192202
203+ class BacktracelessFileRemoveLostAndFoundDirectory (Workload ):
204+ def write (self ):
205+ self ._mount .run_shell (["mkdir" , "subdir" ])
206+ self ._mount .write_n_mb ("subdir/sixmegs" , 6 )
207+ self ._initial_state = self ._mount .stat ("subdir/sixmegs" )
208+
209+ def flush (self ):
210+ # Never flush metadata, so backtrace won't be written
211+ pass
212+
213+ def mangle (self ):
214+ self ._filesystem .rados (["-p" , self ._filesystem .get_metadata_pool_name (), "rm" , "4.00000000" ])
215+ self ._filesystem .rados (["-p" , self ._filesystem .get_metadata_pool_name (), "rmomapkey" , "1.00000000" , "lost+found_head" ])
216+
217+ def validate (self ):
218+ # The dir should be gone since we manually removed it
219+ self .assert_not_equal (self ._mount .ls (sudo = True ), ["lost+found" ])
193220
194221class StripedStashedLayout (Workload ):
195222 def __init__ (self , fs , m , pool = None ):
@@ -427,6 +454,8 @@ def get_state(mds_id):
427454 self .fs .data_scan (["scan_inodes" ], worker_count = workers )
428455 self .fs .data_scan (["scan_links" ])
429456
457+ workload .mangle ()
458+
430459 # Mark the MDS repaired
431460 self .run_ceph_cmd ('mds' , 'repaired' , '0' )
432461
@@ -435,13 +464,13 @@ def get_state(mds_id):
435464 self .fs .wait_for_daemons ()
436465 log .info (str (self .mds_cluster .status ()))
437466
438- # Mount a client
439- self .mount_a .mount_wait ()
440-
441467 # run scrub as it is recommended post recovery for most
442468 # (if not all) recovery mechanisms.
443469 workload .scrub ()
444470
471+ # Mount a client
472+ self .mount_a .mount_wait ()
473+
445474 # See that the files are present and correct
446475 errors = workload .validate ()
447476 if errors :
@@ -465,6 +494,9 @@ def test_rebuild_moved_file(self):
465494 def test_rebuild_backtraceless (self ):
466495 self ._rebuild_metadata (BacktracelessFile (self .fs , self .mount_a ))
467496
497+ def test_rebuild_backtraceless_with_lf_dir_removed (self ):
498+ self ._rebuild_metadata (BacktracelessFileRemoveLostAndFoundDirectory (self .fs , self .mount_a ))
499+
468500 def test_rebuild_moved_dir (self ):
469501 self ._rebuild_metadata (MovedDir (self .fs , self .mount_a ))
470502
0 commit comments