On Thu, Oct 01, 2009 at 08:18:33PM +0200, Paolo Bonzini wrote:
In order to correctly pass the paused/unpaused state on the remote
side,
we use the newly introduced return code of qemudDomainMigratePerform.
The return code does not need to be public (it is internal to the QEMU
driver). A return code of 0 specifies the old behavior.
* src/qemu/qemu_driver.c (qemudDomainMigratePerform): Check if
the machine will have to be resumed on the destination side,
pass a return value to indicate this.
(qemudDomainMigrateFinish2): Conditionalize resumption on
the return code from qemudDomainMigratePerform.
* src/qemu/qemu_driver.h (qemuDomainMigratePerformResult): New enum.
---
src/qemu/qemu_driver.c | 14 ++++++++++----
src/qemu/qemu_driver.h | 6 ++++++
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d2429de..5811ba2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -37,6 +37,7 @@
#include <errno.h>
#include <sys/utsname.h>
#include <sys/stat.h>
+#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <paths.h>
@@ -5969,7 +5970,9 @@ cleanup:
return ret;
}
-/* Perform is the second step, and it runs on the source host. */
+/* Perform is the second step, and it runs on the source host. It
+ returns a combination of actions that should (or should not) be
+ done by MigrateFinish2, currently QEMU_MIGRATE_NO_RESUME. */
static int
qemudDomainMigratePerform (virDomainPtr dom,
const char *cookie ATTRIBUTE_UNUSED,
@@ -5983,7 +5986,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
virDomainObjPtr vm;
virDomainEventPtr event = NULL;
int ret = -1;
- int paused = 0;
+ int paused = 0, need_resume = 0;
int status;
xmlURIPtr uribits = NULL;
unsigned long long transferred, remaining, total;
@@ -6004,6 +6007,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
goto cleanup;
}
+ need_resume = (vm->state == VIR_DOMAIN_RUNNING);
if (!(flags & VIR_MIGRATE_LIVE)) {
/* Pause domain for non-live migration */
if (qemuMonitorStopCPUs(vm) < 0)
@@ -6072,7 +6076,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
virDomainRemoveInactive(&driver->domains, vm);
vm = NULL;
}
- ret = 0;
+ ret = need_resume ? 0 : QEMU_MIGRATE_NO_RESUME;
cleanup:
if (paused) {
@@ -6131,7 +6135,9 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
if (retcode >= 0) {
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
- if (!(flags & VIR_MIGRATE_PAUSED)) {
+ assert (vm->state == VIR_DOMAIN_PAUSED);
NACK ! an error in migration should not result in a dead daemon
assert/exit forbidden even in error handling paths.
+ if (!(retcode & QEMU_MIGRATE_NO_RESUME)
+ && !(flags & VIR_MIGRATE_PAUSED)) {
/* run 'cont' on the destination, which allows migration on qemu
* >= 0.10.6 to work properly. This isn't strictly necessary on
* older qemu's, but it also doesn't hurt anything there
diff --git a/src/qemu/qemu_driver.h b/src/qemu/qemu_driver.h
index 17b184f..74ec089 100644
--- a/src/qemu/qemu_driver.h
+++ b/src/qemu/qemu_driver.h
@@ -47,6 +47,12 @@
# define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */
#endif
+/* Flags passed from virDomainMigratePerform to virDomainMigrateFinish. */
+
+typedef enum {
+ QEMU_MIGRATE_NO_RESUME = 1 /* destination domain should stay paused */
+} qemuDomainMigratePerformResult;
+
int qemuRegister(void);
#endif /* QEMUD_DRIVER_H */
--
1.6.2.5
--
Libvir-list mailing list
Libvir-list(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
--
Daniel Veillard | libxml Gnome XML XSLT toolkit
http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine
http://rpmfind.net/
http://veillard.com/ | virtualization library
http://libvirt.org/