@@ -638,6 +638,69 @@ def test_quiesce_path_splitauth(self):
638638 op = self .fs .rank_tell (["quiesce" , "path" , self .subvolume , '--wait' ], rank = 0 )['op' ]
639639 self .assertEqual (op ['result' ], - 1 ) # EPERM
640640
641+ def test_quiesce_authpin_wait (self ):
642+ """
643+ That a quiesce_inode op with outstanding remote authpin requests can be killed.
644+ """
645+
646+ self .config_set ('mds' , 'mds_heartbeat_grace' , '60' )
647+ self ._configure_subvolume ()
648+ self .mount_a .setfattr ("." , "ceph.dir.pin.distributed" , "1" )
649+ self ._client_background_workload ()
650+ self ._wait_distributed_subtrees (2 * 2 , rank = "all" , path = self .mntpnt )
651+ status = self .fs .status ()
652+
653+ p = self .mount_a .run_shell_payload ("ls" , stdout = StringIO ())
654+ dirs = p .stdout .getvalue ().strip ().split ()
655+
656+ # make rank 0 unresponsive to auth pin requests
657+ p = self .run_ceph_cmd ("tell" , f"mds.{ self .fs .id } :1" , "lockup" , "30000" , wait = False )
658+
659+ qops = []
660+ for d in dirs :
661+ path = os .path .join (self .mntpnt , d )
662+ op = self .fs .rank_tell ("quiesce" , "path" , path , rank = 0 )['op' ]
663+ reqid = self .reqid_tostr (op ['reqid' ])
664+ log .info (f"created { reqid } " )
665+ qops .append (reqid )
666+
667+ def find_quiesce (blocked_on_remote_auth_pin ):
668+ # verify no quiesce ops
669+ ops = self .fs .get_ops (locks = False , rank = 0 , path = "/tmp/mds.0-ops" , status = status )['ops' ]
670+ for op in ops :
671+ type_data = op ['type_data' ]
672+ flag_point = type_data ['flag_point' ]
673+ op_type = type_data ['op_type' ]
674+ if op_type == 'client_request' or op_type == 'peer_request' :
675+ continue
676+ if type_data ['op_name' ] == "quiesce_inode" :
677+ if blocked_on_remote_auth_pin :
678+ if flag_point == "requesting remote authpins" :
679+ return True
680+ else :
681+ return True
682+ return False
683+
684+ with safe_while (sleep = 1 , tries = 30 , action = 'wait for quiesce op with outstanding remote authpin requests' ) as proceed :
685+ while proceed ():
686+ if find_quiesce (True ):
687+ break
688+
689+ # okay, now kill all quiesce ops
690+ for reqid in qops :
691+ self .fs .kill_op (reqid , rank = 0 )
692+
693+ # verify some quiesce_inode ops still exist because authpin acks have not been received
694+ if not find_quiesce (True ):
695+ self .fail ("did not find quiesce_inode op blocked on remote authpins!" )
696+
697+ # wait for sleep to complete
698+ p .wait ()
699+
700+ with safe_while (sleep = 1 , tries = 30 , action = 'wait for quiesce kill' ) as proceed :
701+ while proceed ():
702+ if not find_quiesce (False ):
703+ break
641704
642705 def test_quiesce_path_multirank (self ):
643706 """
0 commit comments