qemu: Make qemuDomainPrepareDiskChainElement aware of remote storage

Refactor the function to accept a virStorageSourcePtr instead of just
the path, add a check to run it only on local storage and fix callers
(possibly by using a newly introduced wrapper that wraps a path in the
 virStorageSource struct for legacy code)
This commit is contained in:
Peter Krempa 2014-05-05 10:34:16 +02:00
parent b3e99ad8d6
commit b8d6ba9bdc

View File

@ -12020,22 +12020,26 @@ static int
qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver, qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr disk, virDomainDiskDefPtr disk,
const char *file, virStorageSourcePtr elem,
qemuDomainDiskChainMode mode) qemuDomainDiskChainMode mode)
{ {
/* The easiest way to label a single file with the same /* The easiest way to label a single file with the same
* permissions it would have as if part of the disk chain is to * permissions it would have as if part of the disk chain is to
* temporarily modify the disk in place. */ * temporarily modify the disk in place. */
char *origsrc = disk->src.path; virStorageSource origdisk;
int origformat = disk->src.format;
virStorageSourcePtr origchain = disk->src.backingStore;
bool origreadonly = disk->readonly; bool origreadonly = disk->readonly;
virQEMUDriverConfigPtr cfg = NULL;
int ret = -1; int ret = -1;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
disk->src.path = (char *) file; /* casting away const is safe here */ /* XXX Labelling of non-local files isn't currently supported */
disk->src.format = VIR_STORAGE_FILE_RAW; if (virStorageSourceGetActualType(&disk->src) == VIR_STORAGE_TYPE_NETWORK)
disk->src.backingStore = NULL; return 0;
cfg = virQEMUDriverGetConfig(driver);
/* XXX This would be easier when disk->src will be a pointer */
memcpy(&origdisk, &disk->src, sizeof(origdisk));
memcpy(&disk->src, elem, sizeof(*elem));
disk->readonly = mode == VIR_DISK_CHAIN_READ_ONLY; disk->readonly = mode == VIR_DISK_CHAIN_READ_ONLY;
if (mode == VIR_DISK_CHAIN_NO_ACCESS) { if (mode == VIR_DISK_CHAIN_NO_ACCESS) {
@ -12058,9 +12062,7 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
disk->src.path = origsrc; memcpy(&disk->src, &origdisk, sizeof(origdisk));
disk->src.format = origformat;
disk->src.backingStore = origchain;
disk->readonly = origreadonly; disk->readonly = origreadonly;
virObjectUnref(cfg); virObjectUnref(cfg);
return ret; return ret;
@ -12070,6 +12072,25 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
/* Return -1 if request is not sent to agent due to misconfig, -2 if request /* Return -1 if request is not sent to agent due to misconfig, -2 if request
* is sent but failed, and number of frozen filesystems on success. If -2 is * is sent but failed, and number of frozen filesystems on success. If -2 is
* returned, FSThaw should be called revert the quiesced status. */ * returned, FSThaw should be called revert the quiesced status. */
static int
qemuDomainPrepareDiskChainElementPath(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,
const char *file,
qemuDomainDiskChainMode mode)
{
virStorageSource src;
memset(&src, 0, sizeof(src));
src.type = VIR_STORAGE_TYPE_FILE;
src.format = VIR_STORAGE_FILE_RAW;
src.path = (char *) file; /* casting away const is safe here */
return qemuDomainPrepareDiskChainElement(driver, vm, disk, &src, mode);
}
static int static int
qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver, qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
@ -12829,9 +12850,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
VIR_FORCE_CLOSE(fd); VIR_FORCE_CLOSE(fd);
} }
if (qemuDomainPrepareDiskChainElement(driver, vm, disk, source, if (qemuDomainPrepareDiskChainElement(driver, vm, disk, &snap->src,
VIR_DISK_CHAIN_READ_WRITE) < 0) { VIR_DISK_CHAIN_READ_WRITE) < 0) {
qemuDomainPrepareDiskChainElement(driver, vm, disk, source, qemuDomainPrepareDiskChainElement(driver, vm, disk, &snap->src,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
goto cleanup; goto cleanup;
} }
@ -12962,7 +12983,7 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
(persistDisk && VIR_STRDUP(persistSource, source) < 0)) (persistDisk && VIR_STRDUP(persistSource, source) < 0))
goto cleanup; goto cleanup;
qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src.path, qemuDomainPrepareDiskChainElement(driver, vm, disk, &disk->src,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
if (need_unlink && if (need_unlink &&
virStorageFileStat(&disk->src, &st) == 0 && S_ISREG(st.st_mode) && virStorageFileStat(&disk->src, &st) == 0 && S_ISREG(st.st_mode) &&
@ -15276,10 +15297,10 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
if (VIR_STRDUP(mirror, dest) < 0) if (VIR_STRDUP(mirror, dest) < 0)
goto endjob; goto endjob;
if (qemuDomainPrepareDiskChainElement(driver, vm, disk, dest, if (qemuDomainPrepareDiskChainElementPath(driver, vm, disk, dest,
VIR_DISK_CHAIN_READ_WRITE) < 0) { VIR_DISK_CHAIN_READ_WRITE) < 0) {
qemuDomainPrepareDiskChainElement(driver, vm, disk, dest, qemuDomainPrepareDiskChainElementPath(driver, vm, disk, dest,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
goto endjob; goto endjob;
} }
@ -15290,8 +15311,8 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0); virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0);
qemuDomainObjExitMonitor(driver, vm); qemuDomainObjExitMonitor(driver, vm);
if (ret < 0) { if (ret < 0) {
qemuDomainPrepareDiskChainElement(driver, vm, disk, dest, qemuDomainPrepareDiskChainElementPath(driver, vm, disk, dest,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
goto endjob; goto endjob;
} }
@ -15468,12 +15489,12 @@ qemuDomainBlockCommit(virDomainPtr dom,
* operation succeeds, but doing that requires tracking the * operation succeeds, but doing that requires tracking the
* operation in XML across libvirtd restarts. */ * operation in XML across libvirtd restarts. */
clean_access = true; clean_access = true;
if (qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource->path, if (qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource,
VIR_DISK_CHAIN_READ_WRITE) < 0 || VIR_DISK_CHAIN_READ_WRITE) < 0 ||
(top_parent && top_parent != disk->src.path && (top_parent && top_parent != disk->src.path &&
qemuDomainPrepareDiskChainElement(driver, vm, disk, qemuDomainPrepareDiskChainElementPath(driver, vm, disk,
top_parent, top_parent,
VIR_DISK_CHAIN_READ_WRITE) < 0)) VIR_DISK_CHAIN_READ_WRITE) < 0))
goto endjob; goto endjob;
/* Start the commit operation. Pass the user's original spelling, /* Start the commit operation. Pass the user's original spelling,
@ -15491,12 +15512,12 @@ qemuDomainBlockCommit(virDomainPtr dom,
endjob: endjob:
if (ret < 0 && clean_access) { if (ret < 0 && clean_access) {
/* Revert access to read-only, if possible. */ /* Revert access to read-only, if possible. */
qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource->path, qemuDomainPrepareDiskChainElement(driver, vm, disk, baseSource,
VIR_DISK_CHAIN_READ_ONLY); VIR_DISK_CHAIN_READ_ONLY);
if (top_parent && top_parent != disk->src.path) if (top_parent && top_parent != disk->src.path)
qemuDomainPrepareDiskChainElement(driver, vm, disk, qemuDomainPrepareDiskChainElementPath(driver, vm, disk,
top_parent, top_parent,
VIR_DISK_CHAIN_READ_ONLY); VIR_DISK_CHAIN_READ_ONLY);
} }
if (!qemuDomainObjEndJob(driver, vm)) if (!qemuDomainObjEndJob(driver, vm))
vm = NULL; vm = NULL;