3939from journaler import Journaler
4040from refcounter import RefCounter
4141from ipc import IPCFlag
42+ from cowutil import getCowUtil
4243from lvmcowutil import LV_PREFIX , NS_PREFIX_LVM , VG_LOCATION , VG_PREFIX
4344from lvmanager import LVActivator
4445from vditype import VdiType
7778 'configuration' : CONFIGURATION
7879 }
7980
80- PARAM_VHD = "vhd"
81- PARAM_RAW = "raw"
81+ CREATE_PARAM_TYPES = {
82+ "raw" : VdiType .RAW ,
83+ "vhd" : VdiType .VHD ,
84+ "qcow2" : VdiType .QCOW2
85+ }
8286
8387OPS_EXCLUSIVE = [
8488 "sr_create" , "sr_delete" , "sr_attach" , "sr_detach" , "sr_scan" ,
@@ -729,8 +733,7 @@ def scan(self, uuid) -> None:
729733 parent = cowutil .getParentNoCheck (lvPath )
730734
731735 if parent is not None :
732- sm_config ['vhd-parent' ] = parent [len ( \
733- LV_PREFIX [VdiType .VHD ]):]
736+ sm_config ['vhd-parent' ] = parent [len (LV_PREFIX [VdiType .VHD ]):]
734737 size = cowutil .getSizeVirt (lvPath )
735738 if self .provision == "thin" :
736739 utilisation = util .roundup (
@@ -1123,7 +1126,7 @@ def _completeCloneOp(self, vdis, origUuid, baseUuid, clonUuid):
11231126 base_vdi .utilisation = base .sizeLV
11241127 base_vdi .managed = False
11251128 base_vdi .sm_config = {
1126- "vdi_type" : VdiType . VHD ,
1129+ "vdi_type" : base . vdiType ,
11271130 "vhd-parent" : baseUuid }
11281131
11291132 if not self .legacyMode :
@@ -1154,14 +1157,14 @@ def _completeCloneOp(self, vdis, origUuid, baseUuid, clonUuid):
11541157 util .SMlog ("*** INTERRUPTED CLONE OP: complete" )
11551158
11561159 def _undoAllJournals (self ):
1157- """Undo all VHD & SM interrupted journaled operations. This call must
1160+ """Undo all COW image & SM interrupted journaled operations. This call must
11581161 be serialized with respect to all operations that create journals"""
1159- # undoing interrupted inflates must be done first, since undoing VHD
1162+ # undoing interrupted inflates must be done first, since undoing COW images
11601163 # ops might require inflations
11611164 self .lock .acquire ()
11621165 try :
11631166 self ._undoAllInflateJournals ()
1164- self ._undoAllVHDJournals ()
1167+ self ._undoAllCowJournals ()
11651168 self ._handleInterruptedCloneOps ()
11661169 self ._handleInterruptedCoalesceLeaf ()
11671170 finally :
@@ -1195,33 +1198,37 @@ def _undoAllInflateJournals(self):
11951198 delattr (self , "vdiInfo" )
11961199 delattr (self , "allVDIs" )
11971200
1198- def _undoAllVHDJournals (self ):
1199- """check if there are VHD journals in existence and revert them"""
1200- journals = lvhdutil .getAllVHDJournals (self .lvmCache )
1201+ def _undoAllCowJournals (self ):
1202+ """
1203+ Check if there are COW journals in existence and revert them.
1204+ """
1205+ journals = LvmCowUtil .getAllResizeJournals (self .lvmCache )
12011206 if len (journals ) == 0 :
12021207 return
12031208 self ._loadvdis ()
1204- # TODO
1205- cowutil = None
1209+
12061210 for uuid , jlvName in journals :
12071211 vdi = self .vdis [uuid ]
1208- util .SMlog ("Found VHD journal %s, reverting %s" % (uuid , vdi .path ))
1212+ util .SMlog ("Found COW journal %s, reverting %s" % (uuid , vdi .path ))
1213+ cowutil = getCowUtil (vdi .vdi_type )
1214+ lvmcowutil = LvmCowUtil (cowutil )
1215+
12091216 self .lvActivator .activate (uuid , vdi .lvname , False )
12101217 self .lvmCache .activateNoRefcount (jlvName )
12111218 fullSize = lvmcowutil .calcVolumeSize (vdi .size )
1212- lvmcowutil .inflate (self .journaler , self .uuid , vdi .uuid , fullSize )
1219+ lvmcowutil .inflate (self .journaler , self .uuid , vdi .uuid , vdi . vdi_type , fullSize )
12131220 try :
12141221 jFile = os .path .join (self .path , jlvName )
12151222 cowutil .revert (vdi .path , jFile )
12161223 except util .CommandException :
1217- util .logException ("VHD journal revert" )
1224+ util .logException ("COW journal revert" )
12181225 cowutil .check (vdi .path )
1219- util .SMlog ("VHD revert failed but VHD ok: removing journal" )
1226+ util .SMlog ("COW image revert failed but COW image ok: removing journal" )
12201227 # Attempt to reclaim unused space
12211228
12221229
1223- vhdInfo = cowutil .getInfo (vdi .path , LvmCowUtil .extractUuid , False )
1224- NewSize = lvmcowutil .calcVolumeSize (vhdInfo .sizeVirt )
1230+ imageInfo = cowutil .getInfo (vdi .path , LvmCowUtil .extractUuid , False )
1231+ NewSize = lvmcowutil .calcVolumeSize (imageInfo .sizeVirt )
12251232 if NewSize < fullSize :
12261233 lvmcowutil .deflate (self .lvmCache , vdi .lvname , int (NewSize ))
12271234 LvmCowUtil .refreshVolumeOnAllSlaves (self .session , self .uuid , self .vgname , vdi .lvname , uuid )
@@ -1360,15 +1367,14 @@ def load(self, vdi_uuid) -> None:
13601367 if "vdi_sm_config" in self .sr .srcmd .params and \
13611368 "type" in self .sr .srcmd .params ["vdi_sm_config" ]:
13621369 type = self .sr .srcmd .params ["vdi_sm_config" ]["type" ]
1363- if type == PARAM_RAW :
1364- self .vdi_type = VdiType .RAW
1365- elif type == PARAM_VHD :
1366- self .vdi_type = VdiType .VHD
1367- if self .sr .cmd == 'vdi_create' and self .sr .legacyMode :
1368- raise xs_errors .XenError ('VDICreate' , \
1369- opterr = 'Cannot create VHD type disk in legacy mode' )
1370- else :
1370+
1371+ try :
1372+ self .vdi_type = CREATE_PARAM_TYPES [type ]
1373+ except :
13711374 raise xs_errors .XenError ('VDICreate' , opterr = 'bad type' )
1375+ if self .sr .legacyMode and self .sr .cmd == 'vdi_create' and VdiType .isCowImage (self .vdi_type ):
1376+ raise xs_errors .XenError ('VDICreate' , opterr = 'Cannot create COW type disk in legacy mode' )
1377+
13721378 self .lvname = "%s%s" % (LV_PREFIX [self .vdi_type ], vdi_uuid )
13731379 self .path = os .path .join (self .sr .path , self .lvname )
13741380
@@ -1772,8 +1778,7 @@ def _snapshot(self, snapType, cloneOp=False, cbtlog=None, cbt_consistency=None):
17721778 size_req = lvSizeOrig + lvSizeClon + 2 * self .sr .journaler .LV_SIZE
17731779 lvSizeBase = self .size
17741780 if VdiType .isCowImage (self .vdi_type ):
1775- lvSizeBase = util .roundup (lvutil .LVM_SIZE_INCREMENT ,
1776- vhdutil .getSizePhys (self .path ))
1781+ lvSizeBase = util .roundup (lvutil .LVM_SIZE_INCREMENT , self .cowutil .getSizePhys (self .path ))
17771782 size_req -= (self .utilisation - lvSizeBase )
17781783 self .sr ._ensureSpaceAvailable (size_req )
17791784
@@ -1865,16 +1870,16 @@ def _snapshot(self, snapType, cloneOp=False, cbtlog=None, cbt_consistency=None):
18651870
18661871 def _createSnap (self , snapUuid , snapSizeLV , isNew ):
18671872 """Snapshot self and return the snapshot VDI object"""
1868- snapLV = LV_PREFIX [VdiType . VHD ] + snapUuid
1873+ snapLV = LV_PREFIX [self . vdi_type ] + snapUuid
18691874 snapPath = os .path .join (self .sr .path , snapLV )
18701875 self .sr .lvmCache .create (snapLV , int (snapSizeLV ))
18711876 util .fistpoint .activate ("LVHDRT_clone_vdi_after_lvcreate" , self .sr .uuid )
18721877 if isNew :
18731878 RefCounter .set (snapUuid , 1 , 0 , NS_PREFIX_LVM + self .sr .uuid )
18741879 self .sr .lvActivator .add (snapUuid , snapLV , False )
18751880 parentRaw = (self .vdi_type == VdiType .RAW )
1876- self ._cowutil .snapshot (snapPath , self .path , parentRaw , cowutil .getPreallocationSizeVirt ())
1877- snapParent = self ._cowutil .getParent (snapPath , LvmCowUtil .extractUuid )
1881+ self .cowutil .snapshot (snapPath , self .path , parentRaw , cowutil .getPreallocationSizeVirt ())
1882+ snapParent = self .cowutil .getParent (snapPath , LvmCowUtil .extractUuid )
18781883
18791884 snapVDI = LVMVDI (self .sr , snapUuid )
18801885 snapVDI .read_only = False
@@ -1887,7 +1892,7 @@ def _createSnap(self, snapUuid, snapSizeLV, isNew):
18871892 "type" , "vdi_type" , "vhd-parent" , "paused" , "relinking" , "activating" ] and \
18881893 not key .startswith ("host_" ):
18891894 snapVDI .sm_config [key ] = val
1890- snapVDI .sm_config ["vdi_type" ] = VdiType . VHD
1895+ snapVDI .sm_config ["vdi_type" ] = snapType
18911896 snapVDI .sm_config ["vhd-parent" ] = snapParent
18921897 snapVDI .lvname = snapLV
18931898 return snapVDI
@@ -1919,7 +1924,7 @@ def _finishSnapshot(self, snapVDI, snapVDI2, hostRefs, cloneOp=False, snapType=N
19191924 # for leaf nodes). The normal refcount of the child is not
19201925 # transferred to to the base VDI because normal refcounts are
19211926 # incremented and decremented individually, and not based on the
1922- # VHD chain (i.e., the child's normal refcount will be decremented
1927+ # image chain (i.e., the child's normal refcount will be decremented
19231928 # independently of its parent situation). Add 1 for this clone op.
19241929 # Note that we do not need to do protect the refcount operations
19251930 # below with per-VDI locking like we do in lvutil because at this
@@ -2018,7 +2023,7 @@ def _finishSnapshot(self, snapVDI, snapVDI2, hostRefs, cloneOp=False, snapType=N
20182023 if not basePresent :
20192024 # a single-snapshot of an empty VDI will be a noop, resulting
20202025 # in no new VDIs, so return the existing one. The GC wouldn't
2021- # normally try to single-snapshot an empty VHD of course, but
2026+ # normally try to single-snapshot an empty image of course, but
20222027 # if an external snapshot operation manages to sneak in right
20232028 # before a snapshot-coalesce phase, we would get here
20242029 snap = snapVDI
@@ -2059,14 +2064,16 @@ def _initFromLVInfo(self, lvInfo):
20592064 if not VdiType .isCowImage (self .vdi_type ):
20602065 self .loaded = True
20612066
2062- def _initFromVHDInfo (self , vhdInfo ):
2063- self .size = vhdInfo .sizeVirt
2064- self .parent = vhdInfo .parentUuid
2065- self .hidden = vhdInfo .hidden
2067+ def _initFromImageInfo (self , imageInfo ):
2068+ self .size = imageInfo .sizeVirt
2069+ self .parent = imageInfo .parentUuid
2070+ self .hidden = imageInfo .hidden
20662071 self .loaded = True
20672072
20682073 def _determineType (self ):
2069- """Determine whether this is a raw or a VHD VDI"""
2074+ """
2075+ Determine whether this is a RAW or a COW VDI.
2076+ """
20702077 if "vdi_ref" in self .sr .srcmd .params :
20712078 vdi_ref = self .sr .srcmd .params ["vdi_ref" ]
20722079 sm_config = self .session .xenapi .VDI .get_sm_config (vdi_ref )
@@ -2107,8 +2114,10 @@ def _determineType(self):
21072114 return False
21082115
21092116 def _loadThis (self ):
2110- """Load VDI info for this VDI and activate the LV if it's VHD. We
2111- don't do it in VDI.load() because not all VDI operations need it."""
2117+ """
2118+ Load VDI info for this VDI and activate the LV if it's COW. We
2119+ don't do it in VDI.load() because not all VDI operations need it.
2120+ """
21122121 if self .loaded :
21132122 if VdiType .isCowImage (self .vdi_type ):
21142123 self .sr .lvActivator .activate (self .uuid , self .lvname , False )
@@ -2123,11 +2132,10 @@ def _loadThis(self):
21232132 self ._initFromLVInfo (lvs [self .uuid ])
21242133 if VdiType .isCowImage (self .vdi_type ):
21252134 self .sr .lvActivator .activate (self .uuid , self .lvname , False )
2126- vhdInfo = self ._cowutil .getInfo (self .path , LvmCowUtil .extractUuid , False )
2127- if not vhdInfo :
2128- raise xs_errors .XenError ('VDIUnavailable' , \
2129- opterr = 'getVHDInfo failed' )
2130- self ._initFromVHDInfo (vhdInfo )
2135+ imageInfo = self .cowutil .getInfo (self .path , LvmCowUtil .extractUuid , False )
2136+ if not imageInfo :
2137+ raise xs_errors .XenError ('VDIUnavailable' , opterr = 'getInfo failed' )
2138+ self ._initFromImageInfo (imageInfo )
21312139 self .loaded = True
21322140
21332141 def _chainSetActive (self , active , binary , persistent = False ):
@@ -2139,8 +2147,7 @@ def _chainSetActive(self, active, binary, persistent=False):
21392147
21402148 vdiList = {self .uuid : self .lvname }
21412149 if VdiType .isCowImage (self .vdi_type ):
2142- vdiList = vhdutil .getParentChain (self .lvname ,
2143- LvmCowUtil .extractUuid , self .sr .vgname )
2150+ vdiList = self .cowutil .getParentChain (self .lvname , LvmCowUtil .extractUuid , self .sr .vgname )
21442151 for uuid , lvName in vdiList .items ():
21452152 binaryParam = binary
21462153 if uuid != self .uuid :
0 commit comments