[libvirt] [PATCH RESEND 2/4] qemu_domain: Introduce qemuDomainGetDiskBlockInfo
Doug Goldstein
cardoe at gentoo.org
Mon Sep 16 03:05:41 UTC 2013
On Fri, Sep 13, 2013 at 1:31 AM, Michal Privoznik <mprivozn at redhat.com> wrote:
> 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 at 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;
cfg is NULL here....
> + 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) {
and used here, without being set. I think you're missing a "cfg =
virQEMUDriverGetConfig(driver);" somewhere above.
> + 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 70b587f..b3e120f 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
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
--
Doug Goldstein
More information about the libvir-list
mailing list