[libvirt] [PATCH 4/5] qemu: Refactor qemuDomainGetBlockInfo
John Ferlan
jferlan at redhat.com
Thu Jun 25 17:26:35 UTC 2015
On 06/23/2015 01:15 PM, Peter Krempa wrote:
> Change the code so that it queries the monitor when the VM is alive.
> ---
> src/qemu/qemu_driver.c | 90 +++++++++++++++++++++++++++++---------------------
> 1 file changed, 53 insertions(+), 37 deletions(-)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 004da7e..3da941e 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -11800,10 +11800,12 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
> virQEMUDriverPtr driver = dom->conn->privateData;
> virDomainObjPtr vm;
> int ret = -1;
> - virDomainDiskDefPtr disk = NULL;
> - virStorageSourcePtr src;
> - bool activeFail = false;
> + virDomainDiskDefPtr disk;
> virQEMUDriverConfigPtr cfg = NULL;
> + int rc;
> + virHashTablePtr stats = NULL;
> + qemuBlockStats *entry;
> + char *alias;
>
> virCheckFlags(0, -1);
>
> @@ -11815,11 +11817,6 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
> if (virDomainGetBlockInfoEnsureACL(dom->conn, vm->def) < 0)
> goto cleanup;
>
> - /* Technically, we only need a job if we are going to query the
> - * monitor, which is only for active domains that are using
> - * non-raw block devices. But it is easier to share code if we
> - * always grab a job; furthermore, grabbing the job ensures that
> - * hot-plug won't change disk behind our backs. */
Was the comment wrong? I tend to like comments like this, since it gives
me an understanding why something was done a particular way...
I'm not going to stop a change for removing the comment though...
ACK
John
> if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
> goto cleanup;
>
> @@ -11829,53 +11826,72 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
> goto endjob;
> }
>
> - src = disk->src;
> - if (virStorageSourceIsEmpty(src)) {
> + if (virStorageSourceIsEmpty(disk->src)) {
> virReportError(VIR_ERR_INVALID_ARG,
> _("disk '%s' does not currently have a source assigned"),
> path);
> goto endjob;
> }
>
> - if ((ret = qemuStorageLimitsRefresh(driver, cfg, vm, src)) < 0)
> + /* for inactive domains we have to peek into the files */
> + if (!virDomainObjIsActive(vm)) {
> + if ((qemuStorageLimitsRefresh(driver, cfg, vm, disk->src)) < 0)
> + goto endjob;
> +
> + info->capacity = disk->src->capacity;
> + info->allocation = disk->src->allocation;
> + info->physical = disk->src->physical;
> +
> + ret = 0;
> + goto endjob;
> + }
> +
> + if (!disk->info.alias ||
> + !(alias = qemuDomainStorageAlias(disk->info.alias, 0))) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("missing disk device alias name for %s"), disk->dst);
> goto endjob;
> + }
>
> - if (!src->allocation) {
> - qemuDomainObjPrivatePtr priv = vm->privateData;
> + qemuDomainObjEnterMonitor(driver, vm);
> + rc = qemuMonitorGetAllBlockStatsInfo(qemuDomainGetMonitor(vm),
> + &stats, false);
> + if (rc >= 0)
> + rc = qemuMonitorBlockStatsUpdateCapacity(qemuDomainGetMonitor(vm),
> + stats, false);
>
> - /* If the guest is not running, then success/failure return
> - * depends on whether domain is persistent
> - */
> - if (!virDomainObjIsActive(vm)) {
> - activeFail = true;
> + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
> + goto endjob;
> +
> + if (!(entry = virHashLookup(stats, alias))) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("failed to gather stats for disk '%s'"), disk->dst);
> + goto endjob;
> + }
> +
> + if (!entry->wr_highest_offset_valid) {
> + if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_BLOCK &&
> + disk->src->format != VIR_STORAGE_FILE_RAW) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("failed to query the maximum written offset of "
> + "block device '%s'"), disk->dst);
> goto endjob;
> }
>
> - qemuDomainObjEnterMonitor(driver, vm);
> - ret = qemuMonitorGetBlockExtent(priv->mon,
> - disk->info.alias,
> - &src->allocation);
> - if (qemuDomainObjExitMonitor(driver, vm) < 0)
> - ret = -1;
> + info->allocation = entry->physical;
> + } else {
> + info->allocation = entry->wr_highest_offset;
> }
>
> - if (ret == 0) {
> - info->capacity = src->capacity;
> - info->allocation = src->allocation;
> - info->physical = src->physical;
> - }
> + info->capacity = entry->capacity;
> + info->physical = entry->physical;
> +
> + ret = 0;
>
> endjob:
> qemuDomainObjEndJob(driver, vm);
> cleanup:
> - /* 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;
> - }
> + virHashFree(stats);
> virDomainObjEndAPI(&vm);
> virObjectUnref(cfg);
> return ret;
>
More information about the libvir-list
mailing list