Extract the code to look up the disk alias and return the block stats struct so that it can be reused later in qemuDomainBlockStatsFlags. --- src/qemu/qemu_driver.c | 122 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 06168b1..e280cdf 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10480,6 +10480,80 @@ qemuDomainBlockResize(virDomainPtr dom, return ret; } + +/** + * qemuDomainBlocksStatsGather: + * @driver: driver object + * @vm: domain object + * @path: to gather the statistics for + * @retstats: returns pointer to structure holding the stats + * + * Gathers the block statistics for use in qemuDomainBlockStats* APIs. + * + * Returns -1 on error; number of filled block statistics on success. + */ +static int +qemuDomainBlocksStatsGather(virQEMUDriverPtr driver, + virDomainObjPtr vm, + const char *path, + qemuBlockStatsPtr *retstats) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainDiskDefPtr disk; + virHashTablePtr blockstats = NULL; + qemuBlockStatsPtr stats; + int nstats; + char *diskAlias = NULL; + int ret = -1; + + if (*path) { + int idx; + + if ((idx = virDomainDiskIndexByName(vm->def, path, false)) < 0) { + virReportError(VIR_ERR_INVALID_ARG, _("invalid path: %s"), path); + goto cleanup; + } + disk = vm->def->disks[idx]; + + if (!disk->info.alias) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing disk device alias name for %s"), disk->dst); + goto cleanup; + } + + if (VIR_STRDUP(diskAlias, disk->info.alias) < 0) + goto cleanup; + } else { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("summary statistics are not supported yet")); + goto cleanup; + } + + qemuDomainObjEnterMonitor(driver, vm); + nstats = qemuMonitorGetAllBlockStatsInfo(priv->mon, &blockstats, false); + if (qemuDomainObjExitMonitor(driver, vm) < 0 || nstats < 0) + goto cleanup; + + if (VIR_ALLOC(*retstats) < 0) + goto cleanup; + + if (!(stats = virHashLookup(blockstats, diskAlias))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find statistics for device '%s'"), diskAlias); + goto cleanup; + } + + **retstats = *stats; + + ret = nstats; + + cleanup: + VIR_FREE(diskAlias); + virHashFree(blockstats); + return ret; +} + + /* This uses the 'info blockstats' monitor command which was * integrated into both qemu & kvm in late 2007. If the command is * not supported we detect this and return the appropriate error. @@ -10490,18 +10564,9 @@ qemuDomainBlockStats(virDomainPtr dom, virDomainBlockStatsPtr stats) { virQEMUDriverPtr driver = dom->conn->privateData; - int idx; + qemuBlockStatsPtr blockstats = NULL; int ret = -1; virDomainObjPtr vm; - virDomainDiskDefPtr disk = NULL; - qemuDomainObjPrivatePtr priv; - char *diskAlias = NULL; - - if (!*path) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("summary statistics are not supported yet")); - return ret; - } if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; @@ -10518,47 +10583,24 @@ qemuDomainBlockStats(virDomainPtr dom, goto endjob; } - if ((idx = virDomainDiskIndexByName(vm->def, path, false)) < 0) { - virReportError(VIR_ERR_INVALID_ARG, - _("invalid path: %s"), path); + if (qemuDomainBlocksStatsGather(driver, vm, path, &blockstats) < 0) goto endjob; - } - disk = vm->def->disks[idx]; - - if (!disk->info.alias) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("missing disk device alias name for %s"), disk->dst); - goto endjob; - } - - if (VIR_STRDUP(diskAlias, disk->info.alias) < 0) - goto endjob; - - priv = vm->privateData; + stats->rd_req = blockstats->rd_req; + stats->rd_bytes = blockstats->rd_bytes; + stats->wr_req = blockstats->wr_req; + stats->wr_bytes = blockstats->wr_bytes; /* qemu doesn't report the error count */ stats->errs = -1; - qemuDomainObjEnterMonitor(driver, vm); - ret = qemuMonitorGetBlockStatsInfo(priv->mon, - diskAlias, - &stats->rd_req, - &stats->rd_bytes, - NULL, - &stats->wr_req, - &stats->wr_bytes, - NULL, - NULL, - NULL); - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; + ret = 0; endjob: qemuDomainObjEndJob(driver, vm); cleanup: qemuDomObjEndAPI(&vm); - VIR_FREE(diskAlias); + VIR_FREE(blockstats); return ret; } -- 2.2.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list