virStorageSourceFree(def->src);
VIR_FREE(def->serial);
VIR_FREE(def->dst);
- VIR_FREE(def->mirror);
+ virStorageSourceFree(def->mirror);
VIR_FREE(def->wwn);
VIR_FREE(def->vendor);
VIR_FREE(def->product);
char *ioeventfd = NULL;
char *event_idx = NULL;
char *copy_on_read = NULL;
- char *mirror = NULL;
- char *mirrorFormat = NULL;
- bool mirroring = false;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
event_idx = virXMLPropString(cur, "event_idx");
copy_on_read = virXMLPropString(cur, "copy_on_read");
discard = virXMLPropString(cur, "discard");
- } else if (!mirror && xmlStrEqual(cur->name, BAD_CAST "mirror") &&
+ } else if (!def->mirror &&
+ xmlStrEqual(cur->name, BAD_CAST "mirror") &&
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
char *ready;
- mirror = virXMLPropString(cur, "file");
- if (!mirror) {
+ char *mirrorFormat;
+
+ if (VIR_ALLOC(def->mirror) < 0)
+ goto error;
+ def->mirror->type = VIR_STORAGE_TYPE_FILE;
+ def->mirror->path = virXMLPropString(cur, "file");
+ if (!def->mirror->path) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("mirror requires file name"));
goto error;
}
mirrorFormat = virXMLPropString(cur, "format");
+ if (mirrorFormat) {
+ def->mirror->format =
+ virStorageFileFormatTypeFromString(mirrorFormat);
+ if (def->mirror->format <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown mirror format value '%s'"),
+ mirrorFormat);
+ VIR_FREE(mirrorFormat);
+ goto error;
+ }
+ VIR_FREE(mirrorFormat);
+ }
ready = virXMLPropString(cur, "ready");
if (ready) {
- mirroring = true;
+ def->mirroring = true;
VIR_FREE(ready);
}
} else if (xmlStrEqual(cur->name, BAD_CAST "auth")) {
authUsername = NULL;
def->src->driverName = driverName;
driverName = NULL;
- def->mirror = mirror;
- mirror = NULL;
- def->mirroring = mirroring;
def->src->encryption = encryption;
encryption = NULL;
def->serial = serial;
}
}
- if (mirrorFormat) {
- def->mirrorFormat = virStorageFileFormatTypeFromString(mirrorFormat);
- if (def->mirrorFormat <= 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unknown mirror format value '%s'"),
- driverType);
- goto error;
- }
- }
-
if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&& virDomainDiskDefAssignAddress(xmlopt, def) < 0)
goto error;
VIR_FREE(authUsage);
VIR_FREE(driverType);
VIR_FREE(driverName);
- VIR_FREE(mirror);
- VIR_FREE(mirrorFormat);
VIR_FREE(cachetag);
VIR_FREE(error_policy);
VIR_FREE(rerror_policy);
* for live domains, therefore we ignore it on input except for
* the internal parse on libvirtd restart. */
if (def->mirror && !(flags & VIR_DOMAIN_XML_INACTIVE)) {
- virBufferEscapeString(buf, "<mirror file='%s'", def->mirror);
- if (def->mirrorFormat)
+ virBufferEscapeString(buf, "<mirror file='%s'", def->mirror->path);
+ if (def->mirror->format)
virBufferAsprintf(buf, " format='%s'",
- virStorageFileFormatTypeToString(def->mirrorFormat));
+ virStorageFileFormatTypeToString(def->mirror->format));
if (def->mirroring)
virBufferAddLit(buf, " ready='yes'");
virBufferAddLit(buf, "/>\n");
int ret = -1, rc;
qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainBlockJobInfo info;
- const char *format = virStorageFileFormatTypeToString(disk->mirrorFormat);
+ const char *format = NULL;
bool resume = false;
char *oldsrc = NULL;
int oldformat;
virStorageSourcePtr oldchain = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ if (!disk->mirror) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("pivot of disk '%s' requires an active copy job"),
+ disk->dst);
+ goto cleanup;
+ }
+
+ format = virStorageFileFormatTypeToString(disk->mirror->format);
+
/* Probe the status, if needed. */
if (!disk->mirroring) {
qemuDomainObjEnterMonitor(driver, vm);
oldsrc = disk->src->path;
oldformat = disk->src->format;
oldchain = disk->src->backingStore;
- disk->src->path = disk->mirror;
- disk->src->format = disk->mirrorFormat;
+ disk->src->path = disk->mirror->path;
+ disk->src->format = disk->mirror->format;
disk->src->backingStore = NULL;
if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0) {
disk->src->path = oldsrc;
disk->src->backingStore = oldchain;
goto cleanup;
}
- if (disk->mirrorFormat && disk->mirrorFormat != VIR_STORAGE_FILE_RAW &&
+ if (disk->mirror->format && disk->mirror->format != VIR_STORAGE_FILE_RAW &&
(virDomainLockDiskAttach(driver->lockManager, cfg->uri,
vm, disk) < 0 ||
qemuSetupDiskCgroup(vm, disk) < 0 ||
/* Attempt the pivot. */
qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorDrivePivot(priv->mon, device, disk->mirror, format);
+ ret = qemuMonitorDrivePivot(priv->mon, device, disk->mirror->path, format);
qemuDomainObjExitMonitor(driver, vm);
if (ret == 0) {
* for now, we leak the access to the original. */
VIR_FREE(oldsrc);
virStorageSourceFree(oldchain);
- disk->mirror = NULL;
+ disk->mirror->path = NULL;
} else {
/* On failure, qemu abandons the mirror, and reverts back to
* the source disk (RHEL 6.3 has a bug where the revert could
disk->src->format = oldformat;
virStorageSourceFree(disk->src->backingStore);
disk->src->backingStore = oldchain;
- VIR_FREE(disk->mirror);
}
- disk->mirrorFormat = VIR_STORAGE_FILE_NONE;
+ virStorageSourceFree(disk->mirror);
+ disk->mirror = NULL;
disk->mirroring = false;
cleanup:
if (mode == BLOCK_JOB_ABORT && disk->mirror) {
/* XXX We should also revoke security labels and disk lease on
* the mirror, and audit that fact, before dropping things. */
- VIR_FREE(disk->mirror);
- disk->mirrorFormat = VIR_STORAGE_FILE_NONE;
+ virStorageSourceFree(disk->mirror);
+ disk->mirror = NULL;
disk->mirroring = false;
}
int idx;
struct stat st;
bool need_unlink = false;
- char *mirror = NULL;
+ virStorageSourcePtr mirror = NULL;
virQEMUDriverConfigPtr cfg = NULL;
/* Preliminaries: find the disk we are editing, sanity checks */
goto endjob;
}
+ if (VIR_ALLOC(mirror) < 0)
+ goto endjob;
+ /* XXX Allow non-file mirror destinations */
+ mirror->type = VIR_STORAGE_TYPE_FILE;
+
if (!(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)) {
int fd = qemuOpenFile(driver, vm, dest, O_WRONLY | O_TRUNC | O_CREAT,
&need_unlink, NULL);
goto endjob;
VIR_FORCE_CLOSE(fd);
if (!format)
- disk->mirrorFormat = disk->src->format;
+ mirror->format = disk->src->format;
} else if (format) {
- disk->mirrorFormat = virStorageFileFormatTypeFromString(format);
- if (disk->mirrorFormat <= 0) {
+ mirror->format = virStorageFileFormatTypeFromString(format);
+ if (mirror->format <= 0) {
virReportError(VIR_ERR_INVALID_ARG, _("unrecognized format '%s'"),
format);
goto endjob;
* also passed the RAW flag (and format is non-NULL), or it is
* safe for us to probe the format from the file that we will
* be using. */
- disk->mirrorFormat = virStorageFileProbeFormat(dest, cfg->user,
- cfg->group);
+ mirror->format = virStorageFileProbeFormat(dest, cfg->user,
+ cfg->group);
}
- if (!format && disk->mirrorFormat > 0)
- format = virStorageFileFormatTypeToString(disk->mirrorFormat);
- if (VIR_STRDUP(mirror, dest) < 0)
+ if (!format && mirror->format > 0)
+ format = virStorageFileFormatTypeToString(mirror->format);
+ if (VIR_STRDUP(mirror->path, dest) < 0)
goto endjob;
if (qemuDomainPrepareDiskChainElementPath(driver, vm, disk, dest,
endjob:
if (need_unlink && unlink(dest))
VIR_WARN("unable to unlink just-created %s", dest);
- if (ret < 0 && disk)
- disk->mirrorFormat = VIR_STORAGE_FILE_NONE;
- VIR_FREE(mirror);
+ if (ret < 0 && disk) {
+ virStorageSourceFree(disk->mirror);
+ disk->mirror = NULL;
+ }
+ virStorageSourceFree(mirror);
if (!qemuDomainObjEndJob(driver, vm))
vm = NULL;