On Fri, Feb 25, 2011 at 07:04:11PM +0100, Jiri Denemark wrote: > --- > src/qemu/qemu_driver.c | 37 ++++++++++++++++++++++++++++++++----- > 1 files changed, 32 insertions(+), 5 deletions(-) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index ba046d7..a02d1b9 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -6041,21 +6041,47 @@ cleanup: > > /* The domain is expected to be locked and active. */ > static int > -qemuDomainSnapshotCreateActive(struct qemud_driver *driver, > +qemuDomainSnapshotCreateActive(virConnectPtr conn, > + struct qemud_driver *driver, > virDomainObjPtr *vmptr, > virDomainSnapshotObjPtr snap) > { > virDomainObjPtr vm = *vmptr; > qemuDomainObjPrivatePtr priv = vm->privateData; > - int ret; > + bool resume = false; > + int ret = -1; > > if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) > return -1; > > + if (vm->state == VIR_DOMAIN_RUNNING) { > + /* savevm monitor command pauses the domain emitting an event which > + * confuses libvirt since it's not notified when qemu resumes the > + * domain. Thus we stop and start CPUs ourselves. > + */ Not having a resume event from QEMU sounds like a QEMU bug, right ? > + if (qemuProcessStopCPUs(driver, vm) < 0) > + goto cleanup; > + > + resume = true; > + if (!virDomainObjIsActive(vm)) { > + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("guest unexpectedly quit")); > + goto cleanup; > + } > + } > + > qemuDomainObjEnterMonitorWithDriver(driver, vm); > ret = qemuMonitorCreateSnapshot(priv->mon, snap->def->name); > qemuDomainObjExitMonitorWithDriver(driver, vm); > > +cleanup: > + if (resume && virDomainObjIsActive(vm) && > + qemuProcessStartCPUs(driver, vm, conn) < 0 && > + virGetLastError() == NULL) { > + qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", > + _("resuming after snapshot failed")); > + } > + > if (qemuDomainObjEndJob(vm) == 0) > *vmptr = NULL; > > @@ -6100,18 +6126,19 @@ static virDomainSnapshotPtr qemuDomainSnapshotCreateXML(virDomainPtr domain, > if (!(snap = virDomainSnapshotAssignDef(&vm->snapshots, def))) > goto cleanup; > > + snap->def->state = vm->state; > + > /* actually do the snapshot */ > if (!virDomainObjIsActive(vm)) { > if (qemuDomainSnapshotCreateInactive(vm, snap) < 0) > goto cleanup; > } > else { > - if (qemuDomainSnapshotCreateActive(driver, &vm, snap) < 0) > + if (qemuDomainSnapshotCreateActive(domain->conn, driver, > + &vm, snap) < 0) > goto cleanup; > } > > - snap->def->state = vm->state; > - > /* FIXME: if we fail after this point, there's not a whole lot we can > * do; we've successfully taken the snapshot, and we are now running > * on it, so we have to go forward the best we can ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list