On 07/29/2014 07:06 AM, Peter Krempa wrote:
On 07/29/14 06:20, Eric Blake wrote:
> With this in place, I can (finally!) now do:
>
> virsh blockcommit $dom vda --shallow --verbose --pivot
>
> and watch qemu shorten the backing chain by one, followed by
> libvirt automatically updating the dumpxml output, effectively
> undoing the work of virsh snapshot-commit --no-metadata --disk-only.
> Commit is SOOOO much faster than blockpull, when I'm still fairly
> close in time to when the temporary qcow2 wrapper file was created
> via a snapshot operation!
>
> * src/qemu/qemu_driver.c (qemuDomainBlockCommit): Implement live
> commit.
>
> Signed-off-by: Eric Blake <eblake(a)redhat.com>
> ---
> src/qemu/qemu_driver.c | 36 ++++++++++++++++++++++++++++++++----
> 1 file changed, 32 insertions(+), 4 deletions(-)
>
ACK,
didn't change from my previous commit much.
Alas, it needs to change - now that I'm more careful about using the
qemu events to react to state changes, I have to be prepared for a qemu
event that occurs prior to regaining lock in the main code. I'll post a
v6, but here's the interdiff:
diff --git i/src/qemu/qemu_driver.c w/src/qemu/qemu_driver.c
index 6a649e5..c619fbb 100644
--- i/src/qemu/qemu_driver.c
+++ w/src/qemu/qemu_driver.c
@@ -15673,23 +15673,31 @@ qemuDomainBlockCommit(virDomainPtr dom,
* if any, through to qemu, since qemu may behave differently
* depending on whether the input was specified as relative or
* absolute (that is, our absolute top_canon may do the wrong
- * thing if the user specified a relative name). */
+ * thing if the user specified a relative name). Be prepared for
+ * a ready event to occur while locks are dropped. */
+ if (mirror) {
+ disk->mirror = mirror;
+ disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT;
+ }
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorBlockCommit(priv->mon, device,
topPath, basePath, backingPath,
bandwidth);
qemuDomainObjExitMonitor(driver, vm);
- if (ret == 0 && mirror) {
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ if (mirror) {
+ if (ret == 0) {
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- disk->mirror = mirror;
- mirror = NULL;
- disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT;
- if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
- VIR_WARN("Unable to save status on vm %s after block job",
- vm->def->name);
- virObjectUnref(cfg);
+ mirror = NULL;
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
+ VIR_WARN("Unable to save status on vm %s after block job",
+ vm->def->name);
+ virObjectUnref(cfg);
+ } else {
+ disk->mirror = NULL;
+ disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
+ }
}
endjob:
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org