Hello Federico Simoncelli, Francesco Romani,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/32323
to review the following change.
Change subject: Live Merge: Extend internal block volumes during merge
......................................................................
Live Merge: Extend internal block volumes during merge
Libvirt will be exposing the high write watermark for internal volumes
directly in the domain XML. An <allocation/> element will be added to
each member of the image chain. This patch implements the missing logic
for _getMergeWriteWatermarks using this new API.
Change-Id: I3a9e0ebdb9c42df713c40e0fc5782945eb7228a8
Signed-off-by: Adam Litke <alitke(a)redhat.com>
Bug-Url:
https://bugzilla.redhat.com/show_bug.cgi?id=1109920
Reviewed-on:
http://gerrit.ovirt.org/31268
Reviewed-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/virt/vm.py
1 file changed, 34 insertions(+), 9 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/23/32323/1
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 0811723..34023bc 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -215,7 +215,8 @@
pass
-VolumeChainEntry = namedtuple('VolumeChainEntry', ['uuid',
'path'])
+VolumeChainEntry = namedtuple('VolumeChainEntry',
+ ['uuid', 'path', 'allocation'])
class VmStatsThread(sampling.AdvancedStatsThread):
@@ -2481,18 +2482,34 @@
self.conf['timeOffset'] = newTimeOffset
def _getMergeWriteWatermarks(self):
- # TODO: Adopt the future libvirt API when the following RFE is done
- #
https://bugzilla.redhat.com/show_bug.cgi?id=1041569
- return {}
+ drives = [drive for drive in self.getDiskDevices()
+ if isVdsmImage(drive) and drive.blockDev]
+ allChains = self._driveGetActualVolumeChain(drives).values()
+ return dict((entry.uuid, entry.allocation)
+ for chain in allChains
+ for entry in chain)
def _getLiveMergeExtendCandidates(self):
ret = {}
- watermarks = self._getMergeWriteWatermarks()
+
+ # The common case is that there are no active jobs.
+ if not self.conf['_blockJobs'].values():
+ return ret
+
+ try:
+ watermarks = self._getMergeWriteWatermarks()
+ except LookupError:
+ self.log.warning("Failed to look up watermark information")
+ return ret
+
for job in self.conf['_blockJobs'].values():
- if 'done' in job:
- # Skip active layer commits that are in the cleanup phase
+ try:
+ drive = self._findDriveByUUIDs(job['disk'])
+ except LookupError:
+ # After an active layer merge completes the vdsm metadata will
+ # be out of sync for a brief period. If we cannot find the old
+ # disk then it's safe to skip it.
continue
- drive = self._findDriveByUUIDs(job['disk'])
if not drive.blockDev or drive.format != 'cow':
continue
@@ -5765,13 +5782,21 @@
break
sourceAttr = ('file', 'dev')[drive.blockDev]
path = sourceXML.getAttribute(sourceAttr)
- entry = VolumeChainEntry(pathToVolID(drive, path), path)
+ alloc = None
+ if drive.blockDev:
+ allocXML = find_element_by_name(diskXML, 'allocation')
+ if not allocXML:
+ self.log.debug("<allocation/> missing from backing "
+ "chain for block device %s", drive.name)
+ break
+ alloc = int(allocXML.firstChild.nodeValue)
bsXML = find_element_by_name(diskXML, 'backingStore')
if not bsXML:
self.log.warning("<backingStore/> missing from backing "
"chain for drive %s", drive.name)
break
diskXML = bsXML
+ entry = VolumeChainEntry(pathToVolID(drive, path), path, alloc)
volChain.insert(0, entry)
return volChain or None
--
To view, visit
http://gerrit.ovirt.org/32323
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3a9e0ebdb9c42df713c40e0fc5782945eb7228a8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Adam Litke <alitke(a)redhat.com>
Gerrit-Reviewer: Federico Simoncelli <fsimonce(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)redhat.com>