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 <[email protected]> --- 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 <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
