Change in vdsm[master]: Refactor prepareVolumePath
by smizrahi@redhat.com
Saggi Mizrahi has uploaded a new change for review.
Change subject: Refactor prepareVolumePath
......................................................................
Refactor prepareVolumePath
Change-Id: I57bb8684fd11a47843a158d13fcc2815147fa7ef
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
M vdsm/API.py
M vdsm/clientIF.py
M vdsm/libvirtvm.py
M vdsm/storage/devicemapper.py
M vdsm/vm.py
5 files changed, 93 insertions(+), 63 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/55/7755/1
diff --git a/vdsm/API.py b/vdsm/API.py
index 720c3b9..c324d79 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -173,8 +173,7 @@
# NOTE: pickled params override command-line params. this
# might cause problems if an upgrade took place since the
# parmas were stored.
- fname = self._cif.prepareVolumePath(paramFilespec)
- try:
+ with self._cif.preparedDrive(paramFilespec) as fname:
with file(fname) as f:
pickledMachineParams = pickle.load(f)
@@ -183,8 +182,6 @@
+ str(pickledMachineParams))
self.log.debug('former conf ' + str(vmParams))
vmParams.update(pickledMachineParams)
- finally:
- self._cif.teardownVolumePath(paramFilespec)
except:
self.log.error("Error restoring VM parameters",
exc_info=True)
@@ -299,9 +296,15 @@
:param hiberVolHandle: opaque string, indicating the location of
hibernation images.
"""
- params = {'vmId': self._UUID, 'mode': 'file',
- 'hiberVolHandle': hibernationVolHandle}
- response = self.migrate(params)
+ v = self._getVmObject()
+ if v is None:
+ return errCode['noVM']
+
+ try:
+ response = self.hibernate(hibernationVolHandle)
+ except vm.WrongStateError:
+ response = errCode['noVM']
+
if not response['status']['code']:
response['status']['message'] = 'Hibernation process starting'
return response
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index 55a7fc9..0446eb2 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -25,6 +25,7 @@
from xml.dom import minidom
import uuid
import errno
+from contextlib import contextmanager
from storage.dispatcher import Dispatcher
from storage.hsm import HSM
@@ -44,6 +45,7 @@
import blkid
import supervdsm
import vmContainer
+from storage import devicemapper
try:
import gluster.api as gapi
_glusterEnabled = True
@@ -239,50 +241,74 @@
self.log.info('Error finding path for device', exc_info=True)
raise vm.VolumeError(uuid)
+ def _preparePoolImage(self, drive):
+ res = self.irs.prepareImage(
+ drive['domainID'], drive['poolID'],
+ drive['imageID'], drive['volumeID'])
+
+ if res['status']['code']:
+ raise vm.VolumeError(drive)
+
+ drive['volumeChain'] = res['chain']
+ return res['path']
+
+ def _prepareDmDevice(self, drive, vmId):
+ volPath = devicemapper.getDevicePathByGuid(drive["GUID"])
+
+ if not os.path.exists(volPath):
+ raise vm.VolumeError(drive)
+
+ res = self.irs.appropriateDevice(drive["GUID"], vmId)
+ if res['status']['code']:
+ raise vm.VolumeError(drive)
+
+ return volPath
+
+ def _prepareScsiDevice(self, drive):
+ return self._getUUIDSpecPath(drive["UUID"])
+
+ def _prepareVmPayload(self, drive, vmId):
+ '''
+ vmPayload is a key in specParams
+ 'vmPayload': {'file': {'filename': 'content'}}
+ '''
+ for key, files in drive['specParams']['vmPayload'].iteritems():
+ if key == 'file':
+ svdsm = supervdsm.getProxy()
+ if drive['device'] == 'cdrom':
+ return svdsm.mkIsoFs(vmId, files)
+ elif drive['device'] == 'floppy':
+ return svdsm.mkFloppyFs(vmId, files)
+
+ raise vm.VolumeError(drive)
+
+ def _preparePath(self, drive):
+ return drive['path']
+
+ @contextmanager
+ def perparedDrive(self, drive, vmId=None):
+ path = self.prepareVolumePath(drive, vmId)
+ try:
+ yield path
+ finally:
+ self.teardownVolumePath(drive, vmId)
+
def prepareVolumePath(self, drive, vmId=None):
if type(drive) is dict:
- # PDIV drive format
if drive['device'] == 'disk' and vm.isVdsmImage(drive):
- res = self.irs.prepareImage(
- drive['domainID'], drive['poolID'],
- drive['imageID'], drive['volumeID'])
+ volPath = self._preparePoolImage(drive)
- if res['status']['code']:
- raise vm.VolumeError(drive)
-
- volPath = res['path']
- drive['volumeChain'] = res['chain']
-
- # GUID drive format
elif "GUID" in drive:
- volPath = os.path.join("/dev/mapper", drive["GUID"])
+ volPath = self._prepareDmDevice(drive, vmId)
- if not os.path.exists(volPath):
- raise vm.VolumeError(drive)
-
- res = self.irs.appropriateDevice(drive["GUID"], vmId)
- if res['status']['code']:
- raise vm.VolumeError(drive)
-
- # UUID drive format
elif "UUID" in drive:
- volPath = self._getUUIDSpecPath(drive["UUID"])
+ volPath = self._prepareScsiDevice(drive)
elif 'specParams' in drive and 'vmPayload' in drive['specParams']:
- '''
- vmPayload is a key in specParams
- 'vmPayload': {'file': {'filename': 'content'}}
- '''
- for key, files in drive['specParams']['vmPayload'].iteritems():
- if key == 'file':
- if drive['device'] == 'cdrom':
- volPath = supervdsm.getProxy().mkIsoFs(vmId, files)
- elif drive['device'] == 'floppy':
- volPath = \
- supervdsm.getProxy().mkFloppyFs(vmId, files)
+ volPath = self._prepareVmPayload(drive, vmId)
elif "path" in drive:
- volPath = drive['path']
+ volPath = self._preparePath(drive)
else:
raise vm.VolumeError(drive)
@@ -301,17 +327,22 @@
self.log.info("prepared volume path: %s", volPath)
return volPath
- def teardownVolumePath(self, drive):
- res = {'status': doneCode}
- if type(drive) == dict:
- try:
- res = self.irs.teardownImage(drive['domainID'],
- drive['poolID'], drive['imageID'])
- except KeyError:
- #This drive is not a vdsm image (quartet)
- self.log.info("Avoiding tear down drive %s", str(drive))
+ def _teardownPoolImage(self, drive):
+ try:
+ res = self.irs.teardownImage(drive['domainID'],
+ drive['poolID'], drive['imageID'])
+ return res['status']['code']
+ except KeyError:
+ #This drive is not a vdsm image (quartet)
+ self.log.info("Avoiding tear down drive %s", str(drive))
+ return doneCode
- return res['status']['code']
+ def teardownVolumePath(self, drive):
+ if type(drive) == dict:
+ return self._teardownPoolImage(drive)
+ else:
+ # Other types don't require tear down
+ return 0
def createVm(self, vmParams):
try:
@@ -320,6 +351,7 @@
except vmContainer.VmContainerError as e:
if e.errno == errno.EEXIST:
return errCode['exist']
+
return
def waitForShutdown(self, timeout=None):
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index a530228..ea0d017 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -404,11 +404,8 @@
hooks.before_vm_hibernate(self._vm._dom.XMLDesc(0), self._vm.conf)
try:
self._vm._vmStats.pause()
- fname = self._vm.cif.prepareVolumePath(self._dst)
- try:
+ with self._vm.cif.preparedDrive(self._dst) as fname:
self._vm._dom.save(fname)
- finally:
- self._vm.cif.teardownVolumePath(self._dst)
except:
self._vm._vmStats.cont()
raise
@@ -1397,11 +1394,8 @@
elif 'restoreState' in self.conf:
hooks.before_vm_dehibernate(self.conf.pop('_srcDomXML'), self.conf)
- fname = self.cif.prepareVolumePath(self.conf['restoreState'])
- try:
+ with self.cif.preparedDrive(self.conf['restoreState']) as fname:
self._connection.restore(fname)
- finally:
- self.cif.teardownVolumePath(self.conf['restoreState'])
self._dom = NotifyingVirDomain(
self._connection.lookupByUUIDString(self.id),
diff --git a/vdsm/storage/devicemapper.py b/vdsm/storage/devicemapper.py
index a1651e0..388c1cd 100644
--- a/vdsm/storage/devicemapper.py
+++ b/vdsm/storage/devicemapper.py
@@ -46,6 +46,10 @@
(major, minor)))
+def getDevicePathByGuid(devGuid):
+ return DMPATH_FORMAT % devGuid
+
+
def getSysfsPath(devName):
if "/" in devName:
raise ValueError("devName has an illegal format. "
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 3aa9f52..49193d3 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -210,12 +210,9 @@
if ignoreParam in self._machineParams:
del self._machineParams[ignoreParam]
- fname = self._vm.cif.prepareVolumePath(self._dstparams)
- try:
- with file(fname, "w") as f:
+ with self._vm.cif.preparedDrive(self._dstparams) as fname:
+ with file(fname, "wb") as f:
pickle.dump(self._machineParams, f)
- finally:
- self._vm.cif.teardownVolumePath(self._dstparams)
self._vm.setDownStatus(NORMAL, "SaveState succeeded")
self.status = {
--
To view, visit http://gerrit.ovirt.org/7755
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I57bb8684fd11a47843a158d13fcc2815147fa7ef
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
10 years
Change in vdsm[master]: [wip] hsm: remove superfluous refreshes at startup
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: [wip] hsm: remove superfluous refreshes at startup
......................................................................
[wip] hsm: remove superfluous refreshes at startup
During the startup it's not mandatory to refresh the iscsi connections
(the sdcache is already stale) and the lvm module can handle the lazy
initialization.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=870768
Change-Id: I8386d40c644c99a52f04b6b41b392abf16e3a2a6
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/hsm.py
1 file changed, 0 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/76/9276/1
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 46d1605..6a5040a 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -364,9 +364,6 @@
self.log.warn("Failed to clean Storage Repository.", exc_info=True)
def storageRefresh():
- lvm._lvminfo.bootstrap()
- sdCache.refreshStorage()
-
fileUtils.createdir(self.tasksDir)
# TBD: Should this be run in connectStoragePool? Should tasksDir
# exist under pool link as well (for hsm tasks)
--
To view, visit http://gerrit.ovirt.org/9276
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8386d40c644c99a52f04b6b41b392abf16e3a2a6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
10 years
Change in vdsm[master]: Remove unnecesary preparePaths.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: Remove unnecesary preparePaths.
......................................................................
Remove unnecesary preparePaths.
Recovering running VM's therefore paths are already prepared.
Prepare paths is not locking the volumes anymore (Federico).
Change-Id: I35890d36227633ca147387d670c152b9be357e50
---
M vdsm/clientIF.py
1 file changed, 0 insertions(+), 16 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/86/786/1
--
To view, visit http://gerrit.ovirt.org/786
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I35890d36227633ca147387d670c152b9be357e50
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
10 years
Change in vdsm[master]: Avoid template deactivation and lock.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: Avoid template deactivation and lock.
......................................................................
Avoid template deactivation and lock.
Change-Id: Ieedf863ac967f34405f038201bac324c52fbbe89
---
M vdsm/storage/blockVolume.py
M vdsm/storage/volume.py
2 files changed, 39 insertions(+), 18 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/63/863/1
--
To view, visit http://gerrit.ovirt.org/863
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ieedf863ac967f34405f038201bac324c52fbbe89
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
10 years
Change in vdsm[master]: [WIP] Add the validateImage command to the SPM
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: [WIP] Add the validateImage command to the SPM
......................................................................
[WIP] Add the validateImage command to the SPM
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
Change-Id: I095362e7d1eb91045569bd9526a102392e7adbe8
---
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/storage/hsm.py
M vdsm/storage/image.py
M vdsm/storage/sp.py
M vdsm/storage/volume.py
6 files changed, 60 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/91/3491/1
--
To view, visit http://gerrit.ovirt.org/3491
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I095362e7d1eb91045569bd9526a102392e7adbe8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
10 years
Change in vdsm[master]: image: copying a template is always allowed
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: image: copying a template is always allowed
......................................................................
image: copying a template is always allowed
To copy a template from a domain to another is a safe action even if
it has images that are based on it. This patch relaxes the check during
moveImage if the operation is a copy.
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
Change-Id: I9e07d569eec02ac4dcd386a7c576342f640ec242
---
M vdsm/storage/hsm.py
1 file changed, 19 insertions(+), 11 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/08/8408/1
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 50d6ce1..730ee03 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1288,32 +1288,39 @@
self._spmSchedule(spUUID, "deleteImage", lambda : True)
- def validateImageMove(self, srcDom, dstDom, imgUUID):
+ def validateImageCopy(self, srcDom, dstDom, imgUUID, safeToMove=False):
"""
- Determines if the image move is legal.
+ Determines if it is possible to copy (or move) the image.
- Moving an image based on a template to a data domain is only allowed if
- the template exists on the target domain.
- Moving a template from a data domain is only allowed if there are no
- images based on it in the source data domain.
+ Copying or moving an image based on a template to a data domain is
+ allowed only if the template already exists on the target domain.
+ When the option safeToMove (default: False) is active (True) an
+ extra check makes sure that if the image is a template (on a data
+ domain) then there are no other images based on it and therefore it
+ is safe to remove it.
"""
srcAllVols = srcDom.getAllVolumes()
dstAllVols = dstDom.getAllVolumes()
# Filter volumes related to this image
srcVolsImgs = sd.getVolsOfImage(srcAllVols, imgUUID)
+
# Find the template
for volName, imgsPar in srcVolsImgs.iteritems():
if len(imgsPar.imgs) > 1:
# This is the template. Should be only one.
tName, tImgs = volName, imgsPar.imgs
+
# Template self image is the 1st entry
if imgUUID != tImgs[0] and tName not in dstAllVols.keys():
- self.log.error("img %s can't be moved to dom %s because "
- "template %s is absent on it", imgUUID, dstDom.sdUUID, tName)
+ self.log.error("Cannot move image %s to domain %s "
+ "because the template %s is missing on the "
+ "destination", imgUUID, dstDom.sdUUID, tName)
raise se.ImageDoesNotExistInSD(imgUUID, dstDom.sdUUID)
- elif imgUUID == tImgs[0] and not srcDom.isBackup():
+ elif (safeToMove and imgUUID == tImgs[0]
+ and not srcDom.isBackup()):
raise se.MoveTemplateImageError(imgUUID)
+
break
return True
@@ -1333,7 +1340,8 @@
srcDom = self.validateSdUUID(srcDomUUID)
dstDom = self.validateSdUUID(dstDomUUID)
pool = self.getPool(spUUID) #Validates that the pool is connected. WHY?
- self.validateImageMove(srcDom, dstDom, imgUUID)
+ self.validateImageCopy(srcDom, dstDom, imgUUID,
+ safeToMove=(op != image.COPY_OP))
domains = [srcDomUUID, dstDomUUID]
domains.sort()
@@ -1364,7 +1372,7 @@
images = {}
for (imgUUID, pZero) in imgDict.iteritems():
images[imgUUID.strip()] = misc.parseBool(pZero)
- self.validateImageMove(srcDom, dstDom, imgUUID)
+ self.validateImageCopy(srcDom, dstDom, imgUUID, safeToMove=True)
domains = sorted([srcDomUUID, dstDomUUID])
for dom in domains:
--
To view, visit http://gerrit.ovirt.org/8408
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9e07d569eec02ac4dcd386a7c576342f640ec242
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
10 years
Change in vdsm[master]: [WIP] Simplifiying hsm.copyImage logic.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: [WIP] Simplifiying hsm.copyImage logic.
......................................................................
[WIP] Simplifiying hsm.copyImage logic.
Consider further optimization moving the
*.validateCreateVolumeParams() to the domain level.
Change-Id: I5db9053dabb97423611634e2bdfbdd09ec02876b
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/hsm.py
M vdsm/storage/sd.py
2 files changed, 14 insertions(+), 27 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/09/8509/1
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 2a8bc59..2c031f8 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1386,35 +1386,29 @@
Create new template/volume from VM.
Do it by collapse and copy the whole chain (baseVolUUID->srcVolUUID)
"""
- argsStr = "sdUUID=%s, spUUID=%s, vmUUID=%s, srcImgUUID=%s, srcVolUUID=%s, dstImgUUID=%s, "\
- "dstVolUUID=%s, description=%s, dstSdUUID=%s, volType=%s, volFormat=%s, "\
- "preallocate=%s force=%s, postZero=%s" % (sdUUID, spUUID, vmUUID,
- srcImgUUID, srcVolUUID, dstImgUUID, dstVolUUID, description,
- dstSdUUID, volType, volFormat, preallocate, force, postZero)
+ argsStr = str(locals())
vars.task.setDefaultException(se.TemplateCreationError("%s" % argsStr))
+ if dstSdUUID == sd.BLANK_UUID:
+ dstSdUUID = sdUUID
+
+ if dstSdUUID != sdUUID:
+ domains = (sdUUID, dstSdUUID)
# Validate imgUUID in case of copy inside source domain itself
- if dstSdUUID in (sdUUID, sd.BLANK_UUID):
- if srcImgUUID == dstImgUUID:
+ elif srcImgUUID == dstImgUUID:
raise se.InvalidParameterException("dstImgUUID", dstImgUUID)
+ else:
+ domains = (sdUUID)
+
pool = self.getPool(spUUID)
- self.validateSdUUID(sdUUID)
+ for dom in domains:
+ self.validateSdUUID(domains)
# Avoid VM copy if one of its volume (including template if exists) ILLEGAL/FAKE
pool.validateVolumeChain(sdUUID, srcImgUUID)
# Validate volume type and format
- if dstSdUUID != sd.BLANK_UUID:
- dom = dstSdUUID
- else:
- dom = sdUUID
- sdCache.produce(dom).validateCreateVolumeParams(volFormat, preallocate, volume.BLANK_UUID)
+ sdCache.produce(dstSdUUID).validateCreateVolumeParams(volFormat, preallocate, volume.BLANK_UUID)
- # If dstSdUUID defined, means we copy image to it
- domains = [sdUUID]
- if dstSdUUID not in [sdUUID, sd.BLANK_UUID]:
- self.validateSdUUID(dstSdUUID)
- domains.append(dstSdUUID)
- domains.sort()
-
+ domains.sort()
for dom in domains:
vars.task.getSharedLock(STORAGE, dom)
diff --git a/vdsm/storage/sd.py b/vdsm/storage/sd.py
index fcb796c..9c7fd52 100644
--- a/vdsm/storage/sd.py
+++ b/vdsm/storage/sd.py
@@ -369,13 +369,6 @@
"""
pass
- @classmethod
- def validateCreateVolumeParams(cls, volFormat, preallocate, srcVolUUID):
- """
- Validate create volume parameters
- """
- pass
-
def createVolume(self, imgUUID, size, volFormat, preallocate, diskType,
volUUID, desc, srcImgUUID, srcVolUUID):
"""
--
To view, visit http://gerrit.ovirt.org/8509
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5db9053dabb97423611634e2bdfbdd09ec02876b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
10 years
Change in vdsm[master]: vm: refresh all volumes after migration
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: vm: refresh all volumes after migration
......................................................................
vm: refresh all volumes after migration
After the vm live migration is completed the volumes must be refreshed
to comply with a possible volume extension happened after the migration
started.
Change-Id: Ibe0bd784e68f162b7902bb6ae50ff183d9f8fa8a
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/libvirtvm.py
M vdsm/vm.py
2 files changed, 32 insertions(+), 7 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/18/8518/1
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index 9f865de..729a288 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -1634,6 +1634,23 @@
else:
self._monitorResponse = 0
+ def refreshAllDrives(self):
+ volInfoList = []
+
+ for device in self._devices[vm.DISK_DEVICES][:]:
+ if not device.blockDev or not hasattr(device, 'domainID'):
+ continue
+
+ volInfoList.append({
+ 'domainID': device.domainID,
+ 'poolID': device.poolID,
+ 'imageID': device.imageID,
+ 'volumeID': device.volumeID,
+ })
+
+ if volInfoList:
+ self.refreshVolumes(volInfoList)
+
def _waitForIncomingMigrationFinish(self):
if 'restoreState' in self.conf:
self.cont()
@@ -1667,8 +1684,11 @@
del self.conf['guestIPs']
if 'username' in self.conf:
del self.conf['username']
+
self.saveState()
- self.log.debug("End of migration")
+
+ self.log.debug("Migration ended, refreshing all the drive volumes")
+ self.refreshAllDrives()
def _underlyingCont(self):
hooks.before_vm_cont(self._dom.XMLDesc(0), self.conf)
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 5ea2859..a3c6839 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -742,16 +742,21 @@
else:
self.__extendDriveVolume(vmDrive, newSize)
- def __refreshDriveVolume(self, volInfo):
+ def refreshVolumes(self, volInfoList):
""" Stop vm before refreshing LV. """
-
self._guestCpuLock.acquire()
try:
wasRunning = self._guestCpuRunning
+
if wasRunning:
self.pause(guestCpuLocked=True)
- self.cif.irs.refreshVolume(volInfo['domainID'],
- volInfo['poolID'], volInfo['imageID'], volInfo['volumeID'])
+
+ for volInfo in volInfoList:
+ self.cif.irs.refreshVolume(
+ volInfo['domainID'], volInfo['poolID'],
+ volInfo['imageID'], volInfo['volumeID']
+ )
+
if wasRunning:
self.cont(guestCpuLocked=True)
finally:
@@ -759,7 +764,7 @@
def __afterReplicaExtend(self, volInfo):
self.log.debug("Refreshing replica volume: %s", volInfo)
- self.__refreshDriveVolume(volInfo)
+ self.refreshVolumes((volInfo,))
vmDrive = self._findDriveByName(volInfo['name'])
@@ -778,7 +783,7 @@
def __afterDriveExtend(self, volInfo):
self.log.debug("Refreshing drive volume: %s", volInfo)
- self.__refreshDriveVolume(volInfo)
+ self.refreshVolumes((volInfo,))
vmDrive = self._findDriveByName(volInfo['name'])
res = self.cif.irs.getVolumeSize(vmDrive.domainID, vmDrive.poolID,
--
To view, visit http://gerrit.ovirt.org/8518
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibe0bd784e68f162b7902bb6ae50ff183d9f8fa8a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
10 years
Change in vdsm[master]: [wip] volume: make volume._share idempotent
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: [wip] volume: make volume._share idempotent
......................................................................
[wip] volume: make volume._share idempotent
With this patch it will possible to run the volume._share command
multiple times without harm (idempotent) for the image and for the
running VMs.
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
Change-Id: I237e4a8f094ba04dcd4ef7bff418e03f81162d8d
---
M vdsm/storage/blockVolume.py
M vdsm/storage/fileVolume.py
M vdsm/storage/volume.py
3 files changed, 39 insertions(+), 16 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/70/8270/1
diff --git a/vdsm/storage/blockVolume.py b/vdsm/storage/blockVolume.py
index 38285c1..ee8ba67 100644
--- a/vdsm/storage/blockVolume.py
+++ b/vdsm/storage/blockVolume.py
@@ -324,6 +324,7 @@
dstPath = os.path.join(dstImgPath, self.volUUID)
self.log.debug("Share volume %s to %s", self.volUUID, dstImgPath)
+ # TODO: make this idempotent
os.symlink(self.getDevPath(), dstPath)
@classmethod
diff --git a/vdsm/storage/fileVolume.py b/vdsm/storage/fileVolume.py
index 0aa9043..2e76944 100644
--- a/vdsm/storage/fileVolume.py
+++ b/vdsm/storage/fileVolume.py
@@ -227,29 +227,49 @@
"""
Share this volume to dstImgPath, including the metadata and the lease
"""
- dstVolPath = os.path.join(dstImgPath, self.volUUID)
- dstMetaPath = self._getMetaVolumePath(dstVolPath)
-
self.log.debug("Share volume %s to %s", self.volUUID, dstImgPath)
- self.oop.fileUtils.safeUnlink(dstVolPath)
- self.oop.os.link(self.getVolumePath(), dstVolPath)
+ dstVolumePath = os.path.join(dstImgPath, self.volUUID)
- self.log.debug("Share volume metadata of %s to %s", self.volUUID,
- dstImgPath)
+ # Format: itemName, srcPath, dstPath, itemRequired
+ itemsList = [
+ ('volume', self.getVolumePath(), dstVolumePath, True),
+ ('metadata', self._getMetaVolumePath(),
+ self._getMetaVolumePath(dstVolumePath), True),
+ ('lease', self._getLeaseVolumePath(),
+ self._getLeaseVolumePath(dstVolumePath),
+ sdCache.produce(self.sdUUID).hasVolumeLeases()),
+ ]
- self.oop.fileUtils.safeUnlink(dstMetaPath)
- self.oop.os.link(self._getMetaVolumePath(), dstMetaPath)
+ for itemName, srcPath, dstPath, itemRequired in itemsList:
+ self.log.debug("Sharing %s %s to %s (required: %s)", itemName,
+ self.volUUID, dstPath, itemRequired)
- # Link the lease file if the domain uses sanlock
- if sdCache.produce(self.sdUUID).hasVolumeLeases():
- dstLeasePath = self._getLeaseVolumePath(dstVolPath)
+ try:
+ srcInfo = self.oop.stat(srcPath)
+ except OSError, e:
+ if e != os.errno.ENOENT or itemRequired:
+ # Source not found
+ self.log.debug("TODO: <message>")
+ raise
- self.log.debug("Share volume lease of %s to %s", self.volUUID,
- dstImgPath)
+ try:
+ dstInfo = self.oop.stat(dstPath)
+ except OSError, e:
+ if e != os.errno.ENOENT:
+ raise
- self.oop.fileUtils.safeUnlink(dstLeasePath)
- self.oop.os.link(self._getLeaseVolumePath(), dstLeasePath)
+ # Destination file not present, linking
+ self.log.debug("TODO: <message>")
+ self.oop.os.link(srcPath, dstPath)
+ else:
+ # If both the source and destination are present and they are
+ # the same file (already linked) then continue.
+ if srcInfo.st_ino == dstInfo.st_ino:
+ self.log.debug("TODO: <message>")
+ else:
+ self.log.debug("TODO: <message>")
+ raise OSError(os.errno.EEXIST, "Destination file exists")
@classmethod
def shareVolumeRollback(cls, taskObj, volPath):
diff --git a/vdsm/storage/volume.py b/vdsm/storage/volume.py
index b9eb356..7938c6f 100644
--- a/vdsm/storage/volume.py
+++ b/vdsm/storage/volume.py
@@ -297,6 +297,8 @@
self._share(dstImgPath)
except Exception, e:
+ self.log.debug("Cannot share volume %s to %s", self.volUUID,
+ dstImgPath, exc_info=True)
raise se.CannotShareVolume(self.getVolumePath(), dstPath, str(e))
def refreshVolume(self):
--
To view, visit http://gerrit.ovirt.org/8270
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I237e4a8f094ba04dcd4ef7bff418e03f81162d8d
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
10 years
Change in vdsm[master]: WIP - Avoid creation of fake templates.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: WIP - Avoid creation of fake templates.
......................................................................
WIP - Avoid creation of fake templates.
Change-Id: I7ae6e455757f247bfc3d8e261d8f5cec25f8776a
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/image.py
M vdsm/storage/sp.py
2 files changed, 0 insertions(+), 45 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/80/8280/1
diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py
index d004046..bb620ef 100644
--- a/vdsm/storage/image.py
+++ b/vdsm/storage/image.py
@@ -20,7 +20,6 @@
import os
import logging
-import threading
import uuid
from contextlib import contextmanager
@@ -65,7 +64,6 @@
Consist from chain of volumes.
"""
log = logging.getLogger('Storage.Image')
- _fakeTemplateLock = threading.Lock()
@classmethod
def createImageRollback(cls, taskObj, imageDir):
@@ -428,37 +426,6 @@
self.repoPath, destDom.sdUUID, sd.DOMAIN_IMAGES,
templateImage, volUUID), tLink)
- def createFakeTemplate(self, sdUUID, volParams):
- """
- Create fake template (relevant for Backup domain only)
- """
- with self._fakeTemplateLock:
- try:
- destDom = sdCache.produce(sdUUID)
- volclass = destDom.getVolumeClass()
- # Validate that the destination template exists and accessible
- volclass(self.repoPath, sdUUID, volParams['imgUUID'], volParams['volUUID'])
- except (se.VolumeDoesNotExist, se.ImagePathError):
- try:
- # Create fake parent volume
- destDom.createVolume(imgUUID=volParams['imgUUID'], size=volParams['size'],
- volFormat=volume.COW_FORMAT, preallocate=volume.SPARSE_VOL,
- diskType=volParams['disktype'], volUUID=volParams['volUUID'], desc="Fake volume",
- srcImgUUID=volume.BLANK_UUID, srcVolUUID=volume.BLANK_UUID)
-
- vol = destDom.produceVolume(imgUUID=volParams['imgUUID'], volUUID=volParams['volUUID'])
- # Mark fake volume as "FAKE"
- vol.setLegality(volume.FAKE_VOL)
- # Mark fake volume as shared
- vol.setShared()
- # Now we should re-link all hardlinks of this template in all VMs based on it
- self.__templateRelink(destDom, volParams['imgUUID'], volParams['volUUID'])
-
- self.log.debug("Succeeded to create fake image %s in domain %s", volParams['imgUUID'], destDom.sdUUID)
- except Exception:
- self.log.error("Failure to create fake image %s in domain %s", volParams['imgUUID'],
- destDom.sdUUID, exc_info=True)
-
def isLegal(self, sdUUID, imgUUID):
"""
Check correctness of the whole chain (excluding template)
@@ -502,7 +469,6 @@
self.log.error("Unexpected error", exc_info=True)
raise se.SourceImageActionError(imgUUID, srcSdUUID, str(e))
- fakeTemplate = False
pimg = volume.BLANK_UUID # standalone chain
# check if the chain is build above a template, or it is a standalone
pvol = srcChain[0].getParentVolume()
@@ -510,11 +476,6 @@
# find out parent volume parameters
volParams = pvol.getVolumeParams()
pimg = volParams['imgUUID'] # pimg == template image
- if destDom.isBackup():
- # FIXME: This workaround help as copy VM to the backup domain without its template
- # We will create fake template for future VM creation and mark it as FAKE volume
- # This situation is relevant for backup domain only
- fakeTemplate = True
@contextmanager
def justLogIt(img):
@@ -525,9 +486,6 @@
# In destination domain we need to lock image's template if exists
with rmanager.acquireResource(dstImageResourcesNamespace, pimg, rm.LockType.shared) \
if pimg != volume.BLANK_UUID else justLogIt(imgUUID):
- if fakeTemplate:
- self.createFakeTemplate(destDom.sdUUID, volParams)
-
dstChain = []
for srcVol in srcChain:
# Create the dst volume
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 78fbe66..d3b7009 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1828,10 +1828,7 @@
allVols)
else:
# Removing a template with dependencies in backup domain
- # A fake template will be created
img.delete(sdUUID=sdUUID, imgUUID=imgUUID, postZero=postZero, force=True)
- tParams = dom.produceVolume(imgUUID, tName).getVolumeParams()
- img.createFakeTemplate(sdUUID=sdUUID, volParams=tParams)
def mergeSnapshots(self, sdUUID, vmUUID, imgUUID, ancestor, successor, postZero):
"""
--
To view, visit http://gerrit.ovirt.org/8280
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7ae6e455757f247bfc3d8e261d8f5cec25f8776a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
10 years