diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 543384dc1c9b34596d0ae07b82bbce4bce60ded8..c9929c310779263fcd1920eea9b01b47dd59f91f 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1776,6 +1776,23 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon, return qemuMonitorJSONGetAllBlockStatsInfo(mon, ret_stats); } + +/* Updates "stats" to fill virtual and physical size of the image */ +int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon, + virHashTablePtr stats) +{ + VIR_DEBUG("mon=%p, stats=%p", mon, stats); + + if (!mon->json) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("block capacity/size info requires JSON monitor")); + return -1; + } + + return qemuMonitorJSONBlockStatsUpdateCapacity(mon, stats); +} + + /* Return 0 and update @nparams with the number of block stats * QEMU supports if success. Return -1 if failure. */ diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index adf18ab5e0b44c462401981a3c4f96ca770ad912..616d960b8fa409e257a9af57da45a516e7d28de0 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -358,12 +358,18 @@ struct _qemuBlockStats { long long wr_total_times; long long flush_req; long long flush_total_times; + unsigned long long capacity; + unsigned long long physical; }; int qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon, virHashTablePtr *ret_stats) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon, + virHashTablePtr stats) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon, int *nparams); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b3b64510124001aad5ecdefd0f5777928f8bac93..40446734d29fd4e9b909c96629cf03b493ab3c28 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1925,6 +1925,84 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, } +int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon, + virHashTablePtr stats) +{ + int ret = -1; + int rc; + size_t i; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + virJSONValuePtr devices; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-block", NULL))) + return -1; + + if ((rc = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + devices = virJSONValueObjectGet(reply, "return"); + if (!devices || devices->type != VIR_JSON_TYPE_ARRAY) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-block reply was missing device list")); + goto cleanup; + } + + for (i = 0; i < virJSONValueArraySize(devices); i++) { + virJSONValuePtr dev = virJSONValueArrayGet(devices, i); + virJSONValuePtr inserted; + virJSONValuePtr image; + qemuBlockStatsPtr bstats; + const char *devname; + + if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-block device entry was not " + "in expected format")); + goto cleanup; + } + + if (!(devname = virJSONValueObjectGetString(dev, "device"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-block device entry was not " + "in expected format")); + goto cleanup; + } + + if (STRPREFIX(devname, QEMU_DRIVE_HOST_PREFIX)) + devname += strlen(QEMU_DRIVE_HOST_PREFIX); + + /* ignore missing info */ + if (!(bstats = virHashLookup(stats, devname))) + continue; + + /* drive may be empty */ + if (!(inserted = virJSONValueObjectGet(dev, "inserted")) || + !(image = virJSONValueObjectGet(inserted, "image"))) + continue; + + 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; + } + + ret = 0; + + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + + int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon, int *nparams) { diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index ef9b552565a5d0325d972c15a61e3fa4b683f2a1..c7dd4162d9ed6d7868bfb5f481c44c987d5f9654 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -81,6 +81,8 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon, long long *errs); int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, virHashTablePtr *ret_stats); +int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon, + virHashTablePtr stats); int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon, int *nparams); int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,