[libvirt] [PATCH v3 2/3] storage: optimize calls to virStorageFileInit and friends

Prasanna Kumar Kalever prasanna.kalever at redhat.com
Mon Dec 5 13:25:18 UTC 2016


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 at redhat.com>
---
 src/qemu/qemu_domain.c       |  2 +-
 src/qemu/qemu_domain.h       |  5 +++++
 src/qemu/qemu_driver.c       | 40 +++++++++++++++++++++++++++++----------
 src/qemu/qemu_process.c      | 45 ++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_process.h      |  4 ++++
 src/storage/storage_driver.c | 11 ++++++++---
 6 files changed, 93 insertions(+), 14 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 47332a8..35914c5 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..ea76933 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 (virStorageVolumeRegister(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++)
+        virStorageVolumeUnRegister(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 ecd7ded..e949fc8 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4588,6 +4588,35 @@ qemuProcessStartValidate(virQEMUDriverPtr driver,
 }
 
 
+int
+virStorageVolumeRegister(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
+virStorageVolumeUnRegister(virStorageSourcePtr src)
+{
+        if (virStorageSourceIsEmpty(src))
+            return;
+
+        virStorageFileDeinit(src);
+}
+
+
 /**
  * qemuProcessInit:
  *
@@ -4612,6 +4641,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);
@@ -4664,6 +4694,10 @@ qemuProcessInit(virQEMUDriverPtr driver,
     if (qemuDomainSetPrivatePaths(driver, vm) < 0)
         goto cleanup;
 
+    for (i = 0; i < vm->def->ndisks; i++)
+        if (virStorageVolumeRegister(cfg, vm, vm->def->disks[i]->src) < 0)
+            goto cleanup;
+
     ret = 0;
 
  cleanup:
@@ -5671,6 +5705,7 @@ qemuProcessFinishStartup(virConnectPtr conn,
 {
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     int ret = -1;
+    size_t i;
 
     if (startCPUs) {
         VIR_DEBUG("Starting domain CPUs");
@@ -5695,6 +5730,9 @@ qemuProcessFinishStartup(virConnectPtr conn,
                              VIR_HOOK_SUBOP_BEGIN) < 0)
         goto cleanup;
 
+    for (i = 0; i < vm->def->ndisks; i++)
+        virStorageVolumeUnRegister(vm->def->disks[i]->src);
+
     ret = 0;
 
  cleanup:
@@ -6044,6 +6082,10 @@ void qemuProcessStop(virQEMUDriverPtr driver,
         VIR_FREE(xml);
     }
 
+    for (i = 0; i < vm->def->ndisks; i++)
+        if (virStorageVolumeRegister(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,
@@ -6207,6 +6249,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
         VIR_FREE(xml);
     }
 
+    for (i = 0; i < vm->def->ndisks; i++)
+        virStorageVolumeUnRegister(vm->def->disks[i]->src);
+
     virDomainObjRemoveTransientDef(vm);
 
  endjob:
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 21f3b0c..14f6ea0 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 virStorageVolumeRegister(virQEMUDriverConfigPtr cfg,
+                             virDomainObjPtr vm, virStorageSourcePtr src);
+void virStorageVolumeUnRegister(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 52099a2..bf7c938 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




More information about the libvir-list mailing list