Currently, each among virStorageFileGetMetadataRecurse, qemuSecurityChownCallback, qemuDomainSnapshotPrepareDiskExternal and qemuDomainSnapshotCreateSingleDiskActive makes calls to virStorageFileInit and friends for simple operations like stat, read headers, chown and etc. This patch optimize/unify calls to virStorageFileInit and virStorageFileDeinit. Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@xxxxxxxxxx> --- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 5 +++++ src/qemu/qemu_driver.c | 40 +++++++++++++++++++++++++++---------- src/qemu/qemu_process.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_process.h | 4 ++++ src/storage/storage_driver.c | 11 ++++++++--- 6 files changed, 95 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4aae14d..43579ed 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4837,7 +4837,7 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver, priv->ncleanupCallbacks_max = 0; } -static void +void qemuDomainGetImageIds(virQEMUDriverConfigPtr cfg, virDomainObjPtr vm, virStorageSourcePtr src, diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 7650ff3..a9e38bd 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -591,6 +591,11 @@ bool qemuDomainDiskSourceDiffers(virDomainDiskDefPtr disk, bool qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk, virDomainDiskDefPtr orig_disk); +void qemuDomainGetImageIds(virQEMUDriverConfigPtr cfg, + virDomainObjPtr vm, + virStorageSourcePtr src, + uid_t *uid, gid_t *gid); + int qemuDomainStorageFileInit(virQEMUDriverPtr driver, virDomainObjPtr vm, virStorageSourcePtr src); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3517aa2..d0e05f8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -328,6 +328,7 @@ qemuSecurityChownCallback(virStorageSourcePtr src, { struct stat sb; int save_errno = 0; + bool initFlag = false; int ret = -1; if (!virStorageFileSupportsSecurityDriver(src)) @@ -351,8 +352,11 @@ qemuSecurityChownCallback(virStorageSourcePtr src, } /* storage file init reports errors, return -2 on failure */ - if (virStorageFileInit(src) < 0) - return -2; + if (!src->drv) { + if (virStorageFileInit(src) < 0) + return -2; + initFlag = true; + } if (virStorageFileChown(src, uid, gid) < 0) { save_errno = errno; @@ -362,7 +366,8 @@ qemuSecurityChownCallback(virStorageSourcePtr src, ret = 0; cleanup: - virStorageFileDeinit(src); + if (initFlag) + virStorageFileDeinit(src); errno = save_errno; return ret; @@ -13865,9 +13870,6 @@ qemuDomainSnapshotPrepareDiskExternal(virConnectPtr conn, return -1; } - if (virStorageFileInit(snapdisk->src) < 0) - return -1; - if (virStorageFileStat(snapdisk->src, &st) < 0) { if (errno != ENOENT) { virReportSystemError(errno, @@ -13891,7 +13893,6 @@ qemuDomainSnapshotPrepareDiskExternal(virConnectPtr conn, ret = 0; cleanup: - virStorageFileDeinit(snapdisk->src); return ret; } @@ -14126,6 +14127,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, const char *formatStr = NULL; int ret = -1, rc; bool need_unlink = false; + bool initFlag = false; if (snap->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -14138,12 +14140,18 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, if (!(newDiskSrc = virStorageSourceCopy(snap->src, false))) goto cleanup; + else + if (snap->src->drv) + newDiskSrc->drv = snap->src->drv; if (virStorageSourceInitChainElement(newDiskSrc, disk->src, false) < 0) goto cleanup; - if (qemuDomainStorageFileInit(driver, vm, newDiskSrc) < 0) - goto cleanup; + if (!newDiskSrc->drv) { + if (qemuDomainStorageFileInit(driver, vm, newDiskSrc) < 0) + goto cleanup; + initFlag = true; + } if (qemuGetDriveSourceString(newDiskSrc, NULL, &source) < 0) goto cleanup; @@ -14211,7 +14219,8 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, cleanup: if (need_unlink && virStorageFileUnlink(newDiskSrc)) VIR_WARN("unable to unlink just-created %s", source); - virStorageFileDeinit(newDiskSrc); + if (initFlag) + virStorageFileDeinit(newDiskSrc); virStorageSourceFree(newDiskSrc); virStorageSourceFree(persistDiskSrc); VIR_FREE(device); @@ -14566,6 +14575,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, virDomainSnapshotObjPtr snap = NULL; virDomainSnapshotPtr snapshot = NULL; virDomainSnapshotDefPtr def = NULL; + virDomainSnapshotDefPtr refDef = NULL; bool update_current = true; bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE; unsigned int parse_flags = VIR_DOMAIN_SNAPSHOT_PARSE_DISKS; @@ -14574,6 +14584,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, bool align_match = true; virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; + size_t i; virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE | VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT | @@ -14690,6 +14701,10 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE); + for (i = 0; i < def->ndisks; i++) + if (qemuStorageVolumeRegister(cfg, vm, def->disks[i].src) < 0) + goto cleanup; + if (redefine) { if (virDomainSnapshotRedefinePrep(domain, vm, &def, &snap, &update_current, flags) < 0) @@ -14800,6 +14815,11 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, snapshot = virGetDomainSnapshot(domain, snap->def->name); endjob: + refDef = (!snap) ? def : snap->def; + + for (i = 0; i < refDef->ndisks; i++) + qemuStorageVolumeUnRegister(refDef->disks[i].src); + if (snapshot && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) { if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps, cfg->snapshotDir) < 0) { diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7f19c69..c58e622 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4590,6 +4590,35 @@ qemuProcessStartValidate(virQEMUDriverPtr driver, } +int +qemuStorageVolumeRegister(virQEMUDriverConfigPtr cfg, + virDomainObjPtr vm, virStorageSourcePtr src) +{ + uid_t uid; + gid_t gid; + + if (virStorageSourceIsEmpty(src)) + return 0; + + qemuDomainGetImageIds(cfg, vm, src, &uid, &gid); + + if (virStorageFileInitAs(src, uid, gid) < 0) + return -1; + + return 0; +} + + +void +qemuStorageVolumeUnRegister(virStorageSourcePtr src) +{ + if (virStorageSourceIsEmpty(src)) + return; + + virStorageFileDeinit(src); +} + + /** * qemuProcessInit: * @@ -4614,6 +4643,7 @@ qemuProcessInit(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; int stopFlags; int ret = -1; + size_t i; VIR_DEBUG("vm=%p name=%s id=%d migration=%d", vm, vm->def->name, vm->def->id, migration); @@ -4666,6 +4696,12 @@ qemuProcessInit(virQEMUDriverPtr driver, if (qemuDomainSetPrivatePaths(driver, vm) < 0) goto cleanup; + if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) { + for (i = 0; i < vm->def->ndisks; i++) + if (qemuStorageVolumeRegister(cfg, vm, vm->def->disks[i]->src) < 0) + goto cleanup; + } + ret = 0; cleanup: @@ -5674,6 +5710,7 @@ qemuProcessFinishStartup(virConnectPtr conn, { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); int ret = -1; + size_t i; if (startCPUs) { VIR_DEBUG("Starting domain CPUs"); @@ -5698,6 +5735,9 @@ qemuProcessFinishStartup(virConnectPtr conn, VIR_HOOK_SUBOP_BEGIN) < 0) goto cleanup; + for (i = 0; i < vm->def->ndisks; i++) + qemuStorageVolumeUnRegister(vm->def->disks[i]->src); + ret = 0; cleanup: @@ -6047,6 +6087,10 @@ void qemuProcessStop(virQEMUDriverPtr driver, VIR_FREE(xml); } + for (i = 0; i < vm->def->ndisks; i++) + if (qemuStorageVolumeRegister(cfg, vm, vm->def->disks[i]->src) < 0) + goto cleanup; + /* Reset Security Labels unless caller don't want us to */ if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL)) virSecurityManagerRestoreAllLabel(driver->securityManager, @@ -6210,6 +6254,9 @@ void qemuProcessStop(virQEMUDriverPtr driver, VIR_FREE(xml); } + for (i = 0; i < vm->def->ndisks; i++) + qemuStorageVolumeUnRegister(vm->def->disks[i]->src); + virDomainObjRemoveTransientDef(vm); endjob: diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 21f3b0c..e53a154 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -90,6 +90,10 @@ virCommandPtr qemuProcessCreatePretendCmd(virConnectPtr conn, bool standalone, unsigned int flags); +int qemuStorageVolumeRegister(virQEMUDriverConfigPtr cfg, + virDomainObjPtr vm, virStorageSourcePtr src); +void qemuStorageVolumeUnRegister(virStorageSourcePtr src); + int qemuProcessInit(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuDomainAsyncJob asyncJob, diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 7c7fddd..24e2f35 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -3195,6 +3195,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src, ssize_t headerLen; virStorageSourcePtr backingStore = NULL; int backingFormat; + bool initFlag = false; VIR_DEBUG("path=%s format=%d uid=%u gid=%u probe=%d", src->path, src->format, @@ -3204,8 +3205,11 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src, if (!virStorageFileSupportsBackingChainTraversal(src)) return 0; - if (virStorageFileInitAs(src, uid, gid) < 0) - return -1; + if (!src->drv) { + if (virStorageFileInitAs(src, uid, gid) < 0) + return -1; + initFlag = true; + } if (virStorageFileAccess(src, F_OK) < 0) { if (src == parent) { @@ -3281,7 +3285,8 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src, cleanup: VIR_FREE(buf); - virStorageFileDeinit(src); + if (initFlag) + virStorageFileDeinit(src); virStorageSourceFree(backingStore); return ret; } -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list