Skip to content

Commit ecedce7

Browse files
committed
WIP: one directional vdi revert
Signed-off-by: Antoine Bartuccio <antoine.bartuccio@vates.tech>
1 parent c0a7ff3 commit ecedce7

File tree

1 file changed

+89
-22
lines changed

1 file changed

+89
-22
lines changed

drivers/FileSR.py

Lines changed: 89 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# FileSR: local-file storage repository
1919
from contextlib import contextmanager
2020

21-
from sm_typing import Dict, Optional, List, override, Tuple, Union
21+
from sm_typing import Dict, Optional, List, override, Tuple
2222

2323
import SR
2424
import VDI
@@ -777,44 +777,111 @@ def revert(self, sr_uuid, src_uuid, dest_uuid):
777777
if not dest._checkpath(dest.path):
778778
raise xs_errors.XenError(f"Could not find {dest.path}")
779779

780-
if self.parent != dest.parent:
781-
raise xs_errors.XenError("Not implemented yet")
780+
def get_child_of(start: FileVDI, parent_uuid: str) -> Optional[str]:
781+
util.SMlog(f"Looking for common parent: {parent_uuid}")
782+
current = start.uuid
783+
while current is not None:
784+
path, _ = start._get_path_and_type(current)
785+
util.SMlog(f"Testing path {path}")
786+
if not path:
787+
return None
788+
789+
parent = start.cowutil.getParent(path, FileVDI.extractUuid)
790+
util.SMlog(f"Testing {parent} == {parent_uuid}")
791+
if parent == parent_uuid:
792+
util.SMlog(f"Found {current} with next parent {parent}")
793+
return current
794+
current = parent
795+
796+
return None
797+
798+
common_parent_uuid = get_child_of(dest, self.parent)
799+
if not common_parent_uuid:
800+
raise xs_errors.XenError(f"{self.uuid} and {dest.uuid} aren't on the same snapshot tree")
782801

783802
self._ensure_not_max_depth()
784803

785804
dest_tmp_uuid = util.gen_uuid() # Will be replaced by dest.uuid at the end
786805
dest_tmp_path = os.path.join(dest.sr.path, "%s%s" % (dest_tmp_uuid, VDI_TYPE_TO_EXTENSION[dest.vdi_type]))
787806

788-
# snapshot = self._do_snapshot(sr_uuid, src_uuid, VDI.SNAPSHOT_SINGLE)
789-
# util.SMlog(snapshot)
790-
src_parent_path, _ = self._get_path_and_type(self.parent)
791-
if not src_parent_path:
792-
raise xs_errors.XenError(f"Could not find parent of {self.uuid}")
807+
src_parent = VDI.VDI.from_uuid(self.sr.session, self.parent)
793808

809+
def update_vdi_from_file(vdi: FileVDI, path: str):
810+
image_info = vdi.cowutil.getInfo(vdi.path, FileVDI.extractUuid)
811+
vdi.utilisation = image_info.sizePhys
812+
vdi.size = image_info.sizeVirt
813+
vdi.parent = image_info.parentUuid
814+
vdi.hidden = image_info.hidden
815+
if vdi.parent:
816+
vdi.sm_config['vhd-parent'] = vdi.parent
794817

795818
with self._tap_pause(), dest._tap_pause():
796819
# try:
797820
util.fistpoint.activate_custom_fn(
798821
"FileSR_fail_snap1",
799822
self.__fist_enospace)
800-
util.ioretry(lambda: self._snap(dest_tmp_path, src_parent_path, False))
801-
self.cowutil.setHidden(dest_tmp_path, True)
823+
util.ioretry(lambda: self._snap(dest_tmp_path, src_parent.path, False))
824+
self.cowutil.setHidden(dest_tmp_path, False)
825+
826+
if common_parent_uuid != dest.parent:
827+
# Create a new parent VDI based on src parent
828+
src_parent_clone_uuid = util.gen_uuid()
829+
src_parent_clone_path = os.path.join(
830+
dest.sr.path,
831+
"%s%s" % (src_parent_clone_uuid, VDI_TYPE_TO_EXTENSION[dest.vdi_type])
832+
)
802833

803-
if self.parent != dest.parent:
804-
pass # Do more operation
834+
common_parent = VDI.VDI.from_uuid(self.sr.session, common_parent_uuid)
835+
common_parent.sm_config = common_parent.session.xenapi.VDI.get_sm_config(common_parent.sr.srcmd.params['vdi_ref'])
805836

806-
image_info = VdiType.isCowImage(self.vdi_type)
807-
util.SMlog(f"J'ai écrittttttttttttt iciciiiiiii {dest_tmp_path}")
808-
self._rename(dest_tmp_path, dest.path)
809-
util.SMlog(f"J'ai renoméééééé iciciiiiiii {dest.path}")
837+
util.fistpoint.activate_custom_fn(
838+
"FileSR_fail_snap2",
839+
self.__fist_enospace)
840+
util.ioretry(lambda: self._snap(src_parent_clone_path, src_parent.path, False))
841+
self.cowutil.setHidden(src_parent_clone_path, False)
842+
843+
is_raw = self.VDI_TYPE == VdiType.RAW
844+
self.cowutil.setParent(src_parent_clone_path, src_parent.path, is_raw)
845+
self.cowutil.setParent(common_parent.path, src_parent_clone_path, is_raw)
846+
self.cowutil.setParent(self.path, src_parent_clone_path, is_raw)
847+
848+
# Introduce new readonly vdi to db
849+
src_parent_clone = VDI.VDI(self.sr, src_parent_clone_uuid)
850+
851+
# FileVDI emulation for update_vdi_from_file
852+
src_parent_clone.path = src_parent_clone_path
853+
src_parent_clone.parent = src_parent.uuid
854+
src_parent_clone.cowutil = self.cowutil
855+
856+
src_parent_clone.label = "base copy"
857+
src_parent_clone.read_only = True
858+
src_parent_clone.location = src_parent_clone_uuid
859+
src_parent_clone.sm_config = {}
860+
# TODO: fix the raw snapshot case
861+
src_parent_clone.sm_config["image-format"] = getImageStringFromVdiType(self.vdi_type)
862+
if "key_hash" in common_parent.sm_config:
863+
src_parent_clone.sm_config['key_hash'] = common_parent.sm_config['key_hash']
864+
update_vdi_from_file(src_parent_clone, src_parent_clone_uuid)
865+
866+
self.sm_config = self.session.xenapi.VDI.get_sm_config(self.sr.srcmd.params['vdi_ref'])
867+
update_vdi_from_file(self, self.path)
868+
869+
update_vdi_from_file(common_parent, common_parent.path)
870+
871+
src_parent_clone._db_introduce()
872+
873+
common_parent._db_update()
874+
875+
self._db_update()
876+
877+
self.cowutil.setHidden(src_parent_clone_path, True)
878+
879+
util.ioretry(lambda: self._rename(dest_tmp_path, dest.path),
880+
errlist=[errno.EIO, errno.EACCES])
810881

811-
image_info = dest.cowutil.getInfo(dest.path, FileVDI.extractUuid)
812-
dest.utilisation = image_info.sizePhys
813-
dest.size = image_info.sizeVirt
814-
dest.hidden = False
815-
dest.parent = image_info.parentUuid
882+
dest.sm_config = dest.session.xenapi.VDI.get_sm_config(dest.sr.srcmd.params['vdi_ref'])
883+
update_vdi_from_file(dest, dest.path)
816884

817-
dest.cowutil.setHidden(dest.path, False)
818885
dest._db_update()
819886

820887
return dest.get_params()

0 commit comments

Comments
 (0)