On 10/13/2012 06:00 PM, 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). Also, we are relying on qemu to do > error checking (such as validating 'top' and 'base' as being members > of the backing chain), including the fact that the current qemu code > does not support committing the active layer (although it is still > planned to add that before qemu 1.3). Since the active layer won't > change, we have it easy and do not have to alter the domain XML. > Additionally, this will fail if SELinux is enforcing, because we fail > to grant qemu proper read/write access to the files it will modify. > > * src/qemu/qemu_driver.c (qemuDomainBlockCommit): New function. > (qemuDriver): Register it. > --- > > Change from v1: > allow NULL top (let qemu reject it instead) > drop unused event variable > > src/qemu/qemu_driver.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 75 insertions(+) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 6588b82..a9fd93a 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -12540,6 +12540,80 @@ 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; > + 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)) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("online commit 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; > + } > + > + if (!top) > + top = disk->src; > + > + /* 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); > + return ret; > +} > + > static int > qemuDomainOpenGraphics(virDomainPtr dom, > unsigned int idx, > @@ -13882,6 +13956,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 */ ACK (with the version change you've already said you would make). -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list