[libvirt] [PATCH v1 2/5] qemu: Split qemuDomainGetBlockInfo

Michal Privoznik mprivozn at redhat.com
Thu Nov 27 13:55:46 UTC 2014


Again, this is a pure code movement. The function internals are
going to be needed later when determining the disk capacity.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_domain.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h |   6 ++
 src/qemu/qemu_driver.c | 160 +--------------------------------------------
 3 files changed, 179 insertions(+), 159 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e500fb3..0484df5 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2957,3 +2957,175 @@ qemuOpenFileAs(uid_t fallback_uid, gid_t fallback_gid,
                          path);
     goto cleanup;
 }
+
+
+int
+qemuDomainGetBlockInfoImpl(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virDomainDiskDefPtr disk,
+                           virDomainBlockInfoPtr info,
+                           const char *path)
+{
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    int ret = -1;
+    int fd = -1;
+    struct stat sb;
+    ssize_t len;
+    char *buf = NULL;
+    int format;
+    virStorageSourcePtr meta = NULL;
+    off_t end;
+    char *alias = NULL;
+    bool activeFail = false;
+
+    if (virStorageSourceIsLocalStorage(disk->src)) {
+        if (!disk->src->path) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("disk '%s' does not currently have a source assigned"),
+                           path);
+            goto cleanup;
+        }
+
+        if ((fd = qemuOpenFile(driver, vm, disk->src->path, O_RDONLY,
+                               NULL, NULL)) == -1)
+            goto cleanup;
+
+        if (fstat(fd, &sb) < 0) {
+            virReportSystemError(errno,
+                                 _("cannot stat file '%s'"), disk->src->path);
+            goto cleanup;
+        }
+
+        if ((len = virFileReadHeaderFD(fd, VIR_STORAGE_MAX_HEADER, &buf)) < 0) {
+            virReportSystemError(errno, _("cannot read header '%s'"),
+                                 disk->src->path);
+            goto cleanup;
+        }
+    } else {
+        if (virStorageFileInitAs(disk->src, cfg->user, cfg->group) < 0)
+            goto cleanup;
+
+        if ((len = virStorageFileReadHeader(disk->src, VIR_STORAGE_MAX_HEADER,
+                                            &buf)) < 0)
+            goto cleanup;
+
+        if (virStorageFileStat(disk->src, &sb) < 0) {
+            virReportSystemError(errno, _("failed to stat remote file '%s'"),
+                                 NULLSTR(disk->src->path));
+            goto cleanup;
+        }
+    }
+
+    /* Probe for magic formats */
+    if (virDomainDiskGetFormat(disk)) {
+        format = virDomainDiskGetFormat(disk);
+    } else {
+        if (!cfg->allowDiskFormatProbing) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("no disk format for %s and probing is disabled"),
+                           path);
+            goto cleanup;
+        }
+
+        if ((format = virStorageFileProbeFormatFromBuf(disk->src->path,
+                                                       buf, len)) < 0)
+            goto cleanup;
+    }
+
+    if (!(meta = virStorageFileGetMetadataFromBuf(disk->src->path, buf, len,
+                                                  format, NULL)))
+        goto cleanup;
+
+    /* Get info for normal formats */
+    if (S_ISREG(sb.st_mode) || fd == -1) {
+#ifndef WIN32
+        info->physical = (unsigned long long)sb.st_blocks *
+            (unsigned long long)DEV_BSIZE;
+#else
+        info->physical = sb.st_size;
+#endif
+        /* Regular files may be sparse, so logical size (capacity) is not same
+         * as actual physical above
+         */
+        info->capacity = sb.st_size;
+    } else {
+        /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
+         * be 64 bits on all platforms.
+         */
+        end = lseek(fd, 0, SEEK_END);
+        if (end == (off_t)-1) {
+            virReportSystemError(errno,
+                                 _("failed to seek to end of %s"), path);
+            goto cleanup;
+        }
+        info->physical = end;
+        info->capacity = end;
+    }
+
+    /* If the file we probed has a capacity set, then override
+     * what we calculated from file/block extents */
+    if (meta->capacity)
+        info->capacity = meta->capacity;
+
+    /* Set default value .. */
+    info->allocation = info->physical;
+
+    /* ..but if guest is not using raw disk format and on a block device,
+     * then query highest allocated extent from QEMU
+     */
+    if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_BLOCK &&
+        format != VIR_STORAGE_FILE_RAW &&
+        S_ISBLK(sb.st_mode)) {
+        qemuDomainObjPrivatePtr priv = vm->privateData;
+
+        /* If the guest is not running, then success/failure return
+         * depends on whether domain is persistent
+         */
+        if (!virDomainObjIsActive(vm)) {
+            activeFail = true;
+            ret = 0;
+            goto cleanup;
+        }
+
+        if (VIR_STRDUP(alias, disk->info.alias) < 0)
+            goto cleanup;
+
+        if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+            goto cleanup;
+
+        if (virDomainObjIsActive(vm)) {
+            qemuDomainObjEnterMonitor(driver, vm);
+            ret = qemuMonitorGetBlockExtent(priv->mon,
+                                            alias,
+                                            &info->allocation);
+            qemuDomainObjExitMonitor(driver, vm);
+        } else {
+            activeFail = true;
+            ret = 0;
+        }
+
+        if (!qemuDomainObjEndJob(driver, vm))
+            vm = NULL;
+    } else {
+        ret = 0;
+    }
+
+ cleanup:
+    VIR_FREE(buf);
+    VIR_FREE(alias);
+    virStorageSourceFree(meta);
+    VIR_FORCE_CLOSE(fd);
+    if (disk)
+        virStorageFileDeinit(disk->src);
+
+    /* If we failed to get data from a domain because it's inactive and
+     * it's not a persistent domain, then force failure.
+     */
+    if (activeFail && vm && !vm->persistent) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("domain is not running"));
+        ret = -1;
+    }
+    virObjectUnref(cfg);
+    return ret;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 5f36892..d3377c5 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -424,4 +424,10 @@ int qemuOpenFileAs(uid_t fallback_uid, gid_t fallback_gid,
                    const char *path, int oflags,
                    bool *needUnlink, bool *bypassSecurityDriver);
 
+int
+qemuDomainGetBlockInfoImpl(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virDomainDiskDefPtr disk,
+                           virDomainBlockInfoPtr info,
+                           const char *path);
 #endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 561fa6c..71b7e81 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10833,26 +10833,14 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
-    int fd = -1;
-    off_t end;
-    virStorageSourcePtr meta = NULL;
     virDomainDiskDefPtr disk = NULL;
-    struct stat sb;
     int idx;
-    int format;
-    bool activeFail = false;
-    virQEMUDriverConfigPtr cfg = NULL;
-    char *alias = NULL;
-    char *buf = NULL;
-    ssize_t len;
 
     virCheckFlags(0, -1);
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         return -1;
 
-    cfg = virQEMUDriverGetConfig(driver);
-
     if (virDomainGetBlockInfoEnsureACL(dom->conn, vm->def) < 0)
         goto cleanup;
 
@@ -10870,156 +10858,10 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
 
     disk = vm->def->disks[idx];
 
-    if (virStorageSourceIsLocalStorage(disk->src)) {
-        if (!disk->src->path) {
-            virReportError(VIR_ERR_INVALID_ARG,
-                           _("disk '%s' does not currently have a source assigned"),
-                           path);
-            goto cleanup;
-        }
-
-        if ((fd = qemuOpenFile(driver, vm, disk->src->path, O_RDONLY,
-                               NULL, NULL)) == -1)
-            goto cleanup;
-
-        if (fstat(fd, &sb) < 0) {
-            virReportSystemError(errno,
-                                 _("cannot stat file '%s'"), disk->src->path);
-            goto cleanup;
-        }
-
-        if ((len = virFileReadHeaderFD(fd, VIR_STORAGE_MAX_HEADER, &buf)) < 0) {
-            virReportSystemError(errno, _("cannot read header '%s'"),
-                                 disk->src->path);
-            goto cleanup;
-        }
-    } else {
-        if (virStorageFileInitAs(disk->src, cfg->user, cfg->group) < 0)
-            goto cleanup;
-
-        if ((len = virStorageFileReadHeader(disk->src, VIR_STORAGE_MAX_HEADER,
-                                            &buf)) < 0)
-            goto cleanup;
-
-        if (virStorageFileStat(disk->src, &sb) < 0) {
-            virReportSystemError(errno, _("failed to stat remote file '%s'"),
-                                 NULLSTR(disk->src->path));
-            goto cleanup;
-        }
-    }
-
-    /* Probe for magic formats */
-    if (virDomainDiskGetFormat(disk)) {
-        format = virDomainDiskGetFormat(disk);
-    } else {
-        if (!cfg->allowDiskFormatProbing) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("no disk format for %s and probing is disabled"),
-                           path);
-            goto cleanup;
-        }
-
-        if ((format = virStorageFileProbeFormatFromBuf(disk->src->path,
-                                                       buf, len)) < 0)
-            goto cleanup;
-    }
-
-    if (!(meta = virStorageFileGetMetadataFromBuf(disk->src->path, buf, len,
-                                                  format, NULL)))
-        goto cleanup;
-
-    /* Get info for normal formats */
-    if (S_ISREG(sb.st_mode) || fd == -1) {
-#ifndef WIN32
-        info->physical = (unsigned long long)sb.st_blocks *
-            (unsigned long long)DEV_BSIZE;
-#else
-        info->physical = sb.st_size;
-#endif
-        /* Regular files may be sparse, so logical size (capacity) is not same
-         * as actual physical above
-         */
-        info->capacity = sb.st_size;
-    } else {
-        /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
-         * be 64 bits on all platforms.
-         */
-        end = lseek(fd, 0, SEEK_END);
-        if (end == (off_t)-1) {
-            virReportSystemError(errno,
-                                 _("failed to seek to end of %s"), path);
-            goto cleanup;
-        }
-        info->physical = end;
-        info->capacity = end;
-    }
-
-    /* If the file we probed has a capacity set, then override
-     * what we calculated from file/block extents */
-    if (meta->capacity)
-        info->capacity = meta->capacity;
-
-    /* Set default value .. */
-    info->allocation = info->physical;
-
-    /* ..but if guest is not using raw disk format and on a block device,
-     * then query highest allocated extent from QEMU
-     */
-    if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_BLOCK &&
-        format != VIR_STORAGE_FILE_RAW &&
-        S_ISBLK(sb.st_mode)) {
-        qemuDomainObjPrivatePtr priv = vm->privateData;
-
-        /* If the guest is not running, then success/failure return
-         * depends on whether domain is persistent
-         */
-        if (!virDomainObjIsActive(vm)) {
-            activeFail = true;
-            ret = 0;
-            goto cleanup;
-        }
-
-        if (VIR_STRDUP(alias, disk->info.alias) < 0)
-            goto cleanup;
-
-        if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
-            goto cleanup;
-
-        if (virDomainObjIsActive(vm)) {
-            qemuDomainObjEnterMonitor(driver, vm);
-            ret = qemuMonitorGetBlockExtent(priv->mon,
-                                            alias,
-                                            &info->allocation);
-            qemuDomainObjExitMonitor(driver, vm);
-        } else {
-            activeFail = true;
-            ret = 0;
-        }
-
-        if (!qemuDomainObjEndJob(driver, vm))
-            vm = NULL;
-    } else {
-        ret = 0;
-    }
+    ret = qemuDomainGetBlockInfoImpl(driver, vm, disk, info, path);
 
  cleanup:
-    VIR_FREE(buf);
-    VIR_FREE(alias);
-    virStorageSourceFree(meta);
-    VIR_FORCE_CLOSE(fd);
-    if (disk)
-        virStorageFileDeinit(disk->src);
-
-    /* If we failed to get data from a domain because it's inactive and
-     * it's not a persistent domain, then force failure.
-     */
-    if (activeFail && vm && !vm->persistent) {
-        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("domain is not running"));
-        ret = -1;
-    }
     virObjectUnlock(vm);
-    virObjectUnref(cfg);
     return ret;
 }
 
-- 
2.0.4




More information about the libvir-list mailing list