[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