[libvirt] [PATCH 3/3] qemu: bulk stats: add block allocation information
John Ferlan
jferlan at redhat.com
Wed Oct 1 10:21:19 UTC 2014
On 09/25/2014 08:06 AM, Peter Krempa wrote:
> From: Francesco Romani <fromani at redhat.com>
>
> Management software wants to be able to allocate disk space on demand.
> To support this they need keep track of the space occupation of the
> block device. This information is reported by qemu as part of block
> stats.
>
> This patch extend the block information in the bulk stats with the
> allocation information.
>
> To keep the same behaviour a helper is extracted from
> qemuMonitorJSONGetBlockExtent in order to get per-device allocation
> information.
>
> Signed-off-by: Francesco Romani <fromani at redhat.com>
> Signed-off-by: Peter Krempa <pkrempa at redhat.com>
> ---
> src/libvirt.c | 6 +++
> src/qemu/qemu_driver.c | 27 +++++++++++++
> src/qemu/qemu_monitor.h | 1 +
> src/qemu/qemu_monitor_json.c | 91 ++++++++++++++++++++++++++++++++++----------
> 4 files changed, 105 insertions(+), 20 deletions(-)
>
,,,
> int qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index b634121..c41a7fb 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -1782,6 +1782,40 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
> }
>
>
> +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)
> {
> @@ -1908,6 +1942,9 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
> goto cleanup;
> }
>
> + /* it's ok to not have this information here. Just skip silently. */
> + qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
> +
> if (virHashAddEntry(hash, devname, bstats) < 0)
> goto cleanup;
> bstats = NULL;
> @@ -2077,6 +2114,36 @@ int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon,
> 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"));
> +
Missing a break;
(found by my monrning Coverity run)
John
> + 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)
> @@ -2111,9 +2178,8 @@ int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,
>
> 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"));
> @@ -2137,24 +2203,9 @@ int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,
> 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;
> }
> }
>
More information about the libvir-list
mailing list