[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