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.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_domain.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 4 ++
src/qemu/qemu_driver.c | 121 +++--------------------------------------------
3 files changed, 135 insertions(+), 114 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b5770c5..64cd278 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2501,3 +2501,127 @@ error:
path);
goto cleanup;
}
+
+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->info.alias);
+ goto cleanup;
+ }
+ path = disk->src;
+
+ /* The path is correct, now try to open it and get its size. */
+ fd = qemuOpenFile(driver, vm, path, O_RDONLY, NULL, NULL);
+ if (fd == -1)
+ 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))
+ 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 50987a4..b6e6e33 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -360,6 +360,10 @@ void qemuDomainCleanupRemove(virDomainObjPtr vm,
qemuDomainCleanupCallback cb);
void qemuDomainCleanupRun(virQEMUDriverPtr driver,
virDomainObjPtr vm);
+int qemuDomainGetDiskBlockInfo(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk,
+ virDomainBlockInfoPtr info);
extern virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks;
extern virDomainXMLNamespace virQEMUDriverDomainXMLNamespace;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5f5d0f1..78058b9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9556,29 +9556,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 idx;
- int format;
- virQEMUDriverConfigPtr cfg = NULL;
virCheckFlags(0, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
- cfg = virQEMUDriverGetConfig(driver);
-
if (virDomainGetBlockInfoEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
@@ -9595,113 +9589,12 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
goto cleanup;
}
disk = vm->def->disks[idx];
- 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 = qemuOpenFile(driver, vm, path, O_RDONLY, NULL, NULL);
- if (fd == -1)
- 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))
- 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.1.5