Skip to content

Commit fc458c8

Browse files
committed
implement the capability to desactivate CBT on all vdi snapshot childs Implement recursive CBT deactivation for VDI snapshot chains
Add recursive CBT deactivation for VDI and all child snapshots Delete CBT log files when present Update parent/child references in CBT metadata Fixes: Incomplete CBT deactivation on snapshot chains
1 parent de309bc commit fc458c8

File tree

1 file changed

+54
-19
lines changed

1 file changed

+54
-19
lines changed

drivers/VDI.py

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,20 @@ 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 UUIDs 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 [
585+
self.session.xenapi.VDI.get_uuid(ref)
586+
for ref in record.get("snapshots", [])
587+
if self.session.xenapi.VDI.get_uuid(ref)
588+
]
589+
except Exception as error:
590+
util.SMlog("Error listing snapshots for VDI %s : %s" % (vdi_ref, error))
591+
return []
592+
579593
def configure_blocktracking(self, sr_uuid, vdi_uuid, enable):
580594
"""Function for configuring blocktracking"""
581595
import blktap2
@@ -616,29 +630,50 @@ def configure_blocktracking(self, sr_uuid, vdi_uuid, enable):
616630
self._delete_cbt_log()
617631
raise xs_errors.XenError('CBTActivateFailed',
618632
opterr=str(error))
633+
619634
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))
635+
self._disable_cbt(vdi_uuid)
636+
639637
finally:
640638
blktap2.VDI.tap_unpause(self.session, sr_uuid, vdi_uuid)
641639

640+
def _disable_cbt(self, vdi_uuid, visited=None):
641+
# Prevent infite loop
642+
if visited is None:
643+
visited = set()
644+
if vdi_uuid in visited:
645+
return
646+
visited.add(vdi_uuid)
647+
648+
from lock import Lock
649+
lock = Lock("cbtlog", str(vdi_uuid))
650+
lock.acquire()
651+
try:
652+
self.uuid = vdi_uuid
653+
vdi_ref = self.session.xenapi.VDI.get_by_uuid(self.uuid)
654+
vdi_record = self.session.xenapi.VDI.get_record(vdi_ref)
655+
logpath = self._get_cbt_logpath(self.uuid)
656+
if self._cbt_log_exists(logpath):
657+
parent = self._cbt_op(self.uuid, cbtutil.get_cbt_parent, logpath)
658+
self._delete_cbt_log()
659+
# Find parent of leaf metadata file, if any,
660+
# and nullify its successor
661+
parent_path = self._get_cbt_logpath(parent)
662+
if self._cbt_log_exists(parent_path):
663+
self._cbt_op(parent, cbtutil.set_cbt_child, parent_path, uuid.UUID(int=0))
664+
self.session.xenapi.VDI.set_cbt_enabled(vdi_ref, False)
665+
for snapshot_ref in self.list_vdi_snapshots(self.uuid):
666+
snap_ref = self.session.xenapi.VDI.get_by_uuid(snapshot_ref)
667+
snapshot_uuid = self.session.xenapi.VDI.get_uuid(snap_ref)
668+
self._disable_cbt(snapshot_uuid, visited)
669+
670+
except Exception as error:
671+
util.SMlog(f"Error disabling CBT for VDI {self.uuid}: {error}")
672+
raise xs_errors.XenError('CBTDeactivateFailed', str(error))
673+
finally:
674+
lock.release()
675+
lock.cleanup("cbtlog", str(vdi_uuid))
676+
642677
def data_destroy(self, sr_uuid, vdi_uuid):
643678
"""Delete the data associated with a CBT enabled snapshot
644679

0 commit comments

Comments
 (0)