[libvirt] [PATCHv3 7/8] qemu: bulk stats: add block allocation information

Peter Krempa pkrempa at redhat.com
Tue Sep 9 13:19:28 UTC 2014


On 09/08/14 15:05, Francesco Romani wrote:
> Management software, want to be able to allocate disk space on demand.

s/, want/ wants/

> To support this, they need keep track of the space occupation

s/,//

> 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, an helper is extracted from

s/,// s/an/a/

> qemuMonitorJSONGetBlockExtent in order to get per-device
> allocation information.
> 
> Signed-off-by: Francesco Romani <fromani at redhat.com>
> ---
>  src/libvirt.c                |  2 ++
>  src/qemu/qemu_driver.c       | 15 +++++++++
>  src/qemu/qemu_monitor.h      |  1 +
>  src/qemu/qemu_monitor_json.c | 76 ++++++++++++++++++++++++++++++++------------
>  4 files changed, 73 insertions(+), 21 deletions(-)
> 


> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index aa95e71..bc5616d 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -1776,6 +1776,55 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
>  }
>  
>  
> +/* This helper function could be called in the
> + * qemuMonitorJSONGetAllBlockStatsInfo
> + * path - which is used also by the
> + * qemuMonitorJSONGetBlockStatsInfo
> + * path. In this case, we don't know in advance if the wr_highest_offset
> + * field is there, so it is OK to fail silently.
> + * However, we can get here by the
> + * qemuMonitorJSONGetBlockExtent
> + * path, and in that case we _must_ fail loudly.
> + */
> +static int
> +qemuMonitorJSONDevGetBlockExtent(virJSONValuePtr dev,
> +                                 bool report_error,
> +                                 unsigned long long *extent)
> +{
> +    virJSONValuePtr stats;
> +    virJSONValuePtr parent;
> +
> +    if ((parent = virJSONValueObjectGet(dev, "parent")) == NULL ||
> +        parent->type != VIR_JSON_TYPE_OBJECT) {
> +        if (report_error)
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("blockstats parent entry was not in "
> +                             "expected format"));
> +        return -1;
> +    }
> +
> +    if ((stats = virJSONValueObjectGet(parent, "stats")) == NULL ||
> +        stats->type != VIR_JSON_TYPE_OBJECT) {
> +        if (report_error)
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("blockstats stats entry was not in "
> +                             "expected format"));
> +        return -1;
> +    }
> +
> +    if (virJSONValueObjectGetNumberUlong(stats, "wr_highest_offset",
> +                                         extent) < 0) {
> +        if (report_error)
> +            virReportError(VIR_ERR_INTERNAL_ERROR,
> +                           _("cannot read %s statistic"),
> +                           "wr_highest_offset");
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +
>  int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
>                                          const char *dev_name,
>                                          qemuBlockStatsPtr bstats,
> @@ -1919,6 +1968,10 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
>              goto cleanup;
>          }
>  
> +        /* it's ok to not have this information here. Just skip silently. */
> +        qemuMonitorJSONDevGetBlockExtent(dev, false,
> +                                         &bstats->wr_highest_offset);

As you want to ignore errors, it would probably be better just to copy
the extraction code here without error reporting rather than extracting
it to a helper ... this isn't something that would be reused any more.

> +
>          ret++;
>          bstats++;
>      }
> @@ -2010,6 +2063,7 @@ int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon,
>      return ret;
>  }
>  
> +
>  int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,
>                                    const char *dev_name,
>                                    unsigned long long *extent)
> @@ -2044,8 +2098,6 @@ int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,
>  
>      for (i = 0; i < virJSONValueArraySize(devices); i++) {
>          virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
> -        virJSONValuePtr stats;
> -        virJSONValuePtr parent;
>          const char *thisdev;
>          if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
>              virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> @@ -2070,26 +2122,8 @@ 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"));
> +        if (qemuMonitorJSONDevGetBlockExtent(dev, true, extent) < 0)
>              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");
> -            goto cleanup;
> -        }
>      }
>  
>      if (!found) {
> 

Peter

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140909/5a411875/attachment-0001.sig>


More information about the libvir-list mailing list