if (flush_total_times)
*flush_total_times = -1;
- if (qemuMonitorJSONGetAllBlockStatsInfo(mon, &blockstats) < 0)
+ if (qemuMonitorJSONGetAllBlockStatsInfo(mon, &blockstats, false) < 0)
goto cleanup;
if (!(stats = virHashLookup(blockstats, dev_name))) {
}
-int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
- virHashTablePtr *ret_stats)
+static int
+qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
+ const char *dev_name,
+ virHashTablePtr hash,
+ bool backingChain ATTRIBUTE_UNUSED)
+{
+ qemuBlockStatsPtr bstats = NULL;
+ virJSONValuePtr stats;
+ int ret = -1;
+
+ if (VIR_ALLOC(bstats) < 0)
+ goto cleanup;
+
+ if ((stats = virJSONValueObjectGet(dev, "stats")) == NULL ||
+ stats->type != VIR_JSON_TYPE_OBJECT) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("blockstats stats entry was not "
+ "in expected format"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetNumberLong(stats, "rd_bytes",
+ &bstats->rd_bytes) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "rd_bytes");
+ goto cleanup;
+ }
+ if (virJSONValueObjectGetNumberLong(stats, "rd_operations",
+ &bstats->rd_req) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "rd_operations");
+ goto cleanup;
+ }
+ if (virJSONValueObjectHasKey(stats, "rd_total_time_ns") &&
+ (virJSONValueObjectGetNumberLong(stats, "rd_total_time_ns",
+ &bstats->rd_total_times) < 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "rd_total_time_ns");
+ goto cleanup;
+ }
+ if (virJSONValueObjectGetNumberLong(stats, "wr_bytes",
+ &bstats->wr_bytes) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "wr_bytes");
+ goto cleanup;
+ }
+ if (virJSONValueObjectGetNumberLong(stats, "wr_operations",
+ &bstats->wr_req) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "wr_operations");
+ goto cleanup;
+ }
+ if (virJSONValueObjectHasKey(stats, "wr_total_time_ns") &&
+ (virJSONValueObjectGetNumberLong(stats, "wr_total_time_ns",
+ &bstats->wr_total_times) < 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "wr_total_time_ns");
+ goto cleanup;
+ }
+ if (virJSONValueObjectHasKey(stats, "flush_operations") &&
+ (virJSONValueObjectGetNumberLong(stats, "flush_operations",
+ &bstats->flush_req) < 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "flush_operations");
+ goto cleanup;
+ }
+ if (virJSONValueObjectHasKey(stats, "flush_total_time_ns") &&
+ (virJSONValueObjectGetNumberLong(stats, "flush_total_time_ns",
+ &bstats->flush_total_times) < 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "flush_total_time_ns");
+ goto cleanup;
+ }
+
+ /* it's ok to not have this information here. Just skip silently. */
+ qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
+
+ if (virHashAddEntry(hash, dev_name, bstats) < 0)
+ goto cleanup;
+ bstats = NULL;
+ ret = 0;
+ cleanup:
+ VIR_FREE(bstats);
+ return ret;
+}
+
+
+int
+qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
+ virHashTablePtr *ret_stats,
+ bool backingChain)
{
int ret = -1;
int rc;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr devices;
- qemuBlockStatsPtr bstats = NULL;
virHashTablePtr hash = NULL;
if (!(cmd = qemuMonitorJSONMakeCommand("query-blockstats", NULL)))
for (i = 0; i < virJSONValueArraySize(devices); i++) {
virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
- virJSONValuePtr stats;
const char *dev_name;
- if (VIR_ALLOC(bstats) < 0)
- goto cleanup;
-
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("blockstats device entry was not "
if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
- if ((stats = virJSONValueObjectGet(dev, "stats")) == NULL ||
- stats->type != VIR_JSON_TYPE_OBJECT) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("blockstats stats entry was not "
- "in expected format"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberLong(stats, "rd_bytes",
- &bstats->rd_bytes) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "rd_bytes");
- goto cleanup;
- }
- if (virJSONValueObjectGetNumberLong(stats, "rd_operations",
- &bstats->rd_req) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "rd_operations");
- goto cleanup;
- }
- if (virJSONValueObjectHasKey(stats, "rd_total_time_ns") &&
- (virJSONValueObjectGetNumberLong(stats, "rd_total_time_ns",
- &bstats->rd_total_times) < 0)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "rd_total_time_ns");
- goto cleanup;
- }
- if (virJSONValueObjectGetNumberLong(stats, "wr_bytes",
- &bstats->wr_bytes) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "wr_bytes");
+ if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, hash,
+ backingChain) < 0)
goto cleanup;
- }
- if (virJSONValueObjectGetNumberLong(stats, "wr_operations",
- &bstats->wr_req) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "wr_operations");
- goto cleanup;
- }
- if (virJSONValueObjectHasKey(stats, "wr_total_time_ns") &&
- (virJSONValueObjectGetNumberLong(stats, "wr_total_time_ns",
- &bstats->wr_total_times) < 0)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "wr_total_time_ns");
- goto cleanup;
- }
- if (virJSONValueObjectHasKey(stats, "flush_operations") &&
- (virJSONValueObjectGetNumberLong(stats, "flush_operations",
- &bstats->flush_req) < 0)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "flush_operations");
- goto cleanup;
- }
- if (virJSONValueObjectHasKey(stats, "flush_total_time_ns") &&
- (virJSONValueObjectGetNumberLong(stats, "flush_total_time_ns",
- &bstats->flush_total_times) < 0)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "flush_total_time_ns");
- goto cleanup;
- }
-
- /* it's ok to not have this information here. Just skip silently. */
- qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
- if (virHashAddEntry(hash, dev_name, bstats) < 0)
- goto cleanup;
- bstats = NULL;
}
*ret_stats = hash;
ret = 0;
cleanup:
- VIR_FREE(bstats);
virHashFree(hash);
virJSONValueFree(cmd);
virJSONValueFree(reply);
}
-int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
- virHashTablePtr stats)
+static int
+qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
+ const char *dev_name,
+ virHashTablePtr stats,
+ bool backingChain ATTRIBUTE_UNUSED)
+{
+ qemuBlockStatsPtr bstats;
+ int ret = -1;
+
+ if (!(bstats = virHashLookup(stats, dev_name))) {
+ if (VIR_ALLOC(bstats) < 0)
+ goto cleanup;
+
+ if (virHashAddEntry(stats, dev_name, bstats) < 0) {
+ VIR_FREE(bstats);
+ goto cleanup;
+ }
+ }
+
+ /* After this point, we ignore failures; the stats were
+ * zero-initialized when created which is a sane fallback. */
+ ret = 0;
+ if (virJSONValueObjectGetNumberUlong(image, "virtual-size",
+ &bstats->capacity) < 0)
+ goto cleanup;
+
+ /* if actual-size is missing, image is not thin provisioned */
+ if (virJSONValueObjectGetNumberUlong(image, "actual-size",
+ &bstats->physical) < 0)
+ bstats->physical = bstats->capacity;
+ cleanup:
+ return ret;
+}
+
+
+int
+qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
+ virHashTablePtr stats,
+ bool backingChain)
{
int ret = -1;
int rc;
virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
virJSONValuePtr inserted;
virJSONValuePtr image;
- qemuBlockStatsPtr bstats;
const char *dev_name;
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
!(image = virJSONValueObjectGet(inserted, "image")))
continue;
- if (!(bstats = virHashLookup(stats, dev_name))) {
- if (VIR_ALLOC(bstats) < 0)
- goto cleanup;
-
- if (virHashAddEntry(stats, dev_name, bstats) < 0) {
- VIR_FREE(bstats);
- goto cleanup;
- }
- }
-
- if (virJSONValueObjectGetNumberUlong(image, "virtual-size",
- &bstats->capacity) < 0)
- continue;
-
- /* if actual-size is missing, image is not thin provisioned */
- if (virJSONValueObjectGetNumberUlong(image, "actual-size",
- &bstats->physical) < 0)
- bstats->physical = bstats->capacity;
+ if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, stats,
+ backingChain) < 0)
+ goto cleanup;
}
ret = 0;