Change in vdsm[ovirt-3.5]: Live Merge: Extend internal block volumes during merge

alitke at redhat.com alitke at redhat.com
Tue Sep 2 17:20:43 UTC 2014


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 at 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 at redhat.com>
Reviewed-by: Federico Simoncelli <fsimonce at 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 at redhat.com>
Gerrit-Reviewer: Federico Simoncelli <fsimonce at redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani at redhat.com>


More information about the vdsm-patches mailing list