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); + 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list