Adam Litke has uploaded a new change for review.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
SDM: Add extendVolumeContainer API
The extendVolumeContainer API is used to extend LVM logical volumes which store thinly-provisioned vdsm volumes.
Change-Id: I6a128ba3eab4116ff4e794e94a171e51d9e432de Signed-off-by: Adam Litke alitke@redhat.com --- M client/vdsClient.py M vdsm/API.py M vdsm/rpc/BindingXMLRPC.py M vdsm/rpc/vdsmapi-schema.json M vdsm/storage/hsm.py M vdsm/storage/sdm/__init__.py M vdsm/storage/sdm/blockstore.py M vdsm/storage/sdm/filestore.py 8 files changed, 123 insertions(+), 9 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/96/39696/1
diff --git a/client/vdsClient.py b/client/vdsClient.py index 23bfc1a..f6c0c83 100755 --- a/client/vdsClient.py +++ b/client/vdsClient.py @@ -1953,6 +1953,17 @@ else: return status['status']['code'], status['status']['message']
+ def extendVolumeContainer(self, args): + if len(args) != 4: + raise ValueError("Wrong number of arguments") + + sdUUID, imgUUID, volUUID, size = args + status = self.s.extendVolumeContainer(sdUUID, imgUUID, volUUID, size) + if status['status']['code'] == 0: + return 0, '' + else: + return status['status']['code'], status['status']['message'] +
if __name__ == '__main__': if _glusterEnabled: @@ -2844,6 +2855,11 @@ '<srcImage> <dstImage> <collapse>', 'Copy the date from one volume into another.' )), + 'extendVolumeContainer': ( + serv.extendVolumeContainer, ( + '<sdUUID> <imgUUID> <volUUID>', + 'Extend a thinly-provisioned block volume.' + )), } if _glusterEnabled: commands.update(ge.getGlusterCmdDict(serv)) diff --git a/vdsm/API.py b/vdsm/API.py index b4b7308..5661b82 100644 --- a/vdsm/API.py +++ b/vdsm/API.py @@ -1675,6 +1675,10 @@ def copyData(self, srcImage, dstImage, collapse): return self._cif.irs.copyData(srcImage, dstImage, collapse)
+ def extendVolumeContainer(self, sdUUID, imgUUID, volUUID, size): + return self._cif.irs.extendVolumeContainer(sdUUID, imgUUID, volUUID, + size) + # take a rough estimate on how much free mem is available for new vm # memTotal = memFree + memCached + mem_used_by_non_qemu + resident . # simply returning (memFree + memCached) is not good enough, as the diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py index 3e70e28..ae43614 100644 --- a/vdsm/rpc/BindingXMLRPC.py +++ b/vdsm/rpc/BindingXMLRPC.py @@ -993,6 +993,10 @@ api = API.Global() return api.copyData(srcImage, dstImage, collapse)
+ def extendVolumeContainer(self, sdUUID, imgUUID, volUUID, size): + api = API.Global() + return api.extendVolumeContainer(sdUUID, imgUUID, volUUID, size) + def getGlobalMethods(self): return ((self.vmDestroy, 'destroy'), (self.vmCreate, 'create'), @@ -1143,7 +1147,8 @@ 'storageServer_ConnectionRefs_statuses'), (self.volumeCreateContainer, 'createVolumeContainer'), (self.volumeRemove, 'removeVolume'), - (self.copyData, 'copyData')) + (self.copyData, 'copyData'), + (self.extendVolumeContainer, 'extendVolumeContainer'))
def wrapApiMethod(f): diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json index 8720703..f507324 100644 --- a/vdsm/rpc/vdsmapi-schema.json +++ b/vdsm/rpc/vdsmapi-schema.json @@ -4182,6 +4182,24 @@ 'data': {'srcImage': 'VolumeSpec', 'dstImage': 'VolumeSpec', 'collapse': 'bool'}}
+## +# @Host.extendVolumeContainer: +# +# Extend a thinly-provisioned volume. +# +# @sdUUID: The UUID of the storage domain containing the volume +# +# @imgUUID: The UUID of the image containing the volume +# +# @volUUID: The UUID of the volume +# +# @size: The new desired size (in bytes) +# +# Since: 4.18.0 +## +{'command': {'class': 'Host', 'name': 'extendVolumeContainer'}, + 'data': {'sdUUID': 'UUID', 'imgUUID': 'UUID', 'volUUID': 'UUID', + 'size': 'uint'}}
## Category: @ConnectionRefs ################################################## ## diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py index 2236457..34730dd 100644 --- a/vdsm/storage/hsm.py +++ b/vdsm/storage/hsm.py @@ -854,13 +854,22 @@
""" newSize = misc.validateN(newSize, "newSize") / 2 ** 20 - try: - pool = self.getPool(spUUID) - except se.StoragePoolUnknown: - pass + enableSDM = True # Replace this with a check on the SD version + if enableSDM: + domain = sdCache.produce(volDict['domainID']) + self._sdmSchedule('extendVolumeContainer', + sdm.extendVolumeContainer, domain, + volDict['imageID'], volDict['volumeID'], newSize, + callbackFunc, volDict) else: - if pool.hsmMailer: - pool.hsmMailer.sendExtendMsg(volDict, newSize, callbackFunc) + try: + pool = self.getPool(spUUID) + except se.StoragePoolUnknown: + pass + else: + if pool.hsmMailer: + pool.hsmMailer.sendExtendMsg(volDict, newSize, + callbackFunc)
def _spmSchedule(self, spUUID, name, func, *args): self.validateSPM(spUUID) @@ -3744,3 +3753,18 @@ se.VolumeCopyError("Unsupported combination of image types: " "src:%s, dst:%s" % (src.get('type'), dst.get('type'))) + + @public + def extendVolumeContainer(self, sdUUID, imgUUID, volUUID, size): + vars.task.setDefaultException( + se.VolumeExtendingError("sdUUID=%s, volumeUUID=%s, size=%s" % ( + sdUUID, volUUID, size))) + size = misc.validateN(size, "size") + # ExtendVolume expects size in MB + size = math.ceil(size / 2 ** 20) + + dom = sdCache.produce(sdUUID=sdUUID) + misc.validateUUID(imgUUID, 'imgUUID') + misc.validateUUID(volUUID, 'volUUID') + vars.task.getSharedLock(STORAGE, sdUUID) + return sdm.extendVolumeContainer(dom, imgUUID, volUUID, size) diff --git a/vdsm/storage/sdm/__init__.py b/vdsm/storage/sdm/__init__.py index 9d74bd5..7f80ca2 100644 --- a/vdsm/storage/sdm/__init__.py +++ b/vdsm/storage/sdm/__init__.py @@ -195,3 +195,16 @@ finally: dstDom.releaseVolumeLease(dstImage['imgUUID'], dstImage['volUUID']) srcDom.releaseVolumeLease(srcImage['imgUUID'], srcImage['volUUID']) + + +def extendVolumeContainer(domain, imgUUID, volUUID, size, + cbFn=None, cbData=None): + cls = __getStoreClass(domain) + hostId = getDomainHostId(domain.sdUUID) + domain.acquireClusterLock(hostId) + try: + cls.extendVolume(domain, imgUUID, volUUID, size) + finally: + domain.releaseClusterLock() + if cbFn: + cbFn(cbData) diff --git a/vdsm/storage/sdm/blockstore.py b/vdsm/storage/sdm/blockstore.py index b80f869..73a12a8 100644 --- a/vdsm/storage/sdm/blockstore.py +++ b/vdsm/storage/sdm/blockstore.py @@ -20,6 +20,7 @@
import os import logging +import math
import vdsm.utils as utils from vdsm.config import config @@ -27,9 +28,13 @@ import volumestore from .. import blockVolume from .. import lvm +from .. import resourceManager as rm +from .. import sd from .. import storage_exception as se from .. import volume +from ..resourceFactories import IMAGE_NAMESPACE
+rmanager = rm.ResourceManager.getInstance() log = logging.getLogger('Storage.sdm.blockstore')
SECTORS_TO_MB = (1 << 20) / volume.BLOCK_SIZE @@ -37,6 +42,9 @@
class BlockStore(volumestore.VolumeStore): volClass = blockVolume.BlockVolume + + # Estimate of the additional space needed for qcow format internal data. + VOLWM_COW_OVERHEAD = 1.1
@classmethod def volFormatToPreallocate(cls, volFormat): @@ -109,7 +117,7 @@ parent = tag[len(blockVolume.TAG_PREFIX_PARENT):] if parent and image: break - vols.append(volumestore.GCVol(lv.name, volUUID, image, parent)) + vols.append(volumestore.GCVol(lv.name, volUUID, image, parent) return vols
@classmethod @@ -119,3 +127,24 @@ except se.VolumeMetadataReadError: pass lvm.removeLVs(dom.sdUUID, volName) + + @classmethod + def extendVolume(cls, dom, imgUUID, volUUID, size): + imageResourcesNamespace = sd.getNamespace(dom.sdUUID, IMAGE_NAMESPACE) + with rmanager.acquireResource(imageResourcesNamespace, imgUUID, + rm.LockType.shared): + # Verify that the requested size is valid + vol = dom.produceVolume(imgUUID, volUUID) + volInfo = vol.getInfo() + maxSize = int(volInfo['capacity']) + if volInfo['format'] == volume.type2name(volume.COW_FORMAT): + maxSize = maxSize * cls.VOLWM_COW_OVERHEAD + maxSize = math.ceil(maxSize / 2 ** 20) + if size > maxSize: + raise se.VolumeExtendingError( + "Size %i exceeds the maximum extend size of %i for volume " + "%s" % (size, maxSize, volUUID)) + + dom.extendVolume(volUUID, size) + + diff --git a/vdsm/storage/sdm/filestore.py b/vdsm/storage/sdm/filestore.py index dd6c58f..cc3e2bb 100644 --- a/vdsm/storage/sdm/filestore.py +++ b/vdsm/storage/sdm/filestore.py @@ -157,4 +157,9 @@ except se.ImageDeleteError: dom.imageGarbageCollector() else: - dom.oop.os.unlink(volPath) \ No newline at end of file + dom.oop.os.unlink(volPath) + + @classmethod + def extendVolume(cls, dom, imgUUID, volUUID, size): + # There is nothing to do for file domains. The filesystem handles it, + pass
automation@ovirt.org has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 1:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 1:
Build Started (1/2) -> http://jenkins.ovirt.org/job/vdsm_master_pep8_gerrit/17565/
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 1:
Build Started (2/2) -> http://jenkins.ovirt.org/job/vdsm_master_unit-tests_created/17739/
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 1: Code-Review-1 Verified-1
Build Failed
http://jenkins.ovirt.org/job/vdsm_master_pep8_gerrit/17565/ : UNSTABLE
http://jenkins.ovirt.org/job/vdsm_master_unit-tests_created/17739/ : FAILURE
automation@ovirt.org has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 2:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 2:
Build Started (1/2) -> http://jenkins.ovirt.org/job/vdsm_master_pep8_gerrit/17739/
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 2:
Build Started (2/2) -> http://jenkins.ovirt.org/job/vdsm_master_unit-tests_created/17910/
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 2:
Build Failed
http://jenkins.ovirt.org/job/vdsm_master_unit-tests_created/17910/ : FAILURE
http://jenkins.ovirt.org/job/vdsm_master_pep8_gerrit/17739/ : SUCCESS
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 3:
Build Started (1/2) -> http://jenkins.ovirt.org/job/vdsm_master_pep8_gerrit/18310/
automation@ovirt.org has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 3:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 3:
Build Started (2/2) -> http://jenkins.ovirt.org/job/vdsm_master_unit-tests_created/1540/
oVirt Jenkins CI Server has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 3: Verified-1
Build Failed
http://jenkins.ovirt.org/job/vdsm_master_pep8_gerrit/18310/ : SUCCESS
http://jenkins.ovirt.org/job/vdsm_master_unit-tests_created/1540/ : FAILURE
automation@ovirt.org has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 4:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
automation@ovirt.org has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 5:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
Jenkins CI RO has abandoned this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Abandoned
Abandoned due to no activity - please restore if still relevant
gerrit-hooks has posted comments on this change.
Change subject: SDM: Add extendVolumeContainer API ......................................................................
Patch Set 5:
* Update tracker: IGNORE, no Bug-Url found
vdsm-patches@lists.fedorahosted.org