
On 09/05/2014 08:09 AM, Peter Krempa wrote:
On 08/31/14 06:02, Eric Blake wrote:
In order to implement the new virDomainBlockCopy, the existing block copy internal implementation needs to be adjusted. The new function will parse XML into a storage source, and parse typed parameters into integers, then call into the same common backend. For now, it's easier to keep the same implementation limits that only local file destinations are suported, but now the check needs to be explicit.
/* bandwidth in bytes/s */ static int -qemuDomainBlockCopy(virDomainObjPtr vm, - virConnectPtr conn, - const char *path, - const char *dest, const char *format, - unsigned long long bandwidth, unsigned int flags)
You should mention that this function consumes @dest.
+qemuDomainBlockCopyCommon(virDomainObjPtr vm,
- if (VIR_ALLOC(mirror) < 0) + if (!(mirror = virStorageSourceCopy(dest, false)))
Also you won't need to copy it then.
ACK with the docs added. The tweaks of the @dest handling are not necessary.
How about the following interdiff? diff --git i/src/qemu/qemu_driver.c w/src/qemu/qemu_driver.c index 7026a18..26e0237 100644 --- i/src/qemu/qemu_driver.c +++ w/src/qemu/qemu_driver.c @@ -15349,12 +15349,13 @@ qemuDomainBlockJobSetSpeed(virDomainPtr dom, const char *path, /* bandwidth in bytes/s. Caller must lock vm beforehand, and not - * access it afterwards. */ + * access it afterwards; likewise, caller must not access mirror + * afterwards. */ static int qemuDomainBlockCopyCommon(virDomainObjPtr vm, virConnectPtr conn, const char *path, - virStorageSourcePtr dest, + virStorageSourcePtr mirror, unsigned long long bandwidth, unsigned int flags) { @@ -15366,10 +15367,9 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, int idx; struct stat st; bool need_unlink = false; - virStorageSourcePtr mirror = NULL; virQEMUDriverConfigPtr cfg = NULL; const char *format = NULL; - int desttype = virStorageSourceGetActualType(dest); + int desttype = virStorageSourceGetActualType(mirror); /* Preliminaries: find the disk we are editing, sanity checks */ virCheckFlags(VIR_DOMAIN_BLOCK_COPY_SHALLOW | @@ -15419,7 +15419,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, goto endjob; if ((flags & VIR_DOMAIN_BLOCK_COPY_SHALLOW) && - dest->format == VIR_STORAGE_FILE_RAW && + mirror->format == VIR_STORAGE_FILE_RAW && disk->src->backingStore->path) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("disk '%s' has backing file, so raw shallow copy " @@ -15430,20 +15430,20 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, /* Prepare the destination file. */ /* XXX Allow non-file mirror destinations */ - if (!virStorageSourceIsLocalStorage(dest)) { + if (!virStorageSourceIsLocalStorage(mirror)) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("non-file destination not supported yet")); } - if (stat(dest->path, &st) < 0) { + if (stat(mirror->path, &st) < 0) { if (errno != ENOENT) { virReportSystemError(errno, _("unable to stat for disk %s: %s"), - disk->dst, dest->path); + disk->dst, mirror->path); goto endjob; } else if (flags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT || desttype == VIR_STORAGE_TYPE_BLOCK) { virReportSystemError(errno, _("missing destination file for disk %s: %s"), - disk->dst, dest->path); + disk->dst, mirror->path); goto endjob; } } else if (!S_ISBLK(st.st_mode)) { @@ -15451,22 +15451,19 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("external destination file for disk %s already " "exists and is not a block device: %s"), - disk->dst, dest->path); + disk->dst, mirror->path); goto endjob; } if (desttype == VIR_STORAGE_TYPE_BLOCK) { virReportError(VIR_ERR_INVALID_ARG, _("blockdev flag requested for disk %s, but file " "'%s' is not a block device"), - disk->dst, dest->path); + disk->dst, mirror->path); goto endjob; } } - if (!(mirror = virStorageSourceCopy(dest, false))) - goto endjob; - - if (!dest->format) { + if (!mirror->format) { if (!(flags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT)) { mirror->format = disk->src->format; } else { @@ -15474,14 +15471,14 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, * can also pass the RAW flag or use XML to tell us the format. * So if we get here, we assume it is safe for us to probe the * format from the file that we will be using. */ - mirror->format = virStorageFileProbeFormat(dest->path, cfg->user, + mirror->format = virStorageFileProbeFormat(mirror->path, cfg->user, cfg->group); } } /* pre-create the image file */ if (!(flags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT)) { - int fd = qemuOpenFile(driver, vm, dest->path, + int fd = qemuOpenFile(driver, vm, mirror->path, O_WRONLY | O_TRUNC | O_CREAT, &need_unlink, NULL); if (fd < 0) @@ -15504,7 +15501,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, /* Actually start the mirroring */ qemuDomainObjEnterMonitor(driver, vm); - ret = qemuMonitorDriveMirror(priv->mon, device, dest->path, format, + ret = qemuMonitorDriveMirror(priv->mon, device, mirror->path, format, bandwidth, flags); virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0); qemuDomainObjExitMonitor(driver, vm); @@ -15525,8 +15522,8 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, vm->def->name); endjob: - if (need_unlink && unlink(dest->path)) - VIR_WARN("unable to unlink just-created %s", dest->path); + if (need_unlink && unlink(mirror->path)) + VIR_WARN("unable to unlink just-created %s", mirror->path); virStorageSourceFree(mirror); if (!qemuDomainObjEndJob(driver, vm)) vm = NULL; @@ -15603,6 +15600,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base, ret = qemuDomainBlockCopyCommon(vm, dom->conn, path, dest, bandwidth, flags); vm = NULL; + dest = NULL; cleanup: if (vm) -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org