@@ -19,6 +19,7 @@ def add_options(p):
1919 p .add_argument ('--enable-kill-tablets' , action = 'store_true' , help = 'Enable tablet killer' )
2020 p .add_argument ('--enable-kill-blob-depot' , action = 'store_true' , help = 'Enable BlobDepot killer' )
2121 p .add_argument ('--enable-restart-pdisks' , action = 'store_true' , help = 'Enable PDisk restarter' )
22+ p .add_argument ('--enable-readonly-pdisks' , action = 'store_true' , help = 'Enable SetPDiskReadOnly requests' )
2223 p .add_argument ('--kill-signal' , type = str , default = 'KILL' , help = 'Kill signal to send to restart node' )
2324 p .add_argument ('--sleep-before-rounds' , type = float , default = 1 , help = 'Seconds to sleep before rounds' )
2425 p .add_argument ('--no-fail-model-check' , action = 'store_true' , help = 'Do not check VDisk states before taking action' )
@@ -104,6 +105,12 @@ def do(args):
104105 if vslot .ReadOnly
105106 }
106107
108+ pdisk_readonly = {
109+ (pdisk .NodeId , pdisk .PDiskId )
110+ for pdisk in base_config .PDisk
111+ if pdisk .ReadOnly
112+ }
113+
107114 if (len (pdisk_keys ) == 0 ):
108115 # initialize pdisk_keys and pdisk_key_versions
109116 for node_id in {pdisk .NodeId for pdisk in base_config .PDisk }:
@@ -144,6 +151,25 @@ def match(x):
144151 return False
145152 return True
146153
154+ def can_act_on_pdisk (node_id , pdisk_id ):
155+ def match (x ):
156+ return node_id == x [0 ] and pdisk_id == x [1 ]
157+
158+ for group in base_config .Group :
159+ if any (map (match , map (common .get_vslot_id , group .VSlotId ))):
160+ if not common .is_dynamic_group (group .GroupId ):
161+ return False
162+
163+ content = {
164+ common .get_vdisk_id_short (vslot ): not match (vslot_id ) and vslot .Ready and vdisk_status [vslot_id + common .get_vdisk_id (vslot )]
165+ for vslot_id in map (common .get_vslot_id , group .VSlotId )
166+ for vslot in [vslot_map [vslot_id ]]
167+ }
168+ common .print_if_verbose (args , content , file = sys .stderr )
169+ if not grouptool .check_fail_model (content , group .ErasureSpecies ):
170+ return False
171+ return True
172+
147173 def do_restart (node_id ):
148174 host = node_fqdn_map [node_id ]
149175 if args .enable_pdisk_encryption_keys_changes :
@@ -166,6 +192,20 @@ def do_restart_pdisk(node_id, pdisk_id):
166192 if not response .Success :
167193 raise Exception ('Unexpected error from BSC: %s' % response .ErrorDescription )
168194
195+ def do_readonly_pdisk (node_id , pdisk_id , readonly ):
196+ assert can_act_on_vslot (node_id , pdisk_id )
197+ request = common .kikimr_bsconfig .TConfigRequest (IgnoreDegradedGroupsChecks = True )
198+ cmd = request .Command .add ().SetPDiskReadOnly
199+ cmd .TargetPDiskId .NodeId = node_id
200+ cmd .TargetPDiskId .PDiskId = pdisk_id
201+ cmd .Value = readonly
202+ try :
203+ response = common .invoke_bsc_request (request )
204+ except Exception as e :
205+ raise Exception ('failed to perform SetPDiskReadOnly request: %s' % e )
206+ if not response .Success :
207+ raise Exception ('Unexpected error from BSC: %s' % response .ErrorDescription )
208+
169209 def do_evict (vslot_id ):
170210 assert can_act_on_vslot (* vslot_id )
171211 try :
@@ -253,15 +293,16 @@ def do_kill_blob_depot():
253293 readonlies = []
254294 unreadonlies = []
255295 pdisk_restarts = []
296+ make_pdisks_readonly = []
297+ make_pdisks_not_readonly = []
256298
257299 for vslot in base_config .VSlot :
258300 if common .is_dynamic_group (vslot .GroupId ):
259301 vslot_id = common .get_vslot_id (vslot .VSlotId )
302+ node_id , pdisk_id = vslot_id [:2 ]
260303 vdisk_id = '[%08x:%d:%d:%d]' % (vslot .GroupId , vslot .FailRealmIdx , vslot .FailDomainIdx , vslot .VDiskIdx )
261304 if vslot_id in vslot_readonly and not args .disable_readonly :
262305 unreadonlies .append (('un-readonly vslot id: %s, vdisk id: %s' % (vslot_id , vdisk_id ), (do_readonly , vslot , False )))
263- if can_act_on_vslot (* vslot_id [:2 ]) and args .enable_restart_pdisks :
264- pdisk_restarts .append (('restart pdisk node_id: %d, pdisk_id: %d' % vslot_id [:2 ], (do_restart_pdisk , * vslot_id [:2 ])))
265306 if can_act_on_vslot (* vslot_id ) and (recent_restarts or args .disable_restarts ):
266307 if not args .disable_evicts :
267308 evicts .append (('evict vslot id: %s, vdisk id: %s' % (vslot_id , vdisk_id ), (do_evict , vslot_id )))
@@ -270,6 +311,18 @@ def do_kill_blob_depot():
270311 if not args .disable_readonly :
271312 readonlies .append (('readonly vslot id: %s, vdisk id: %s' % (vslot_id , vdisk_id ), (do_readonly , vslot , True )))
272313
314+ for pdisk in base_config .PDisk :
315+ node_id , pdisk_id = pdisk .NodeId , pdisk .PDiskId
316+
317+ if can_act_on_pdisk (node_id , pdisk_id ):
318+ if args .enable_restart_pdisks :
319+ pdisk_restarts .append (('restart pdisk node_id: %d, pdisk_id: %d' % (node_id , pdisk_id ), (do_restart_pdisk , node_id , pdisk_id )))
320+ if args .enable_readonly_pdisks :
321+ make_pdisks_readonly .append (('readonly pdisk node_id: %d, pdisk_id: %d' % (node_id , pdisk_id ), (do_readonly_pdisk , node_id , pdisk_id , True )))
322+
323+ if (node_id , pdisk_id ) in pdisk_readonly and args .enable_readonly_pdisks :
324+ make_pdisks_not_readonly .append (('un-readonly pdisk node_id: %d, pdisk_id: %d' % (node_id , pdisk_id ), (do_readonly_pdisk , node_id , pdisk_id , False )))
325+
273326 def pick (v ):
274327 action_name , action = random .choice (v )
275328 print (action_name )
@@ -285,6 +338,10 @@ def pick(v):
285338 possible_actions .append (('un-readonly' , (pick , unreadonlies )))
286339 if pdisk_restarts :
287340 possible_actions .append (('restart-pdisk' , (pick , pdisk_restarts )))
341+ if make_pdisks_readonly :
342+ possible_actions .append (('make-pdisks-readonly' , (pick , make_pdisks_readonly )))
343+ if make_pdisks_not_readonly :
344+ possible_actions .append (('make-pdisks-not-readonly' , (pick , make_pdisks_not_readonly )))
288345
289346 restarts = []
290347
0 commit comments