[libvirt] [PATCH v3 RESEND 08/12] qemu_domain: Introduce qemuDomainGetDiskBlockInfo

Michal Privoznik mprivozn at redhat.com
Mon Feb 18 14:38:41 UTC 2013


This is just digging out important implementation from qemu
driver's qemuDomainGetDiskBlockInfo() API as this functionality
is going to be required in the next patch.
---
 src/qemu/qemu_domain.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h |   4 ++
 src/qemu/qemu_driver.c | 124 +++--------------------------------------------
 3 files changed, 138 insertions(+), 117 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 482f64a..8df2739 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -40,6 +40,9 @@
 
 #include <sys/time.h>
 #include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include <libxml/xpathInternals.h>
 
@@ -1959,3 +1962,127 @@ cleanup:
     virObjectUnref(cfg);
     return ret;
 }
+
+int
+qemuDomainGetDiskBlockInfo(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virDomainDiskDefPtr disk,
+                           virDomainBlockInfoPtr info)
+{
+
+    int ret = -1;
+    virStorageFileMetadata *meta = NULL;
+    virQEMUDriverConfigPtr cfg = NULL;
+    int format;
+    struct stat sb;
+    int fd = -1;
+    off_t end;
+    const char *path;
+
+    if (!disk->src) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("disk %s does not currently have a source assigned"),
+                       disk->dst);
+        goto cleanup;
+    }
+    path = disk->src;
+    cfg = virQEMUDriverGetConfig(driver);
+
+    /* The path is correct, now try to open it and get its size. */
+    if ((fd = open(path, O_RDONLY)) < 0) {
+        virReportSystemError(errno, _("failed to open path '%s'"), path);
+        goto cleanup;
+    }
+
+    /* Probe for magic formats */
+    if (disk->format) {
+        format = disk->format;
+    } else {
+        if (cfg->allowDiskFormatProbing) {
+            if ((format = virStorageFileProbeFormat(path,
+                                                    cfg->user,
+                                                    cfg->group)) < 0)
+                goto cleanup;
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("no disk format for %s and probing is disabled"),
+                           path);
+            goto cleanup;
+        }
+    }
+
+    if (!(meta = virStorageFileGetMetadataFromFD(path, fd, format)))
+        goto cleanup;
+
+    /* Get info for normal formats */
+    if (fstat(fd, &sb) < 0) {
+        virReportSystemError(errno, _("cannot stat file '%s'"), path);
+        goto cleanup;
+    }
+
+    if (S_ISREG(sb.st_mode)) {
+#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 running & not using raw
+       disk format and on a block device, then query
+       highest allocated extent from QEMU */
+    if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
+        format != VIR_STORAGE_FILE_RAW &&
+        S_ISBLK(sb.st_mode) &&
+        virDomainObjIsActive(vm)) {
+        qemuDomainObjPrivatePtr priv = vm->privateData;
+
+        if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+            goto cleanup;
+
+        if (virDomainObjIsActive(vm)) {
+            qemuDomainObjEnterMonitor(driver, vm);
+            ret = qemuMonitorGetBlockExtent(priv->mon,
+                                            disk->info.alias,
+                                            &info->allocation);
+            qemuDomainObjExitMonitor(driver, vm);
+        } else {
+            ret = 0;
+        }
+
+        if (qemuDomainObjEndJob(driver, vm) == 0)
+            vm = NULL;
+    } else {
+        ret = 0;
+    }
+
+cleanup:
+    VIR_FORCE_CLOSE(fd);
+    virStorageFileFreeMetadata(meta);
+    virObjectUnref(cfg);
+    return ret;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index e4df668..4e20a49 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -334,5 +334,9 @@ void qemuDomainCleanupRemove(virDomainObjPtr vm,
                              qemuDomainCleanupCallback cb);
 void qemuDomainCleanupRun(virQEMUDriverPtr driver,
                           virDomainObjPtr vm);
+int qemuDomainGetDiskBlockInfo(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               virDomainDiskDefPtr disk,
+                               virDomainBlockInfoPtr info);
 
 #endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 23499ef..bff7885 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9145,29 +9145,23 @@ cleanup:
 }
 
 
-static int qemuDomainGetBlockInfo(virDomainPtr dom,
-                                  const char *path,
-                                  virDomainBlockInfoPtr info,
-                                  unsigned int flags) {
+static int
+qemuDomainGetBlockInfo(virDomainPtr dom,
+                       const char *path,
+                       virDomainBlockInfoPtr info,
+                       unsigned int flags)
+{
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
-    int fd = -1;
-    off_t end;
-    virStorageFileMetadata *meta = NULL;
     virDomainDiskDefPtr disk = NULL;
-    struct stat sb;
     int i;
-    int format;
-    virQEMUDriverConfigPtr cfg = NULL;
 
     virCheckFlags(0, -1);
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
-    cfg = virQEMUDriverGetConfig(driver);
-
     if (!path || path[0] == '\0') {
         virReportError(VIR_ERR_INVALID_ARG,
                        "%s", _("NULL or empty path"));
@@ -9181,116 +9175,12 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
         goto cleanup;
     }
     disk = vm->def->disks[i];
-    if (!disk->src) {
-        virReportError(VIR_ERR_INVALID_ARG,
-                       _("disk %s does not currently have a source assigned"),
-                       path);
-        goto cleanup;
-    }
-    path = disk->src;
-
-    /* The path is correct, now try to open it and get its size. */
-    fd = open(path, O_RDONLY);
-    if (fd == -1) {
-        virReportSystemError(errno,
-                             _("failed to open path '%s'"), path);
-        goto cleanup;
-    }
-
-    /* Probe for magic formats */
-    if (disk->format) {
-        format = disk->format;
-    } else {
-        if (cfg->allowDiskFormatProbing) {
-            if ((format = virStorageFileProbeFormat(disk->src,
-                                                    cfg->user,
-                                                    cfg->group)) < 0)
-                goto cleanup;
-        } else {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("no disk format for %s and probing is disabled"),
-                           disk->src);
-            goto cleanup;
-        }
-    }
-
-    if (!(meta = virStorageFileGetMetadataFromFD(path, fd, format)))
-        goto cleanup;
-
-    /* Get info for normal formats */
-    if (fstat(fd, &sb) < 0) {
-        virReportSystemError(errno,
-                             _("cannot stat file '%s'"), path);
-        goto cleanup;
-    }
 
-    if (S_ISREG(sb.st_mode)) {
-#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 running & not using raw
-       disk format and on a block device, then query
-       highest allocated extent from QEMU */
-    if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
-        format != VIR_STORAGE_FILE_RAW &&
-        S_ISBLK(sb.st_mode) &&
-        virDomainObjIsActive(vm)) {
-        qemuDomainObjPrivatePtr priv = vm->privateData;
-
-        if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
-            goto cleanup;
-
-        if (virDomainObjIsActive(vm)) {
-            qemuDomainObjEnterMonitor(driver, vm);
-            ret = qemuMonitorGetBlockExtent(priv->mon,
-                                            disk->info.alias,
-                                            &info->allocation);
-            qemuDomainObjExitMonitor(driver, vm);
-        } else {
-            ret = 0;
-        }
-
-        if (qemuDomainObjEndJob(driver, vm) == 0)
-            vm = NULL;
-    } else {
-        ret = 0;
-    }
+    ret = qemuDomainGetDiskBlockInfo(driver, vm, disk, info);
 
 cleanup:
-    virStorageFileFreeMetadata(meta);
-    VIR_FORCE_CLOSE(fd);
     if (vm)
         virObjectUnlock(vm);
-    virObjectUnref(cfg);
     return ret;
 }
 
-- 
1.8.0.2




More information about the libvir-list mailing list