|
|
9119d9 |
From d86dcee6e419259d365eaaa69a4d71c48491e95f Mon Sep 17 00:00:00 2001
|
|
|
9119d9 |
Message-Id: <d86dcee6e419259d365eaaa69a4d71c48491e95f@dist-git>
|
|
|
9119d9 |
From: Eric Blake <eblake@redhat.com>
|
|
|
9119d9 |
Date: Wed, 17 Dec 2014 03:09:04 -0700
|
|
|
9119d9 |
Subject: [PATCH] getstats: prepare monitor collection for recursion
|
|
|
9119d9 |
|
|
|
9119d9 |
https://bugzilla.redhat.com/show_bug.cgi?id=1041569
|
|
|
9119d9 |
|
|
|
9119d9 |
A future patch will allow recursion into backing chains when
|
|
|
9119d9 |
collecting block stats. This patch should not change behavior,
|
|
|
9119d9 |
but merely moves out the common code that will be reused once
|
|
|
9119d9 |
recursion is enabled, and adds the parameter that will turn on
|
|
|
9119d9 |
recursion.
|
|
|
9119d9 |
|
|
|
9119d9 |
* src/qemu/qemu_monitor.h (qemuMonitorGetAllBlockStatsInfo)
|
|
|
9119d9 |
(qemuMonitorBlockStatsUpdateCapacity): Add recursion parameter,
|
|
|
9119d9 |
although it is ignored for now.
|
|
|
9119d9 |
* src/qemu/qemu_monitor.h (qemuMonitorGetAllBlockStatsInfo)
|
|
|
9119d9 |
(qemuMonitorBlockStatsUpdateCapacity): Likewise.
|
|
|
9119d9 |
* src/qemu/qemu_monitor_json.h
|
|
|
9119d9 |
(qemuMonitorJSONGetAllBlockStatsInfo)
|
|
|
9119d9 |
(qemuMonitorJSONBlockStatsUpdateCapacity): Likewise.
|
|
|
9119d9 |
* src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
(qemuMonitorJSONGetAllBlockStatsInfo)
|
|
|
9119d9 |
(qemuMonitorJSONBlockStatsUpdateCapacity): Add parameter, and
|
|
|
9119d9 |
split...
|
|
|
9119d9 |
(qemuMonitorJSONGetOneBlockStatsInfo)
|
|
|
9119d9 |
(qemuMonitorJSONBlockStatsUpdateCapacityOne): ...into helpers.
|
|
|
9119d9 |
(qemuMonitorJSONGetBlockStatsInfo): Update caller.
|
|
|
9119d9 |
* src/qemu/qemu_driver.c (qemuDomainGetStatsBlock): Update caller.
|
|
|
9119d9 |
* src/qemu/qemu_migration.c (qemuMigrationCookieAddNBD): Likewise.
|
|
|
9119d9 |
|
|
|
9119d9 |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
9119d9 |
(cherry picked from commit 7b11f5e5547ded860692caa2cefae1a856920336)
|
|
|
9119d9 |
|
|
|
9119d9 |
Conflicts:
|
|
|
9119d9 |
src/qemu/qemu_migration.c - no disk precreation (commit e1466dc)
|
|
|
9119d9 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
9119d9 |
---
|
|
|
9119d9 |
src/qemu/qemu_driver.c | 5 +-
|
|
|
9119d9 |
src/qemu/qemu_monitor.c | 24 ++--
|
|
|
9119d9 |
src/qemu/qemu_monitor.h | 6 +-
|
|
|
9119d9 |
src/qemu/qemu_monitor_json.c | 257 +++++++++++++++++++++++++------------------
|
|
|
9119d9 |
src/qemu/qemu_monitor_json.h | 6 +-
|
|
|
9119d9 |
5 files changed, 173 insertions(+), 125 deletions(-)
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
9119d9 |
index 03b62d8..8376486 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_driver.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_driver.c
|
|
|
9119d9 |
@@ -18025,8 +18025,9 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
|
|
|
9119d9 |
abbreviated = true; /* it's ok, just go ahead silently */
|
|
|
9119d9 |
} else {
|
|
|
9119d9 |
qemuDomainObjEnterMonitor(driver, dom);
|
|
|
9119d9 |
- rc = qemuMonitorGetAllBlockStatsInfo(priv->mon, &stats);
|
|
|
9119d9 |
- ignore_value(qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats));
|
|
|
9119d9 |
+ rc = qemuMonitorGetAllBlockStatsInfo(priv->mon, &stats, false);
|
|
|
9119d9 |
+ ignore_value(qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats,
|
|
|
9119d9 |
+ false));
|
|
|
9119d9 |
qemuDomainObjExitMonitor(driver, dom);
|
|
|
9119d9 |
|
|
|
9119d9 |
if (rc < 0) {
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
index 38399ba..f797f4f 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
@@ -1787,16 +1787,16 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
return ret;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
-/* Fills the first 'nstats' block stats. 'stats' must be an array.
|
|
|
9119d9 |
- * Returns <0 on error, otherwise the number of block stats retrieved.
|
|
|
9119d9 |
- * if 'dev_name' is != NULL, look for this device only and skip
|
|
|
9119d9 |
- * any other. In that case return value cannot be greater than 1.
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+/* Creates a hash table in 'ret_stats' with all block stats.
|
|
|
9119d9 |
+ * Returns <0 on error, 0 on success.
|
|
|
9119d9 |
*/
|
|
|
9119d9 |
int
|
|
|
9119d9 |
qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr *ret_stats)
|
|
|
9119d9 |
+ virHashTablePtr *ret_stats,
|
|
|
9119d9 |
+ bool backingChain)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
- VIR_DEBUG("mon=%p ret_stats=%p", mon, ret_stats);
|
|
|
9119d9 |
+ VIR_DEBUG("mon=%p ret_stats=%p, backing=%d", mon, ret_stats, backingChain);
|
|
|
9119d9 |
|
|
|
9119d9 |
if (!mon->json) {
|
|
|
9119d9 |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
@@ -1804,15 +1804,17 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
return -1;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
- return qemuMonitorJSONGetAllBlockStatsInfo(mon, ret_stats);
|
|
|
9119d9 |
+ return qemuMonitorJSONGetAllBlockStatsInfo(mon, ret_stats, backingChain);
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
/* Updates "stats" to fill virtual and physical size of the image */
|
|
|
9119d9 |
-int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr stats)
|
|
|
9119d9 |
+int
|
|
|
9119d9 |
+qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ virHashTablePtr stats,
|
|
|
9119d9 |
+ bool backingChain)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
- VIR_DEBUG("mon=%p, stats=%p", mon, stats);
|
|
|
9119d9 |
+ VIR_DEBUG("mon=%p, stats=%p, backing=%d", mon, stats, backingChain);
|
|
|
9119d9 |
|
|
|
9119d9 |
if (!mon->json) {
|
|
|
9119d9 |
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
9119d9 |
@@ -1820,7 +1822,7 @@ int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
return -1;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
- return qemuMonitorJSONBlockStatsUpdateCapacity(mon, stats);
|
|
|
9119d9 |
+ return qemuMonitorJSONBlockStatsUpdateCapacity(mon, stats, backingChain);
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
index d1dc242..b08d74d 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
@@ -382,11 +382,13 @@ struct _qemuBlockStats {
|
|
|
9119d9 |
};
|
|
|
9119d9 |
|
|
|
9119d9 |
int qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr *ret_stats)
|
|
|
9119d9 |
+ virHashTablePtr *ret_stats,
|
|
|
9119d9 |
+ bool backingChain)
|
|
|
9119d9 |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
9119d9 |
|
|
|
9119d9 |
int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr stats)
|
|
|
9119d9 |
+ virHashTablePtr stats,
|
|
|
9119d9 |
+ bool backingChain)
|
|
|
9119d9 |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
9119d9 |
|
|
|
9119d9 |
int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
index 3cf67aa..7088409 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
@@ -1770,7 +1770,7 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
if (flush_total_times)
|
|
|
9119d9 |
*flush_total_times = -1;
|
|
|
9119d9 |
|
|
|
9119d9 |
- if (qemuMonitorJSONGetAllBlockStatsInfo(mon, &blockstats) < 0)
|
|
|
9119d9 |
+ if (qemuMonitorJSONGetAllBlockStatsInfo(mon, &blockstats, false) < 0)
|
|
|
9119d9 |
goto cleanup;
|
|
|
9119d9 |
|
|
|
9119d9 |
if (!(stats = virHashLookup(blockstats, dev_name))) {
|
|
|
9119d9 |
@@ -1836,16 +1836,112 @@ qemuMonitorJSONDevGetBlockExtent(virJSONValuePtr dev,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
-int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr *ret_stats)
|
|
|
9119d9 |
+static int
|
|
|
9119d9 |
+qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
|
|
|
9119d9 |
+ const char *dev_name,
|
|
|
9119d9 |
+ virHashTablePtr hash,
|
|
|
9119d9 |
+ bool backingChain ATTRIBUTE_UNUSED)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
- int ret = -1;
|
|
|
9119d9 |
- int rc;
|
|
|
9119d9 |
- size_t i;
|
|
|
9119d9 |
- virJSONValuePtr cmd;
|
|
|
9119d9 |
- virJSONValuePtr reply = NULL;
|
|
|
9119d9 |
- virJSONValuePtr devices;
|
|
|
9119d9 |
qemuBlockStatsPtr bstats = NULL;
|
|
|
9119d9 |
+ virJSONValuePtr stats;
|
|
|
9119d9 |
+ int ret = -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (VIR_ALLOC(bstats) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if ((stats = virJSONValueObjectGet(dev, "stats")) == NULL ||
|
|
|
9119d9 |
+ stats->type != VIR_JSON_TYPE_OBJECT) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
+ _("blockstats stats entry was not "
|
|
|
9119d9 |
+ "in expected format"));
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (virJSONValueObjectGetNumberLong(stats, "rd_bytes",
|
|
|
9119d9 |
+ &bstats->rd_bytes) < 0) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "rd_bytes");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (virJSONValueObjectGetNumberLong(stats, "rd_operations",
|
|
|
9119d9 |
+ &bstats->rd_req) < 0) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "rd_operations");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (virJSONValueObjectHasKey(stats, "rd_total_time_ns") &&
|
|
|
9119d9 |
+ (virJSONValueObjectGetNumberLong(stats, "rd_total_time_ns",
|
|
|
9119d9 |
+ &bstats->rd_total_times) < 0)) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "rd_total_time_ns");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (virJSONValueObjectGetNumberLong(stats, "wr_bytes",
|
|
|
9119d9 |
+ &bstats->wr_bytes) < 0) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "wr_bytes");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (virJSONValueObjectGetNumberLong(stats, "wr_operations",
|
|
|
9119d9 |
+ &bstats->wr_req) < 0) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "wr_operations");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (virJSONValueObjectHasKey(stats, "wr_total_time_ns") &&
|
|
|
9119d9 |
+ (virJSONValueObjectGetNumberLong(stats, "wr_total_time_ns",
|
|
|
9119d9 |
+ &bstats->wr_total_times) < 0)) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "wr_total_time_ns");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (virJSONValueObjectHasKey(stats, "flush_operations") &&
|
|
|
9119d9 |
+ (virJSONValueObjectGetNumberLong(stats, "flush_operations",
|
|
|
9119d9 |
+ &bstats->flush_req) < 0)) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "flush_operations");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (virJSONValueObjectHasKey(stats, "flush_total_time_ns") &&
|
|
|
9119d9 |
+ (virJSONValueObjectGetNumberLong(stats, "flush_total_time_ns",
|
|
|
9119d9 |
+ &bstats->flush_total_times) < 0)) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
+ _("cannot read %s statistic"),
|
|
|
9119d9 |
+ "flush_total_time_ns");
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* it's ok to not have this information here. Just skip silently. */
|
|
|
9119d9 |
+ qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (virHashAddEntry(hash, dev_name, bstats) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ bstats = NULL;
|
|
|
9119d9 |
+ ret = 0;
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ VIR_FREE(bstats);
|
|
|
9119d9 |
+ return ret;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+int
|
|
|
9119d9 |
+qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ virHashTablePtr *ret_stats,
|
|
|
9119d9 |
+ bool backingChain)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ int ret = -1;
|
|
|
9119d9 |
+ int rc;
|
|
|
9119d9 |
+ size_t i;
|
|
|
9119d9 |
+ virJSONValuePtr cmd;
|
|
|
9119d9 |
+ virJSONValuePtr reply = NULL;
|
|
|
9119d9 |
+ virJSONValuePtr devices;
|
|
|
9119d9 |
virHashTablePtr hash = NULL;
|
|
|
9119d9 |
|
|
|
9119d9 |
if (!(cmd = qemuMonitorJSONMakeCommand("query-blockstats", NULL)))
|
|
|
9119d9 |
@@ -1869,12 +1965,8 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
|
|
|
9119d9 |
for (i = 0; i < virJSONValueArraySize(devices); i++) {
|
|
|
9119d9 |
virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
|
|
|
9119d9 |
- virJSONValuePtr stats;
|
|
|
9119d9 |
const char *dev_name;
|
|
|
9119d9 |
|
|
|
9119d9 |
- if (VIR_ALLOC(bstats) < 0)
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
-
|
|
|
9119d9 |
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
|
|
|
9119d9 |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
_("blockstats device entry was not "
|
|
|
9119d9 |
@@ -1892,81 +1984,10 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
|
|
|
9119d9 |
dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
|
|
|
9119d9 |
|
|
|
9119d9 |
- if ((stats = virJSONValueObjectGet(dev, "stats")) == NULL ||
|
|
|
9119d9 |
- stats->type != VIR_JSON_TYPE_OBJECT) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
9119d9 |
- _("blockstats stats entry was not "
|
|
|
9119d9 |
- "in expected format"));
|
|
|
9119d9 |
+ if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, hash,
|
|
|
9119d9 |
+ backingChain) < 0)
|
|
|
9119d9 |
goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
|
|
|
9119d9 |
- if (virJSONValueObjectGetNumberLong(stats, "rd_bytes",
|
|
|
9119d9 |
- &bstats->rd_bytes) < 0) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "rd_bytes");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- if (virJSONValueObjectGetNumberLong(stats, "rd_operations",
|
|
|
9119d9 |
- &bstats->rd_req) < 0) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "rd_operations");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- if (virJSONValueObjectHasKey(stats, "rd_total_time_ns") &&
|
|
|
9119d9 |
- (virJSONValueObjectGetNumberLong(stats, "rd_total_time_ns",
|
|
|
9119d9 |
- &bstats->rd_total_times) < 0)) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "rd_total_time_ns");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- if (virJSONValueObjectGetNumberLong(stats, "wr_bytes",
|
|
|
9119d9 |
- &bstats->wr_bytes) < 0) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "wr_bytes");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- if (virJSONValueObjectGetNumberLong(stats, "wr_operations",
|
|
|
9119d9 |
- &bstats->wr_req) < 0) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "wr_operations");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- if (virJSONValueObjectHasKey(stats, "wr_total_time_ns") &&
|
|
|
9119d9 |
- (virJSONValueObjectGetNumberLong(stats, "wr_total_time_ns",
|
|
|
9119d9 |
- &bstats->wr_total_times) < 0)) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "wr_total_time_ns");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- if (virJSONValueObjectHasKey(stats, "flush_operations") &&
|
|
|
9119d9 |
- (virJSONValueObjectGetNumberLong(stats, "flush_operations",
|
|
|
9119d9 |
- &bstats->flush_req) < 0)) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "flush_operations");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- if (virJSONValueObjectHasKey(stats, "flush_total_time_ns") &&
|
|
|
9119d9 |
- (virJSONValueObjectGetNumberLong(stats, "flush_total_time_ns",
|
|
|
9119d9 |
- &bstats->flush_total_times) < 0)) {
|
|
|
9119d9 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
9119d9 |
- _("cannot read %s statistic"),
|
|
|
9119d9 |
- "flush_total_time_ns");
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
-
|
|
|
9119d9 |
- /* it's ok to not have this information here. Just skip silently. */
|
|
|
9119d9 |
- qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
|
|
|
9119d9 |
-
|
|
|
9119d9 |
- if (virHashAddEntry(hash, dev_name, bstats) < 0)
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- bstats = NULL;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
*ret_stats = hash;
|
|
|
9119d9 |
@@ -1974,7 +1995,6 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
ret = 0;
|
|
|
9119d9 |
|
|
|
9119d9 |
cleanup:
|
|
|
9119d9 |
- VIR_FREE(bstats);
|
|
|
9119d9 |
virHashFree(hash);
|
|
|
9119d9 |
virJSONValueFree(cmd);
|
|
|
9119d9 |
virJSONValueFree(reply);
|
|
|
9119d9 |
@@ -1982,8 +2002,45 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
-int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr stats)
|
|
|
9119d9 |
+static int
|
|
|
9119d9 |
+qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
|
|
|
9119d9 |
+ const char *dev_name,
|
|
|
9119d9 |
+ virHashTablePtr stats,
|
|
|
9119d9 |
+ bool backingChain ATTRIBUTE_UNUSED)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ qemuBlockStatsPtr bstats;
|
|
|
9119d9 |
+ int ret = -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(bstats = virHashLookup(stats, dev_name))) {
|
|
|
9119d9 |
+ if (VIR_ALLOC(bstats) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (virHashAddEntry(stats, dev_name, bstats) < 0) {
|
|
|
9119d9 |
+ VIR_FREE(bstats);
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* After this point, we ignore failures; the stats were
|
|
|
9119d9 |
+ * zero-initialized when created which is a sane fallback. */
|
|
|
9119d9 |
+ ret = 0;
|
|
|
9119d9 |
+ if (virJSONValueObjectGetNumberUlong(image, "virtual-size",
|
|
|
9119d9 |
+ &bstats->capacity) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* if actual-size is missing, image is not thin provisioned */
|
|
|
9119d9 |
+ if (virJSONValueObjectGetNumberUlong(image, "actual-size",
|
|
|
9119d9 |
+ &bstats->physical) < 0)
|
|
|
9119d9 |
+ bstats->physical = bstats->capacity;
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ return ret;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+int
|
|
|
9119d9 |
+qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ virHashTablePtr stats,
|
|
|
9119d9 |
+ bool backingChain)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
int ret = -1;
|
|
|
9119d9 |
int rc;
|
|
|
9119d9 |
@@ -2012,7 +2069,6 @@ int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
|
|
|
9119d9 |
virJSONValuePtr inserted;
|
|
|
9119d9 |
virJSONValuePtr image;
|
|
|
9119d9 |
- qemuBlockStatsPtr bstats;
|
|
|
9119d9 |
const char *dev_name;
|
|
|
9119d9 |
|
|
|
9119d9 |
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
|
|
|
9119d9 |
@@ -2037,24 +2093,9 @@ int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
!(image = virJSONValueObjectGet(inserted, "image")))
|
|
|
9119d9 |
continue;
|
|
|
9119d9 |
|
|
|
9119d9 |
- if (!(bstats = virHashLookup(stats, dev_name))) {
|
|
|
9119d9 |
- if (VIR_ALLOC(bstats) < 0)
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
-
|
|
|
9119d9 |
- if (virHashAddEntry(stats, dev_name, bstats) < 0) {
|
|
|
9119d9 |
- VIR_FREE(bstats);
|
|
|
9119d9 |
- goto cleanup;
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
- }
|
|
|
9119d9 |
-
|
|
|
9119d9 |
- if (virJSONValueObjectGetNumberUlong(image, "virtual-size",
|
|
|
9119d9 |
- &bstats->capacity) < 0)
|
|
|
9119d9 |
- continue;
|
|
|
9119d9 |
-
|
|
|
9119d9 |
- /* if actual-size is missing, image is not thin provisioned */
|
|
|
9119d9 |
- if (virJSONValueObjectGetNumberUlong(image, "actual-size",
|
|
|
9119d9 |
- &bstats->physical) < 0)
|
|
|
9119d9 |
- bstats->physical = bstats->capacity;
|
|
|
9119d9 |
+ if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, stats,
|
|
|
9119d9 |
+ backingChain) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
ret = 0;
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
|
|
|
9119d9 |
index 17f9718..d039991 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor_json.h
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor_json.h
|
|
|
9119d9 |
@@ -80,9 +80,11 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
long long *flush_total_times,
|
|
|
9119d9 |
long long *errs);
|
|
|
9119d9 |
int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr *ret_stats);
|
|
|
9119d9 |
+ virHashTablePtr *ret_stats,
|
|
|
9119d9 |
+ bool backingChain);
|
|
|
9119d9 |
int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|
|
9119d9 |
- virHashTablePtr stats);
|
|
|
9119d9 |
+ virHashTablePtr stats,
|
|
|
9119d9 |
+ bool backingChain);
|
|
|
9119d9 |
int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
|
|
9119d9 |
int *nparams);
|
|
|
9119d9 |
int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,
|
|
|
9119d9 |
--
|
|
|
9119d9 |
2.2.0
|
|
|
9119d9 |
|