@@ -555,6 +555,20 @@ def update_slaves_on_cbt_disable(self, cbtlog):
555555 # Override in implementation as required.
556556 pass
557557
558+ def _list_vdi_snapshots (self ):
559+ """List vdi of all direct snapshots of a VDI"""
560+ snapshots = []
561+ vdi_record = self .session .xenapi .VDI .get_record (self .sr .srcmd .params ['vdi_ref' ])
562+ try :
563+ for opaque_ref in vdi_record .get ("snapshots" , []):
564+ snapshot_record = self .session .xenapi .VDI .get_record (opaque_ref )
565+ snapshot_uuid = self .session .xenapi .VDI .get_uuid (opaque_ref )
566+ snapshots .append (self .from_uuid (self .session , snapshot_uuid ))
567+ return snapshots
568+ except Exception as error :
569+ util .SMlog (f"Error listing snapshots for VDI { snapshot_uuid } : { error } " )
570+ return []
571+
558572 def configure_blocktracking (self , sr_uuid , vdi_uuid , enable ):
559573 """Function for configuring blocktracking"""
560574 import blktap2
@@ -598,31 +612,44 @@ def configure_blocktracking(self, sr_uuid, vdi_uuid, enable):
598612 self ._delete_cbt_log ()
599613 raise xs_errors .XenError ('CBTActivateFailed' ,
600614 opterr = str (error ))
615+
601616 else :
602- from lock import Lock
603- lock = Lock ("cbtlog" , str (vdi_uuid ))
604- lock .acquire ()
605- try :
606- # Find parent of leaf metadata file, if any,
607- # and nullify its successor
608- logpath = self ._get_cbt_logpath (self .uuid )
609- parent = self ._cbt_op (self .uuid ,
610- cbtutil .get_cbt_parent , logpath )
611- self ._delete_cbt_log ()
612- parent_path = self ._get_cbt_logpath (parent )
613- if self ._cbt_log_exists (parent_path ):
614- self ._cbt_op (parent , cbtutil .set_cbt_child ,
615- parent_path , uuid .UUID (int = 0 ))
616- if disk_state :
617- self .update_slaves_on_cbt_disable (logpath )
618- except Exception as error :
619- raise xs_errors .XenError ('CBTDeactivateFailed' , str (error ))
620- finally :
621- lock .release ()
622- lock .cleanup ("cbtlog" , str (vdi_uuid ))
617+ self ._disable_cbt (disk_state )
618+ # Disable cbt for each child snapshots
619+ for snapshot_vdi in self ._list_vdi_snapshots ():
620+ snapshot_vdi ._disable_cbt ()
621+
623622 finally :
624623 blktap2 .VDI .tap_unpause (self .session , sr_uuid , vdi_uuid )
625624
625+ def _disable_cbt (self , disk_state = None ):
626+ """Disables CBT for the specified VDI and updates associated metadata."""
627+ from lock import Lock
628+ lock = Lock ("cbtlog" , str (self .uuid ))
629+ lock .acquire ()
630+ try :
631+ vdi_ref = self .session .xenapi .VDI .get_by_uuid (self .uuid )
632+ vdi_record = self .session .xenapi .VDI .get_record (vdi_ref )
633+ logpath = self ._get_cbt_logpath (self .uuid )
634+ if self ._cbt_log_exists (logpath ):
635+ parent = self ._cbt_op (self .uuid , cbtutil .get_cbt_parent , logpath )
636+ self ._delete_cbt_log ()
637+ # Find parent of leaf metadata file, if any,
638+ # and nullify its successor
639+ parent_path = self ._get_cbt_logpath (parent )
640+ if self ._cbt_log_exists (parent_path ):
641+ self ._cbt_op (parent , cbtutil .set_cbt_child , parent_path , uuid .UUID (int = 0 ))
642+ if disk_state :
643+ self .update_slaves_on_cbt_disable (logpath )
644+ self .session .xenapi .VDI .set_cbt_enabled (vdi_ref , False )
645+ except Exception as error :
646+ util .SMlog (f"Error disabling CBT for VDI { self .uuid } : { error } " )
647+ raise xs_errors .XenError ('CBTDeactivateFailed' , str (error ))
648+ finally :
649+ lock .release ()
650+ lock .cleanup ("cbtlog" , str (self .uuid ))
651+
652+
626653 def data_destroy (self , sr_uuid , vdi_uuid ):
627654 """Delete the data associated with a CBT enabled snapshot
628655
0 commit comments