On 04.10.2012 16:44, Eric Blake wrote: > This is the bare minimum to kick off a block commit. In particular, > flags support is missing (shallow requires us to crawl the backing > chain to determine the file name to pass to the qemu monitor command; > delete requires us to track what needs to be deleted at the time > the completion event fires), and top must be non-NULL (matching the > fact that the current qemu code does not support committing the > active layer, although it is still planned to add that before 1.3). > Since the active layer won't change, we have it easy and do not have > to alter the domain XML. We are also relying on qemu to do some > error detection on our behalf (such as validating 'top' and 'base' > as being members of the backing chain). Additionally, this will > fail if SELinux is enforcing, because we fail to grant qemu proper > read/write access to the files it will be modifying. > > * src/qemu/qemu_driver.c (qemuDomainBlockCommit): New function. > (qemuDriver): Register it. > --- > src/qemu/qemu_driver.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 79 insertions(+) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index fddb446..137df7e 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -12529,6 +12529,84 @@ qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth, > return qemuDomainBlockRebase(dom, path, NULL, bandwidth, flags); > } > > + > +static int > +qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base, > + const char *top, unsigned long bandwidth, > + unsigned int flags) > +{ > + struct qemud_driver *driver = dom->conn->privateData; > + qemuDomainObjPrivatePtr priv; > + virDomainObjPtr vm = NULL; > + char *device = NULL; > + int ret = -1; > + virDomainEventPtr event = NULL; Not used yet. But since this is a stub only it doesn't really matter. > + int idx; > + virDomainDiskDefPtr disk; > + > + virCheckFlags(0, -1); > + > + if (!(vm = qemuDomObjFromDomain(dom))) > + goto cleanup; > + priv = vm->privateData; > + > + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) > + goto cleanup; > + > + if (!virDomainObjIsActive(vm)) { > + virReportError(VIR_ERR_OPERATION_INVALID, > + "%s", _("domain is not running")); > + goto endjob; > + } > + if (!qemuCapsGet(priv->caps, QEMU_CAPS_BLOCK_COMMIT) || !top) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("online commit of active image not supported with " > + "this QEMU binary")); > + goto endjob; > + } > + > + device = qemuDiskPathToAlias(vm, path, &idx); > + if (!device) > + goto endjob; > + disk = vm->def->disks[idx]; > + > + if (!disk->src) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("disk %s has no source file to be committed"), > + disk->dst); > + goto endjob; > + } > + > + /* XXX For now, we are relying on qemu to check that 'top' and > + * 'base' resolve to members of the backing chain in correct > + * order; but if we ever get more paranoid and track the backing > + * chain ourself, we should be pre-validating the data rather than > + * relying on qemu. For that matter, we need to be changing the > + * SELinux label on both 'base' and the parent of 'top', so that > + * qemu can open(O_RDWR) those files for the duration of the > + * commit. */ > + qemuDomainObjEnterMonitor(driver, vm); > + ret = qemuMonitorBlockCommit(priv->mon, device, top, base, bandwidth); > + qemuDomainObjExitMonitor(driver, vm); > + > +endjob: > + if (qemuDomainObjEndJob(driver, vm) == 0) { > + vm = NULL; > + goto cleanup; > + } > + > +cleanup: > + VIR_FREE(device); > + if (vm) > + virDomainObjUnlock(vm); > + if (event) { > + qemuDriverLock(driver); > + qemuDomainEventQueue(driver, event); > + qemuDriverUnlock(driver); > + } > + return ret; > +} > + > static int > qemuDomainOpenGraphics(virDomainPtr dom, > unsigned int idx, > @@ -13871,6 +13949,7 @@ static virDriver qemuDriver = { > .domainBlockJobSetSpeed = qemuDomainBlockJobSetSpeed, /* 0.9.4 */ > .domainBlockPull = qemuDomainBlockPull, /* 0.9.4 */ > .domainBlockRebase = qemuDomainBlockRebase, /* 0.9.10 */ > + .domainBlockCommit = qemuDomainBlockCommit, /* 0.10.3 */ > .isAlive = qemuIsAlive, /* 0.9.8 */ > .nodeSuspendForDuration = nodeSuspendForDuration, /* 0.9.8 */ > .domainSetBlockIoTune = qemuDomainSetBlockIoTune, /* 0.9.8 */ > Looks good. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list