@@ -576,6 +576,17 @@ def in_sync_with_xenapi_record(self, x):
576576 return False
577577 return True
578578
579+ def _list_vdi_snapshots (self , vdi_uuid ):
580+ """List vdi_ref of all direct snapshots of a VDI"""
581+ try :
582+ vdi_ref = self .session .xenapi .VDI .get_by_uuid (vdi_uuid )
583+ record = self .session .xenapi .VDI .get_record (vdi_ref )
584+ return record .get ("snapshots" , [])
585+
586+ except Exception as error :
587+ util .SMlog (f"Error listing snapshots for VDI { vdi_uuid } : { error } " )
588+ return []
589+
579590 def configure_blocktracking (self , sr_uuid , vdi_uuid , enable ):
580591 """Function for configuring blocktracking"""
581592 import blktap2
@@ -616,29 +627,43 @@ def configure_blocktracking(self, sr_uuid, vdi_uuid, enable):
616627 self ._delete_cbt_log ()
617628 raise xs_errors .XenError ('CBTActivateFailed' ,
618629 opterr = str (error ))
630+
619631 else :
620- from lock import Lock
621- lock = Lock ("cbtlog" , str (vdi_uuid ))
622- lock .acquire ()
623- try :
624- # Find parent of leaf metadata file, if any,
625- # and nullify its successor
626- logpath = self ._get_cbt_logpath (self .uuid )
627- parent = self ._cbt_op (self .uuid ,
628- cbtutil .get_cbt_parent , logpath )
629- self ._delete_cbt_log ()
630- parent_path = self ._get_cbt_logpath (parent )
631- if self ._cbt_log_exists (parent_path ):
632- self ._cbt_op (parent , cbtutil .set_cbt_child ,
633- parent_path , uuid .UUID (int = 0 ))
634- except Exception as error :
635- raise xs_errors .XenError ('CBTDeactivateFailed' , str (error ))
636- finally :
637- lock .release ()
638- lock .cleanup ("cbtlog" , str (vdi_uuid ))
632+ self ._disable_cbt (vdi_uuid )
633+
639634 finally :
640635 blktap2 .VDI .tap_unpause (self .session , sr_uuid , vdi_uuid )
641636
637+ def _disable_cbt (self , vdi_uuid ):
638+ """Disables CBT for the specified VDI and updates associated metadata."""
639+ from lock import Lock
640+ lock = Lock ("cbtlog" , str (vdi_uuid ))
641+ lock .acquire ()
642+ try :
643+ self .uuid = vdi_uuid
644+ vdi_ref = self .session .xenapi .VDI .get_by_uuid (self .uuid )
645+ vdi_record = self .session .xenapi .VDI .get_record (vdi_ref )
646+ logpath = self ._get_cbt_logpath (self .uuid )
647+ if self ._cbt_log_exists (logpath ):
648+ parent = self ._cbt_op (self .uuid , cbtutil .get_cbt_parent , logpath )
649+ self ._delete_cbt_log ()
650+ # Find parent of leaf metadata file, if any,
651+ # and nullify its successor
652+ parent_path = self ._get_cbt_logpath (parent )
653+ if self ._cbt_log_exists (parent_path ):
654+ self ._cbt_op (parent , cbtutil .set_cbt_child , parent_path , uuid .UUID (int = 0 ))
655+ self .session .xenapi .VDI .set_cbt_enabled (vdi_ref , False )
656+ for snapshot_ref in self ._list_vdi_snapshots (self .uuid ):
657+ snapshot_uuid = self .session .xenapi .VDI .get_uuid (snapshot_ref )
658+ self ._disable_cbt (snapshot_uuid )
659+
660+ except Exception as error :
661+ util .SMlog (f"Error disabling CBT for VDI { self .uuid } : { error } " )
662+ raise xs_errors .XenError ('CBTDeactivateFailed' , str (error ))
663+ finally :
664+ lock .release ()
665+ lock .cleanup ("cbtlog" , str (vdi_uuid ))
666+
642667 def data_destroy (self , sr_uuid , vdi_uuid ):
643668 """Delete the data associated with a CBT enabled snapshot
644669
0 commit comments