@@ -107,20 +107,23 @@ def from_dict(cls, data: Dict[str, str]) -> "RevertLogDestinationVDI":
107107
108108
109109class RevertLogSourceVDI :
110- def __init__ (self , uuid : str , parent_path : str ):
110+ def __init__ (self , uuid : str , path : str , parent_path : str ):
111111 self .uuid = uuid
112+ self .path = path
112113 self .parent_path = parent_path
113114
114115 def to_dict (self ) -> Dict [str , Collection [str ]]:
115116 return {
116117 "uuid" : self .uuid ,
118+ "path" : self .path ,
117119 "parent_path" : self .parent_path ,
118120 }
119121
120122 @classmethod
121123 def from_dict (cls , data : Dict [str , str ]) -> "RevertLogSourceVDI" :
122124 return cls (
123125 uuid = data ["uuid" ],
126+ path = data ["path" ],
124127 parent_path = data ["parent_path" ],
125128 )
126129
@@ -152,7 +155,7 @@ def __init__(
152155 self ,
153156 dest : RevertLogDestinationVDI ,
154157 src : RevertLogSourceVDI ,
155- inserted : Optional [ RevertLogInsertedVDI ] ,
158+ inserted : RevertLogInsertedVDI ,
156159 ):
157160 self .dest = dest
158161 self .src = src
@@ -163,7 +166,7 @@ def to_dict(self) -> Dict[str, Collection[str]]:
163166 return {
164167 "dest" : self .dest .to_dict (),
165168 "src" : self .src .to_dict (),
166- "inserted" : self .inserted .to_dict () if self . inserted else ""
169+ "inserted" : self .inserted .to_dict (),
167170 }
168171
169172 @override
@@ -173,8 +176,6 @@ def from_dict(cls, data: Dict[str, Union[Dict[str, str], str]]) -> "RevertLogEnt
173176 dest = RevertLogDestinationVDI .from_dict (data ["dest" ]), # type: ignore # Version checked
174177 src = RevertLogSourceVDI .from_dict (data ["src" ]), # type: ignore # Version checked
175178 inserted = RevertLogInsertedVDI .from_dict (data ["inserted" ]) #type: ignore # Version checked
176- if data ["inserted" ]
177- else None ,
178179 )
179180
180181
@@ -520,23 +521,25 @@ def _rollback_revert_vdi(self, entry: RevertLogEntry):
520521 dest ._db_update ()
521522 self .added_vdi (dest )
522523
524+ util .SMlog (f"Restoring src vdi { entry .src .uuid } " )
525+ if not util .ioretry (lambda : util .pathexists (entry .src .path )):
526+ util .SMlog (f"Restoring src vdi { entry .src .uuid } from { entry .inserted .uuid } " )
527+ dest ._rename (entry .inserted .path , entry .src .path )
528+
529+ util .SMlog (f"Restoring parent { entry .src .parent_path } to { entry .src .uuid } " )
530+ dest .cowutil .setParent (entry .src .path , entry .src .parent_path , False )
531+ dest .cowutil .setHidden (entry .src .path , False )
532+
523533 src : "FileVDI" = self .vdi (entry .src .uuid ) # type: ignore[assignment]
524534 src .sm_config = src .session .xenapi .VDI .get_sm_config (src .session .xenapi .VDI .get_by_uuid (src .uuid ))
525- src .cowutil .setParent (str (src .path ), entry .src .parent_path , False )
526535 src .load_from_file (str (src .path ))
527536 src ._db_update ()
528537
529- if not entry .inserted :
530- util .SMlog (f"No inserted vdi for { entry .dest .uuid } " )
531- return
538+ self .added_vdi (src )
532539
533- try :
534- inserted : "FileVDI" = self .vdi (entry .inserted .uuid ) # type: ignore[assignment]
535- except Exception :
536- self ._unlink_paths (entry .inserted .path )
537- return
538-
539- inserted .delete (inserted .sr .uuid , inserted .uuid )
540+ util .SMlog (f"Removing inserted VDI { entry .inserted .uuid } " )
541+ self ._unlink_paths (entry .inserted .path )
542+ self .deleted_vdi (entry .inserted .uuid )
540543
541544
542545 def _unlink_paths (self , * files : Union [Path , str ]):
@@ -974,111 +977,111 @@ def _do_revert(
974977 raise xs_errors .XenError ("Not implemented yet" )
975978
976979 with self .tap_pause (), dest .tap_pause ():
977- self ._revert (dest , self . parent == dest . parent , cbtlog , cbt_consistency_state )
980+ self ._revert (dest , cbtlog , cbt_consistency_state )
978981
979982 def _revert (
980983 self ,
981984 dest : "FileVDI" ,
982- has_same_parents : bool ,
983985 cbtlog : Optional [str ],
984986 cbt_consistency_state : bool ,
985987 ):
986988 """This assumes that self and dest VDIs has been paused"""
987- dest_tmp_uuid = util .gen_uuid () # Will be replaced by dest.uuid at the end
988- dest_tmp_path = os .path .join (dest .sr .path , f"{ dest_tmp_uuid } { VDI_TYPE_TO_EXTENSION [dest .vdi_type ]} .tmp" )
989989
990- dest_backup_path = os . path . join ( dest . sr . path , f" { util . gen_uuid () } { VDI_TYPE_TO_EXTENSION [ dest . vdi_type ] } .back" )
990+ self . _ensure_not_max_depth ( )
991991
992- src_parent = self .sr .vdi (self .parent )
993- src_parent .sm_config = src_parent .session .xenapi .VDI .get_sm_config (
994- src_parent .session .xenapi .VDI .get_by_uuid (src_parent .uuid )
992+ src_parent_path = os .path .join (
993+ self .sr .path , f"{ self .parent } { VDI_TYPE_TO_EXTENSION [self .vdi_type ]} "
995994 )
996995
997- base_copy_uuid = None
998- base_copy_path = None
999- if not has_same_parents :
1000- self . _ensure_not_max_depth ( )
996+ dest_tmp_uuid = util . gen_uuid () # Will be replaced by dest.uuid at the end
997+ dest_tmp_path = os . path . join (
998+ dest . sr . path , f" { dest_tmp_uuid } { VDI_TYPE_TO_EXTENSION [ dest . vdi_type ] } .tmp"
999+ )
10011000
1002- base_copy_uuid = util .gen_uuid ()
1003- base_copy_path = os .path .join (
1004- src_parent .sr .path ,
1005- "%s%s" % (base_copy_uuid , VDI_TYPE_TO_EXTENSION [src_parent .vdi_type ])
1006- )
1001+ dest_backup_path = os .path .join (
1002+ dest .sr .path ,
1003+ f"{ util .gen_uuid ()} { VDI_TYPE_TO_EXTENSION [dest .vdi_type ]} .back" ,
1004+ )
1005+
1006+ inserted_uuid = util .gen_uuid ()
1007+ inserted_path = os .path .join (
1008+ dest .sr .path , f"{ inserted_uuid } { VDI_TYPE_TO_EXTENSION [dest .vdi_type ]} "
1009+ )
10071010
10081011 log_entry = RevertLogEntry (
10091012 dest = RevertLogDestinationVDI (
10101013 dest .uuid , dest .path , dest_backup_path , dest_tmp_path
10111014 ),
1012- src = RevertLogSourceVDI (self .uuid , src_parent .path ),
1013- inserted = RevertLogInsertedVDI (base_copy_uuid , base_copy_path )
1014- if base_copy_uuid and base_copy_path
1015- else None ,
1015+ src = RevertLogSourceVDI (self .uuid , self .path , src_parent_path ),
1016+ inserted = RevertLogInsertedVDI (inserted_uuid , inserted_path ),
10161017 )
10171018 journal_id , journal_content = log_entry .to_journal ()
10181019 self .sr .journaler .create (log_entry .JRN_KEY , journal_id , journal_content )
10191020
1020- # Change destination content
10211021 ## First move the old vdi to a backup location to allow rolling back
10221022 ## This has to be done first because it's used as a signal to the rollback
10231023 ## algorithm to know if there is cleanup work to do
1024- util .ioretry (lambda : self ._rename (dest .path , dest_backup_path ),
1025- errlist = [errno .EIO , errno .EACCES ])
1024+ util .ioretry (
1025+ lambda : self ._rename (dest .path , dest_backup_path ),
1026+ errlist = [errno .EIO , errno .EACCES ],
1027+ )
10261028
1027- if not has_same_parents :
1028- # Create a base copy to attach both the src snapshot and the new destination
1029- # This is mandatory to prevent the GC from coalescing everything
1030- util .fistpoint .activate_custom_fn (
1031- "FileSR_revert_insert" ,
1032- self .__fist_enospace )
1033- util .ioretry (lambda : self ._snap (base_copy_path , src_parent .path , False ))
1029+ # Transform src into inserted
1030+ self ._rename (self .path , inserted_path )
1031+
1032+ # Create inserted base copy
1033+ util .ioretry (
1034+ lambda : self ._snap (
1035+ self .path ,
1036+ inserted_path ,
1037+ False ,
1038+ )
1039+ )
1040+ util .fistpoint .activate_custom_fn ("FileSR_revert_insert" , self .__fist_enospace )
1041+
1042+ inserted = FileVDI (self .sr , inserted_uuid )
1043+
1044+ inserted .label = "base copy"
1045+ inserted .read_only = True
1046+ inserted .location = inserted_uuid
1047+ inserted .sm_config = {}
1048+ inserted .sm_config ["image-format" ] = getImageStringFromVdiType (self .vdi_type )
1049+ if "key_hash" in self .sm_config :
1050+ inserted .sm_config ["key_hash" ] = self .sm_config ["key_hash" ]
1051+ inserted .cbt_enabled = bool (cbtlog )
10341052
1035- ## Protect the new parent from being coalesced by the GC
1036- self .cowutil .setHidden (str (base_copy_path ), False )
1053+ inserted ._db_introduce ()
10371054
1038- ## Attach src snapshot to it's new parent
1039- self .cowutil .setParent (str (self .path ), str (base_copy_path ), False )
1055+ # Update src
1056+ self .load_from_file (self .path )
1057+ self ._db_update ()
10401058
1041- ## Create snapshot
1042- actual_parent_path = base_copy_path if base_copy_path else src_parent .path
1059+ # Create tmp snapshot for dest
10431060 util .ioretry (
10441061 lambda : self ._snap (
10451062 dest_tmp_path ,
1046- actual_parent_path ,
1063+ inserted . path ,
10471064 False ,
10481065 )
10491066 )
10501067 util .fistpoint .activate_custom_fn (
1051- "FileSR_revert_create_snap" ,
1052- self . __fist_enospace )
1068+ "FileSR_revert_create_snap" , self . __fist_enospace
1069+ )
10531070 self .cowutil .setHidden (dest_tmp_path , False )
10541071 ## Force parent (it can be simplified by vhd tools)
1055- self .cowutil .setParent (dest_tmp_path , actual_parent_path , False )
1056-
1057- if not has_same_parents :
1058- # Introduce new parent to the db
1059- base_copy = FileVDI (self .sr , base_copy_uuid )
1060-
1061- base_copy .label = "base copy"
1062- base_copy .read_only = True
1063- base_copy .location = base_copy_uuid
1064- base_copy .sm_config = {}
1065- base_copy .sm_config ["image-format" ] = getImageStringFromVdiType (self .vdi_type )
1066- if "key_hash" in src_parent .sm_config :
1067- base_copy .sm_config ['key_hash' ] = src_parent .sm_config ['key_hash' ]
1068- base_copy .cbt_enabled = bool (cbtlog )
1069-
1070- base_copy ._db_introduce ()
1072+ self .cowutil .setParent (dest_tmp_path , inserted .path , False )
10711073
1072- ## The new parent can now be set hidden and don't need to be protected by the GC
1073- base_copy .cowutil .setHidden (base_copy .path , True )
1074- self ._db_update ()
1074+ ## The new parent can now be set hidden and don't need to be protected by the GC
1075+ inserted .cowutil .setHidden (inserted .path , True )
10751076
10761077 # Apply snapshot
1077- util .ioretry (lambda : self ._rename (dest_tmp_path , dest .path ),
1078- errlist = [errno .EIO , errno .EACCES ])
1078+ util .ioretry (
1079+ lambda : self ._rename (dest_tmp_path , dest .path ),
1080+ errlist = [errno .EIO , errno .EACCES ],
1081+ )
10791082 util .fistpoint .activate_custom_fn (
1080- "FileSR_revert_apply_snap" ,
1081- self . __fist_enospace )
1083+ "FileSR_revert_apply_snap" , self . __fist_enospace
1084+ )
10821085 dest .load_from_file (dest .path )
10831086 dest ._db_update ()
10841087
0 commit comments