[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