On Mon, Jun 22, 2015 at 17:06:42 -0600, Eric Blake wrote: > Implement the QMP side of asking qemu what node name it assigned > to an arbitrary top-level device node. Assumes that the caller > will have already validated that the device is qcow2 backed by > a block device, and that qemu auto-assigns node names. > > * src/qemu/qemu_monitor.h (qemuMonitorNodeNameLookup): New function. > * src/qemu/qemu_monitor.c (qemuMonitorNodeNameLookup): Likewise. > * src/qemu/qemu_monitor_json.h (qemuMonitorJSONNodeNameLookup): > Likewise. > * src/qemu/qemu_monitor_json.c (qemuMonitorJSONNodeNameLookup): > Likewise. > > Signed-off-by: Eric Blake <eblake@xxxxxxxxxx> > --- > src/qemu/qemu_monitor.c | 15 ++++++++- > src/qemu/qemu_monitor.h | 3 ++ > src/qemu/qemu_monitor_json.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_monitor_json.h | 3 ++ > 4 files changed, 97 insertions(+), 1 deletion(-) > ... > @@ -3900,6 +3902,81 @@ qemuMonitorJSONDiskNameLookup(qemuMonitorPtr mon, > } > > > +/* Look up the node name of the file underneath a qcow2 image. */ > +char * > +qemuMonitorJSONNodeNameLookup(qemuMonitorPtr mon, > + const char *device) > +{ > + char *ret = NULL; > + virJSONValuePtr cmd = NULL; > + virJSONValuePtr reply = NULL; > + virJSONValuePtr devices; > + size_t i; > + > + cmd = qemuMonitorJSONMakeCommand("query-blockstats", NULL); Since this is yet another function that would call query-blockstats ... > + if (!cmd) > + return NULL; > + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) > + goto cleanup; > + > + if (!(devices = virJSONValueObjectGetArray(reply, "return"))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("blockstats reply was missing device list")); > + goto cleanup; > + } > + > + for (i = 0; i < virJSONValueArraySize(devices); i++) { > + virJSONValuePtr dev = virJSONValueArrayGet(devices, i); > + virJSONValuePtr parent; > + const char *thisdev; > + const char *node; > + > + if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("blockstats entry was not in expected format")); > + goto cleanup; > + } > + > + if (!(thisdev = virJSONValueObjectGetString(dev, "device"))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("blockstats entry was not in expected format")); > + goto cleanup; > + } > + > + if (STRPREFIX(thisdev, QEMU_DRIVE_HOST_PREFIX)) > + thisdev += strlen(QEMU_DRIVE_HOST_PREFIX); > + if (STRNEQ(thisdev, device)) > + continue; > + > + if (!(parent = virJSONValueObjectGetObject(dev, "parent"))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("blockstats device %s missing parent node"), > + device); > + goto cleanup; > + } > + > + if (!(node = virJSONValueObjectGetString(parent, "node-name"))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("node name missing for device %s"), device); > + goto cleanup; > + } > + ignore_value(VIR_STRDUP(ret, node)); > + goto cleanup; > + } > + > + /* If we get here, we didn't find the device. */ > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("unable to find node name for device %s"), > + device); ... and works only on one device and thus needs to be re-called for every single disk I'd rather see us fold this code into qemuMonitorJSONGetOneBlockStatsInfo so that all the info can be returned via qemuMonitorJSONGetAllBlockStatsInfo. I'll post a series that kills qemuMonitorJSONGetBlockExtent since it's basically the same instance. Peter
Attachment:
signature.asc
Description: Digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list