Yeela Kaplan has uploaded a new change for review. Change subject: Shrink the new volume When merging block cow volumes ......................................................................
Shrink the new volume When merging block cow volumes Change-Id: I8ace4c48d278cb84ce871bc402643131265c3198 Signed-off-by: Yeela Kaplan <[email protected]> --- M vdsm/qemuImg.py M vdsm/storage/blockVolume.py M vdsm/storage/image.py M vdsm/storage/lvm.py M vdsm/storage/volume.py 5 files changed, 79 insertions(+), 1 deletion(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/25/9725/1 diff --git a/vdsm/qemuImg.py b/vdsm/qemuImg.py index 5496d93..a57fe56 100644 --- a/vdsm/qemuImg.py +++ b/vdsm/qemuImg.py @@ -39,6 +39,7 @@ "[\d.]+[KMGT] \((?P<value>\d+) bytes\)$"), 'clustersize': re.compile("^cluster_size: (?P<value>\d+)$"), 'backingfile': re.compile("^backing file: (?P<value>.+) \(actual path"), + 'offset': re.compile("^Highest offset in use: (?P<value>\d+)$"), } @@ -82,7 +83,7 @@ if len(out) > 5: info['backingfile'] = __iregexSearch("backingfile", out[5]) except: - raise QImgError(rc, out, err, "unable to parse qemu-img output") + raise QImgError(rc, out, err, "unable to parse qemu-img info output") return info @@ -98,3 +99,9 @@ if rc != 0: raise QImgError(rc, out, err) + try: + offset = int(__iregexSearch("offset", out[1])) + except: + raise QImgError(rc, out, err, "unable to parse qemu-img check output") + + return offset diff --git a/vdsm/storage/blockVolume.py b/vdsm/storage/blockVolume.py index 186ca95..5577998 100644 --- a/vdsm/storage/blockVolume.py +++ b/vdsm/storage/blockVolume.py @@ -23,6 +23,7 @@ import logging import sanlock +from vdsm import qemuImg from vdsm.config import config import storage_exception as se import volume @@ -283,6 +284,31 @@ sizemb = (newSize + 2047) / 2048 lvm.extendLV(self.sdUUID, self.volUUID, sizemb) + def reduce(self, newSize): + """Reduce a logical volume + 'newSize' - new size in blocks + """ + self.log.info("Request to reduce LV %s of image %s in VG %s with " + "size = %s", self.volUUID, self.imgUUID, self.sdUUID, + newSize) + sizemb = (newSize + 2047) / 2048 + lvm.reduceLV(self.sdUUID, self.volUUID, sizemb) + + def shrinkOnMerge(self, dstVol): + volParams = self.getVolumeParams() + if volParams['volFormat'] == volume.COW_FORMAT: + lvm.activateLVs(self.sdUUID, self.volUUID) + offset = qemuImg.check(self.getVolumePath(), qemuImg.FORMAT.QCOW2) + lvm.deactivateLVs(self.sdUUID, self.volUUID) + volActualSize = offset + volBaseSize = int(config.get("irs", "volume_utilization_chunk_mb")) + volBaseSize = volBaseSize * 1024 * 1024 + volUtil = int(config.get("irs", "volume_utilization_percent")) + finalSize = (volActualSize + volBaseSize * volUtil * 0.01) + self.reduce((finalSize + 511) / 512) + self.log.debug('Shrink qcow volume: %s on merge to : %s bytes', + self.sdUUID, finalSize) + @classmethod def renameVolumeRollback(cls, taskObj, sdUUID, oldUUID, newUUID): try: diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py index 4364c38..3265633 100644 --- a/vdsm/storage/image.py +++ b/vdsm/storage/image.py @@ -1193,4 +1193,6 @@ self.log.error("Failure to remove subchain %s -> %s in image %s", ancestor, successor, imgUUID, exc_info=True) + srcVol.shrinkOnMerge(dstVol) + self.log.info("Merge src=%s with dst=%s was successfully finished.", srcVol.getVolumePath(), dstVol.getVolumePath()) diff --git a/vdsm/storage/lvm.py b/vdsm/storage/lvm.py index 65badf7..30b6046 100644 --- a/vdsm/storage/lvm.py +++ b/vdsm/storage/lvm.py @@ -1090,6 +1090,36 @@ raise se.LogicalVolumeExtendError(vgName, lvName, "%sM" % (size, )) +def reduceLV(vgName, lvName, size): + """ + Size units: MB (1024 ** 2 = 2 ** 20)B. + """ + # WARNING! From man vgs: + # All sizes are output in these units: (h)uman-readable, (b)ytes, + # (s)ectors,(k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes, + # (p)etabytes, (e)xabytes. + # Capitalise to use multiples of 1000 (S.I.) instead of 1024. + cmd = ("lvreduce",) + LVM_NOBACKUP + cmd += ("--size", "%sm" % (size,), "%s/%s" % (vgName, lvName)) + rc, out, err = _lvminfo.cmd(cmd) + if rc == 0: + _lvminfo._invalidatevgs(vgName) + _lvminfo._invalidatelvs(vgName, lvName) + elif rc == 3: + #In LVM we trust. Hope that 3 is only for this. + log.debug("New size (in extents) matches existing size (in extents).") + elif rc != 0: + #get the free extents size + vg = getVG(vgName) + free_size = int(vg.extent_size) * int(vg.free_count) # in B + if free_size < int(size) * constants.MEGAB: + raise se.VolumeGroupSizeError("%s/%s %d > %d (MiB)" % + (vgName, lvName, int(size), + free_size / constants.MEGAB)) + + raise se.LogicalVolumeReduceError(vgName, lvName, "%sM" % (size, )) + + def activateLVs(vgName, lvNames): lvNames = _normalizeargs(lvNames) toActivate = [lvName for lvName in lvNames diff --git a/vdsm/storage/volume.py b/vdsm/storage/volume.py index dcc6c0b..4c4a7c0 100644 --- a/vdsm/storage/volume.py +++ b/vdsm/storage/volume.py @@ -547,6 +547,12 @@ """ pass + def reduce(self, newsize): + """ + reduce a logical volume + """ + pass + def setDescription(self, descr): """ Set Volume Description @@ -903,6 +909,13 @@ volParams['legality'] = self.getLegality() return volParams + def shrinkOnMerge(self, dstVol): + """ + Shrink only block volume after merge of snapshots + by reducing the new lv + """ + pass + def createVolume(parent, parent_format, volume, size, format, prealloc): """ -- To view, visit http://gerrit.ovirt.org/9725 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8ace4c48d278cb84ce871bc402643131265c3198 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Yeela Kaplan <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
