Skip to content

Commit fbb3d88

Browse files
committed
WIP: Refactoring
Signed-off-by: Antoine Bartuccio <antoine.bartuccio@vates.tech>
1 parent e892b0b commit fbb3d88

File tree

2 files changed

+100
-109
lines changed

2 files changed

+100
-109
lines changed

drivers/FileSR.py

Lines changed: 81 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,18 @@ def _update(self, sr_uuid, virt_alloc_delta):
257257
self.physical_utilisation = self._getutilisation()
258258
self._db_update()
259259

260+
def get_children_of(self, uuid: str) -> List[str]:
261+
if not self.vdis:
262+
self._loadvdis()
263+
264+
children = []
265+
266+
for vdi in self.vdis.values():
267+
if vdi.parent == uuid:
268+
children.append(vdi.uuid)
269+
270+
return children
271+
260272
@override
261273
def content_type(self, sr_uuid) -> str:
262274
return super(FileSR, self).content_type(sr_uuid)
@@ -755,54 +767,32 @@ def _tap_pause(self, secondary=None):
755767
finally:
756768
blktap2.VDI.tap_unpause(self.session, self.sr.uuid, self.uuid, secondary)
757769

758-
759770
@override
760-
def revert(self, sr_uuid, src_uuid, dest_uuid):
761-
util.SMlog("---------------------------------------------------------------->")
762-
util.SMlog(f"in: {src_uuid} - {self.uuid}")
763-
764-
if self.label == "base copy":
765-
raise xs_errors.XenError(f"{self.uuid} is a base copy.")
766-
767-
dest = VDI.VDI.from_uuid(self.sr.session, dest_uuid)
768-
util.SMlog(f"out: {dest_uuid} - {dest.uuid}")
769-
770-
if self.vdi_type != dest.vdi_type:
771-
raise xs_errors.XenError(f"{self.uuid} and {dest.uuid} has incompatible types {self.vdi_type} != {dest.vdi_type}")
772-
773-
771+
def _do_revert(self, dest: "FileVDI", cbtlog: Optional[str] = None):
772+
# Sanity checks
774773
if not self._checkpath(self.path):
775774
raise xs_errors.XenError(f"Could not find {self.path}")
776775

777776
if not dest._checkpath(dest.path):
778777
raise xs_errors.XenError(f"Could not find {dest.path}")
779778

780-
def get_child_of(sr: FileSR, uuid: str, exclude: Optional[List[str]] = None) -> Optional[str]:
781-
if not exclude:
782-
exclude = []
783-
784-
excluded = set(exclude)
785-
sr._loadvdis()
786-
787-
children = []
788-
789-
for vdi in sr.vdis.values():
790-
if vdi.uuid == uuid:
791-
continue
792-
if vdi.parent == uuid and vdi.uuid not in excluded:
793-
children.append(vdi.uuid)
794-
795-
if len(children) != 1:
796-
return None
797-
798-
return children[0]
779+
self._ensure_not_max_depth()
799780

800-
common_parent_uuid = self.parent if self.parent == dest.parent else get_child_of(self.sr, self.parent, [self.uuid])
801-
if not common_parent_uuid:
802-
raise xs_errors.XenError(f"{self.uuid} and {dest.uuid} aren't on the same snapshot tree")
781+
# Get first common parent
782+
if self.parent == dest.parent:
783+
downward_child = None
784+
else:
785+
children = [child for child in self.sr.get_children_of(self.parent) if child != self.uuid]
786+
if not children:
787+
downward_child = None
788+
else:
789+
downward_child = VDI.VDI.from_uuid(self.sr.session, children[0])
803790

804-
self._ensure_not_max_depth()
791+
with self._tap_pause(), dest._tap_pause():
792+
self._revert(dest, downward_child, cbtlog)
805793

794+
def _revert(self, dest: "FileVDI", downward_child: Optional["FileVDI"], cbtlog: Optional[str]):
795+
"""This assumes that self and dest VDIs has been paused"""
806796
dest_tmp_uuid = util.gen_uuid() # Will be replaced by dest.uuid at the end
807797
dest_tmp_path = os.path.join(dest.sr.path, "%s%s" % (dest_tmp_uuid, VDI_TYPE_TO_EXTENSION[dest.vdi_type]))
808798

@@ -817,90 +807,74 @@ def update_vdi_from_file(vdi: FileVDI, path: str):
817807
if vdi.parent:
818808
vdi.sm_config['vhd-parent'] = vdi.parent
819809

820-
with self._tap_pause(), dest._tap_pause():
821-
# try:
822-
util.fistpoint.activate_custom_fn(
823-
"FileSR_fail_snap1",
824-
self.__fist_enospace)
825-
util.ioretry(lambda: self._snap(dest_tmp_path, src_parent.path, False))
826-
self.cowutil.setHidden(dest_tmp_path, False)
827-
828-
if common_parent_uuid != dest.parent:
829-
# Create a new parent VDI based on src parent
830-
src_parent_clone_uuid = util.gen_uuid()
831-
src_parent_clone_path = os.path.join(
832-
dest.sr.path,
833-
"%s%s" % (src_parent_clone_uuid, VDI_TYPE_TO_EXTENSION[dest.vdi_type])
834-
)
810+
# try:
811+
util.fistpoint.activate_custom_fn(
812+
"FileSR_fail_snap1",
813+
self.__fist_enospace)
814+
util.ioretry(lambda: self._snap(dest_tmp_path, src_parent.path, False))
815+
self.cowutil.setHidden(dest_tmp_path, False)
816+
817+
if downward_child:
818+
# Create a new parent VDI based on src parent and attach the rest of the snapshoot tree to it
819+
src_parent_clone_uuid = util.gen_uuid()
820+
src_parent_clone_path = os.path.join(
821+
dest.sr.path,
822+
"%s%s" % (src_parent_clone_uuid, VDI_TYPE_TO_EXTENSION[dest.vdi_type])
823+
)
835824

836-
common_parent = VDI.VDI.from_uuid(self.sr.session, common_parent_uuid)
837-
common_parent.sm_config = common_parent.session.xenapi.VDI.get_sm_config(common_parent.sr.srcmd.params['vdi_ref'])
825+
downward_child.sm_config = downward_child.session.xenapi.VDI.get_sm_config(downward_child.sr.srcmd.params['vdi_ref'])
838826

839-
util.fistpoint.activate_custom_fn(
840-
"FileSR_fail_snap2",
841-
self.__fist_enospace)
842-
util.ioretry(lambda: self._snap(src_parent_clone_path, src_parent.path, False))
843-
self.cowutil.setHidden(src_parent_clone_path, False)
844-
845-
is_raw = self.VDI_TYPE == VdiType.RAW
846-
self.cowutil.setParent(src_parent_clone_path, src_parent.path, is_raw)
847-
self.cowutil.setParent(common_parent.path, src_parent_clone_path, is_raw)
848-
self.cowutil.setParent(self.path, src_parent_clone_path, is_raw)
849-
850-
# Introduce new readonly vdi to db
851-
src_parent_clone = VDI.VDI(self.sr, src_parent_clone_uuid)
852-
853-
# FileVDI emulation for update_vdi_from_file
854-
src_parent_clone.path = src_parent_clone_path
855-
src_parent_clone.parent = src_parent.uuid
856-
src_parent_clone.cowutil = self.cowutil
857-
858-
src_parent_clone.label = "base copy"
859-
src_parent_clone.read_only = True
860-
src_parent_clone.location = src_parent_clone_uuid
861-
src_parent_clone.sm_config = {}
862-
# TODO: fix the raw snapshot case
863-
src_parent_clone.sm_config["image-format"] = getImageStringFromVdiType(self.vdi_type)
864-
if "key_hash" in common_parent.sm_config:
865-
src_parent_clone.sm_config['key_hash'] = common_parent.sm_config['key_hash']
866-
update_vdi_from_file(src_parent_clone, src_parent_clone_uuid)
867-
868-
self.sm_config = self.session.xenapi.VDI.get_sm_config(self.sr.srcmd.params['vdi_ref'])
869-
update_vdi_from_file(self, self.path)
827+
util.fistpoint.activate_custom_fn(
828+
"FileSR_fail_snap2",
829+
self.__fist_enospace)
830+
util.ioretry(lambda: self._snap(src_parent_clone_path, src_parent.path, False))
831+
self.cowutil.setHidden(src_parent_clone_path, False)
870832

871-
update_vdi_from_file(common_parent, common_parent.path)
833+
is_raw = self.VDI_TYPE == VdiType.RAW
834+
self.cowutil.setParent(src_parent_clone_path, src_parent.path, is_raw)
835+
self.cowutil.setParent(downward_child.path, src_parent_clone_path, is_raw)
836+
self.cowutil.setParent(self.path, src_parent_clone_path, is_raw)
872837

873-
src_parent_clone._db_introduce()
838+
# Introduce new readonly vdi to db
839+
src_parent_clone = VDI.VDI(self.sr, src_parent_clone_uuid)
874840

875-
common_parent._db_update()
841+
# FileVDI emulation for update_vdi_from_file
842+
src_parent_clone.path = src_parent_clone_path
843+
src_parent_clone.parent = src_parent.uuid
844+
src_parent_clone.cowutil = self.cowutil
876845

877-
self._db_update()
846+
src_parent_clone.label = "base copy"
847+
src_parent_clone.read_only = True
848+
src_parent_clone.location = src_parent_clone_uuid
849+
src_parent_clone.sm_config = {}
850+
# TODO: fix the raw snapshot case
851+
src_parent_clone.sm_config["image-format"] = getImageStringFromVdiType(self.vdi_type)
852+
if "key_hash" in downward_child.sm_config:
853+
src_parent_clone.sm_config['key_hash'] = downward_child.sm_config['key_hash']
854+
update_vdi_from_file(src_parent_clone, src_parent_clone_uuid)
878855

879-
self.cowutil.setHidden(src_parent_clone_path, True)
856+
self.sm_config = self.session.xenapi.VDI.get_sm_config(self.sr.srcmd.params['vdi_ref'])
857+
update_vdi_from_file(self, self.path)
880858

881-
util.ioretry(lambda: self._rename(dest_tmp_path, dest.path),
882-
errlist=[errno.EIO, errno.EACCES])
859+
update_vdi_from_file(downward_child, downward_child.path)
883860

884-
dest.sm_config = dest.session.xenapi.VDI.get_sm_config(dest.sr.srcmd.params['vdi_ref'])
885-
update_vdi_from_file(dest, dest.path)
861+
src_parent_clone._db_introduce()
886862

887-
dest._db_update()
863+
downward_child._db_update()
888864

889-
return
865+
self._db_update()
890866

867+
self.cowutil.setHidden(src_parent_clone_path, True)
891868

892-
# except util.CommandException as inst:
893-
# # TODO: cleanup
894-
# # XXX: it might be too late if the base disk has been marked as deleted!
895-
# # self._clonecleanup(src, dst, newsrc)
896-
# # util.end_log_entry(self.sr.path, self.path, ["error"])
897-
# # raise xs_errors.XenError('VDIClone',
898-
# # opterr='VDI clone failed error %d' % inst.code)
899-
# pass
869+
util.ioretry(lambda: self._rename(dest_tmp_path, dest.path),
870+
errlist=[errno.EIO, errno.EACCES])
900871

901-
util.SMlog("<---------------------------------------------------------------")
902-
raise xs_errors.XenError('Heloiastrnie')
872+
dest.sm_config = dest.session.xenapi.VDI.get_sm_config(dest.sr.srcmd.params['vdi_ref'])
873+
update_vdi_from_file(dest, dest.path)
903874

875+
dest._db_update()
876+
# except:
877+
#cleanup
904878

905879
@override
906880
def compose(self, sr_uuid, vdi1, vdi2) -> None:

drivers/VDI.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ def _do_snapshot(self, sr_uuid, vdi_uuid, snapType,
217217
cloneOp=False, secondary=None, cbtlog=None, is_mirror_destination=False) -> str:
218218
raise xs_errors.XenError('Unimplemented')
219219

220+
def _do_revert(self, dest, cbtlog: Optional[str] = None) -> None:
221+
raise xs_errors.XenError('Unimplemented')
222+
220223
def _delete_cbt_log(self) -> None:
221224
raise xs_errors.XenError('Unimplemented')
222225

@@ -249,14 +252,28 @@ def resize(self, sr_uuid, vdi_uuid, size) -> str:
249252
"""
250253
raise xs_errors.XenError('Unimplemented')
251254

252-
def revert(self, sr_uuid, vdi_uuid, target_uuid):
255+
def revert(self, sr_uuid: str, vdi_uuid: str, target_uuid: str) -> None:
253256
"""Replaces the contents of the target_uuid VDI with the contents of the vdi_uuid
254257
without changing the identitity of the target (i.e. name-label, uuid and location
255258
are guaranteed to remain the same)..
256259
257260
This operation IS idempotent and the vdi pointed by vdi_uuid is preserved.
258261
"""
259-
raise xs_errors.XenError('Unimplemented')
262+
if self.label == "base copy":
263+
raise xs_errors.XenError(f"{self.uuid} is a base copy.")
264+
265+
dest = self.__class__.from_uuid(self.sr.session, target_uuid)
266+
267+
if self.vdi_type != dest.vdi_type:
268+
raise xs_errors.XenError(f"{self.uuid} and {dest.uuid} has incompatible types {self.vdi_type} != {dest.vdi_type}")
269+
270+
if self._get_blocktracking_status():
271+
cbtlog = self._get_cbt_logpath(self.uuid)
272+
else:
273+
cbtlog = None
274+
275+
self._do_revert(dest, cbtlog=cbtlog)
276+
260277

261278
def resize_cbt(self, sr_uuid, vdi_uuid, size):
262279
"""Resize the given VDI to size <size> MB. Size can

0 commit comments

Comments
 (0)