Milan Zamazal has uploaded a new change for review.
Change subject: virt: Start all VM related stuff after switching to post-copy migration ......................................................................
virt: Start all VM related stuff after switching to post-copy migration
On the migration destination, we perform running-VM actions only after the migration completes. But when the migration switches to post-copy mode, the VM starts fully running on the destination. So switching to post-copy should be considered as the actual start of the VM and appropriate actions should be performed.
This patch implements unblocking the start up actions after switching to post-copy mode.
The only exception is VM status, which must still signal migration until the migration completes.
Change-Id: Ic8b17e58f63cbd9db09e4420871a562eaa0b3f3d Signed-off-by: Milan Zamazal mzamazal@redhat.com Bug-Url: https://bugzilla.redhat.com/1354343 --- M vdsm/virt/vm.py 1 file changed, 25 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/51/63551/8
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py index e24a90a..ed60354 100644 --- a/vdsm/virt/vm.py +++ b/vdsm/virt/vm.py @@ -264,6 +264,7 @@ self._migrationSourceThread = migration.SourceThread(self) self._kvmEnable = self.conf.get('kvmEnable', 'true') self._incomingMigrationFinished = threading.Event() + self._incoming_migration_vm_running = threading.Event() self.id = self.conf['vmId'] self._volPrepareLock = threading.Lock() self._initTimePauseCode = None @@ -540,6 +541,11 @@ if ('migrationDest' in self.conf or 'restoreState' in self.conf) \ and self.lastStatus != vmstatus.DOWN: self._completeIncomingMigration() + if self.lastStatus == vmstatus.MIGRATION_DESTINATION: + # Waiting for post-copy migration to finish before we can + # change status to UP. + # Should we set a timeout here? + self._incomingMigrationFinished.wait()
self.lastStatus = vmstatus.UP if self._initTimePauseCode: @@ -2921,7 +2927,8 @@ if self._needToWaitForMigrationToComplete(): usedTimeout = self._waitForUnderlyingMigration() self._attachLibvirtDomainAfterMigration( - self._incomingMigrationFinished.isSet(), usedTimeout) + self._incoming_migration_vm_running.is_set(), + usedTimeout) # else domain connection already established earlier self._domDependentInit() del self.conf['migrationDest'] @@ -2973,7 +2980,7 @@ def _waitForUnderlyingMigration(self): timeout = config.getint('vars', 'migration_destination_timeout') self.log.debug("Waiting %s seconds for end of migration", timeout) - self._incomingMigrationFinished.wait(timeout) + self._incoming_migration_vm_running.wait(timeout) return timeout
def _attachLibvirtDomainAfterMigration(self, migrationFinished, timeout): @@ -2991,7 +2998,7 @@ raise MigrationError("Migration Error - Timed out " "(did not receive success " "event)") - self.log.debug("NOTE: incomingMigrationFinished event has " + self.log.debug("NOTE: incoming_migration_vm_running event has " "not been set and wait timed out after %d " "seconds. Current VM state: %d, reason %d. " "Continuing with VM initialization anyway.", @@ -3920,7 +3927,7 @@ self.log.info('Release VM resources') self.lastStatus = vmstatus.POWERING_DOWN # Terminate the VM's creation thread. - self._incomingMigrationFinished.set() + self._incoming_migration_vm_running.set() self.guestAgent.stop() if self._dom.connected: result = self._destroyVm(gracefulAttempts) @@ -4155,6 +4162,8 @@ pass else: hooks.after_vm_pause(domxml, self.conf) + elif detail == libvirt.VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED: + pass # will be handled in a followup patch
elif event == libvirt.VIR_DOMAIN_EVENT_RESUMED: self._setGuestCpuRunning(True) @@ -4171,9 +4180,19 @@ pass else: hooks.after_vm_cont(domxml, self.conf) - elif (detail == libvirt.VIR_DOMAIN_EVENT_RESUMED_MIGRATED and - self.lastStatus == vmstatus.MIGRATION_DESTINATION): + elif (self.lastStatus == vmstatus.MIGRATION_DESTINATION and + detail == libvirt.VIR_DOMAIN_EVENT_RESUMED_MIGRATED): + self._incoming_migration_vm_running.set() self._incomingMigrationFinished.set() + elif (self.lastStatus == vmstatus.MIGRATION_DESTINATION and + detail == libvirt.VIR_DOMAIN_EVENT_RESUMED_POSTCOPY): + # When we enter post-copy mode, the VM starts actually + # running on the destination, so we should unblock the + # start up processing here. The only exception is status, + # which must still signal incoming migration to not confuse + # Engine. + self._incoming_migration_vm_running.set() + self.log.info("Migration switched to post-copy mode")
def _updateDevicesDomxmlCache(self, xml): """