goto cleanup; \
} while (0)
+#define QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, num, name, value) \
+do { \
+ char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
+ snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
+ "block.%zu.%s", num, name); \
+ if (virTypedParamsAddULLong(&(record)->params, \
+ &(record)->nparams, \
+ maxparams, \
+ param_name, \
+ value) < 0) \
+ goto cleanup; \
+} while (0)
+
static int
qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
virDomainObjPtr dom,
qemuDomainObjEnterMonitor(driver, dom);
rc = qemuMonitorGetAllBlockStatsInfo(priv->mon, &stats);
+ ignore_value(qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats));
qemuDomainObjExitMonitor(driver, dom);
if (rc < 0) {
"fl.reqs", entry->flush_req);
QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i,
"fl.times", entry->flush_total_times);
+
+ QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, i,
+ "allocation", entry->wr_highest_offset);
+
+ if (entry->capacity)
+ QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, i,
+ "capacity", entry->capacity);
+ if (entry->physical)
+ QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, i,
+ "physical", entry->physical);
+
}
ret = 0;
#undef QEMU_ADD_BLOCK_PARAM_LL
+#undef QEMU_ADD_BLOCK_PARAM_ULL
+
#undef QEMU_ADD_NAME_PARAM
#undef QEMU_ADD_COUNT_PARAM
}
+typedef enum {
+ QEMU_MONITOR_BLOCK_EXTENT_ERROR_OK,
+ QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOPARENT,
+ QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOSTATS,
+ QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOOFFSET,
+} qemuMonitorBlockExtentError;
+
+
+static int
+qemuMonitorJSONDevGetBlockExtent(virJSONValuePtr dev,
+ unsigned long long *extent)
+{
+ virJSONValuePtr stats;
+ virJSONValuePtr parent;
+
+ if ((parent = virJSONValueObjectGet(dev, "parent")) == NULL ||
+ parent->type != VIR_JSON_TYPE_OBJECT) {
+ return QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOPARENT;
+ }
+
+ if ((stats = virJSONValueObjectGet(parent, "stats")) == NULL ||
+ stats->type != VIR_JSON_TYPE_OBJECT) {
+ return QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOSTATS;
+ }
+
+ if (virJSONValueObjectGetNumberUlong(stats, "wr_highest_offset",
+ extent) < 0) {
+ return QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOOFFSET;
+ }
+
+ return QEMU_MONITOR_BLOCK_EXTENT_ERROR_OK;
+}
+
+
int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
virHashTablePtr *ret_stats)
{
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;
return ret;
}
+
+static int
+qemuMonitorJSONReportBlockExtentError(qemuMonitorBlockExtentError error)
+{
+ switch (error) {
+ case QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOPARENT:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("blockstats parent entry was not in "
+ "expected format"));
+ break;
+
+ case QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOSTATS:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("blockstats stats entry was not in "
+ "expected format"));
+
+ case QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOOFFSET:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot read %s statistic"),
+ "wr_highest_offset");
+ break;
+
+ case QEMU_MONITOR_BLOCK_EXTENT_ERROR_OK:
+ return 0;
+ }
+
+ return -1;
+}
+
+
int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,
const char *dev_name,
unsigned long long *extent)
for (i = 0; i < virJSONValueArraySize(devices); i++) {
virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
- virJSONValuePtr stats;
- virJSONValuePtr parent;
const char *thisdev;
+ int err;
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("blockstats device entry was not in expected format"));
continue;
found = true;
- if ((parent = virJSONValueObjectGet(dev, "parent")) == NULL ||
- parent->type != VIR_JSON_TYPE_OBJECT) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("blockstats parent entry was not in expected format"));
- goto cleanup;
- }
-
- if ((stats = virJSONValueObjectGet(parent, "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 (virJSONValueObjectGetNumberUlong(stats, "wr_highest_offset", extent) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot read %s statistic"),
- "wr_highest_offset");
+ if ((err = qemuMonitorJSONDevGetBlockExtent(dev, extent)) !=
+ QEMU_MONITOR_BLOCK_EXTENT_ERROR_OK) {
+ qemuMonitorJSONReportBlockExtentError(err);
goto cleanup;
}
}