On 09/25/2014 08:06 AM, Peter Krempa wrote: > From: Francesco Romani <fromani@xxxxxxxxxx> > > 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@xxxxxxxxxx> > Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> > --- > 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; > } > } > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list