Change in vdsm[master]: Live Merge: WIP: support active layer commit

alitke at redhat.com alitke at redhat.com
Wed Jun 11 13:35:52 UTC 2014


Adam Litke has uploaded a new change for review.

Change subject: Live Merge: WIP: support active layer commit
......................................................................

Live Merge: WIP: support active layer commit

Change-Id: Idab76081c2d004bc4f9e5bc9cb72e86845640f6a
Signed-off-by: Adam Litke <alitke at redhat.com>
---
M vdsm/virt/vm.py
1 file changed, 53 insertions(+), 20 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/98/28598/1

diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 865e936..be84051 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -5310,6 +5310,29 @@
             return errCode['mergeErr']
         baseSize = int(res['info']['apparentsize'])
 
+        # Indicate that we expect libvirt to maintain the relative paths of
+        # backing files.  This is necessary to ensure that a volume chain is
+        # visible from any host even if the mountpoint is different.
+        try:
+            flags = libvirt.VIR_DOMAIN_BLOCK_COMMIT_RELATIVE
+        except AttributeError:
+            self.log.error("Libvirt missing VIR_DOMAIN_BLOCK_COMMIT_RELATIVE. "
+                           "Unable to perform live merge.")
+            return errCode['mergeErr']
+
+        if topVolUUID == drive.volumeID:
+            # Pass a flag to libvirt to indicate that we expect a two phase
+            # block job.  In the first phase, data is copied to base.  Once
+            # completed, an event is raised to indicate that the job has
+            # transitioned to the second phase.  We must then tell libvirt to
+            # pivot to the new active layer (baseVolUUID).
+            try:
+                flags |= libvirt.VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
+            except AttributeError:
+                self.log.error("Unable to merge the active layer.  Libvirt is "
+                               "missing VIR_DOMAIN_BLOCK_COMMIT_ACTIVE.")
+                return errCode['mergeErr']
+
         ret = self.trackBlockJob(jobUUID, drive, baseVolUUID, topVolUUID,
                                  'commit')
         if ret is False:
@@ -5317,16 +5340,6 @@
             return errCode['mergeErr']
         self.log.debug("Starting merge with jobUUID='%s'", jobUUID)
 
-        flags = 0
-        # Indicate that we expect libvirt to maintain the relative paths of
-        # backing files.  This is necessary to ensure that a volume chain is
-        # visible from any host even if the mountpoint is different.
-        try:
-            flags |= libvirt.VIR_DOMAIN_BLOCK_COMMIT_RELATIVE
-        except AttributeError:
-            self.log.error("Libvirt missing VIR_DOMAIN_BLOCK_COMMIT_RELATIVE. "
-                           "Unable to perform live merge.")
-            return errCode['mergeErr']
         try:
             ret = self._dom.blockCommit(drive.path, base, top, bandwidth,
                                         flags)
@@ -5441,13 +5454,22 @@
                     if x['volumeID'] in volumes]
         device['volumeChain'] = drive.volumeChain = newChain
 
-    def _onBlockJobEvent(self, path, blockJobType, status):
-        if blockJobType != libvirt.VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT:
-            self.log.warning("Ignoring unrecognized block job type: '%s'",
-                             blockJobType)
-            return
+    def _onBlockJobActiveCommitEvent(self, path):
+        flags = libvirt.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
+        try:
+            self._dom.blockJobAbort(path, flags)
+        except libvirt.libvirtError:
+            self.log.error("Failed to perform pivot", exc_info=True)
 
-        self.log.debug("Live merge completed for path '%s'", path)
+    def _onBlockJobEvent(self, path, blockJobType, status):
+        def isActiveCommit(jobType):
+            try:
+                if jobType == libvirt.VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT:
+                    return True
+            except AttributeError:
+                pass
+            return False
+
         drive = self._lookupDeviceByPath(path)
         try:
             jobID = self.getBlockJob(drive)['jobID']
@@ -5456,12 +5478,23 @@
                            "'%s'", path)
             return
 
-        if status == libvirt.VIR_DOMAIN_BLOCK_JOB_COMPLETED:
-            self._syncVolumeChain(drive)
-        else:
+        if status != libvirt.VIR_DOMAIN_BLOCK_JOB_COMPLETED:
             self.log.warning("Block job '%s' did not complete successfully "
                              "(status:%i)", path, status)
-        self.untrackBlockJob(jobID)
+            self.untrackBlockJob(jobID)
+            return
+
+        if blockJobType == libvirt.VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT:
+            self.log.debug("Live merge completed for disk '%s'", path)
+            self._syncVolumeChain(drive)
+            self.untrackBlockJob(jobID)
+        elif isActiveCommit(blockJobType):
+            self.log.debug("Requesting pivot to complete active layer commit "
+                           "for disk '%s'", path)
+            self._onBlockJobActiveCommitEvent(path)
+        else:
+            self.log.warning("Received unexpected block job event %i on path "
+                             "%s", blockJobType, path)
 
     def _initLegacyConf(self):
         self.conf['displayPort'] = GraphicsDevice.LIBVIRT_PORT_AUTOSELECT


-- 
To view, visit http://gerrit.ovirt.org/28598
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idab76081c2d004bc4f9e5bc9cb72e86845640f6a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <alitke at redhat.com>


More information about the vdsm-patches mailing list