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@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list