[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] Confused by QOM: /machine/unattached/device[5]/dr-conne
From: |
Andreas Färber |
Subject: |
Re: [Qemu-devel] Confused by QOM: /machine/unattached/device[5]/dr-connector[255]/fdt |
Date: |
Wed, 9 Sep 2015 18:04:10 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 |
Am 09.09.2015 um 17:22 schrieb Markus Armbruster:
> Andreas Färber <address@hidden> writes:
>> Am 09.09.2015 um 16:38 schrieb Markus Armbruster:
>>> I ran into this:
>>>
>>> $ qemu-system-ppc64 -nodefaults -S -display none -monitor stdio
>>> -machine pseries-2.4
>>> QEMU 2.4.50 monitor - type 'help' for more information
>>> (qemu) qom-list /machine/unattached/device[5]/dr-connector[255]
>>> fdt (struct)
>>> entity-sense (uint32)
>>> name (string)
>>> connector_type (uint32)
>>> index (uint32)
>>> id (uint32)
>>> allocation-state (uint32)
>>> indicator-state (uint32)
>>> isolation-state (uint32)
>>> parent_bus (link<bus>)
>>> hotplugged (bool)
>>> hotpluggable (bool)
>>> realized (bool)
>>> type (string)
>>> (qemu) qom-list /machine/unattached/device[5]/dr-connector[255]/fdt
>>> Device '/machine/unattached/device[5]/dr-connector[255]/fdt' not found
>>>
>>> According to the first qom-list, .../fdt exists. According to the
>>> second, it doesn't.
>>
>> Actually this is fully expected: qom-list operates on QOM objects. The
>> fdt property returns a struct, which is considered a value QOM-wise, so
>> to read it you need to use qom-get, not qom-list.
>>
>> Now, it may well be that visiting a struct does not work as expected, I
>> remember we ran into issues there, that held up the qom-tree stuff...
>
> Okay, switching to QMP, because there's no qom-get in HMP (is that
> intentional?).
>
> QMP> { "execute": "qom-list", "arguments": { "path":
> "/machine/unattached/device[5]/dr-connector[255]" } }
> {"return": [{"name": "fdt", "type": "struct"}, {"name": "entity-sense",
> "type": "uint32"}, {"name": "name", "type": "string"}, {"name":
> "connector_type", "type": "uint32"}, {"name": "index", "type": "uint32"},
> {"name": "id", "type": "uint32"}, {"name": "allocation-state", "type":
> "uint32"}, {"name": "indicator-state", "type": "uint32"}, {"name":
> "isolation-state", "type": "uint32"}, {"name": "parent_bus", "type":
> "link<bus>"}, {"name": "hotplugged", "type": "bool"}, {"name":
> "hotpluggable", "type": "bool"}, {"name": "realized", "type": "bool"},
> {"name": "type", "type": "string"}]}
> QMP> { "execute": "qom-list", "arguments": { "path":
> "/machine/unattached/device[5]/dr-connector[255]/fdt" } }
> {"error": {"class": "DeviceNotFound", "desc": "Device
> '/machine/unattached/device[5]/dr-connector[255]/fdt' not found"}}
>
> Should qom-list really fail DeviceNotFound? I find it rather confusing.
> For what it's worth, attempting to read a directory fails with EISDIR,
> not ENOENT.
Listing a non-existing directory on my system results in:
ls: cannot access foo: No such file or directory
As for the DeviceNotFound, I merely implemented the HMP glue, so you
should rather direct such questions at Eric or Luiz (or Anthony).
I believe that an ObjectNotFound is out of the question, as any new code
would just use the Generic class.
>
> Moving on to my next confusion: qom-get.
>
> QMP> { "execute": "qom-get", "arguments": { "path":
> "/machine/unattached/device[5]/dr-connector[255]", "property": "fdt" } }
> {"return": {}}
>
> The return value {} is weird. Let's see where it comes from.
>
> qmp_qom_get() first calls object_resolve_path() on the path, then
> object_property_get_qobject() on the property. For our test case,
> object_resolve_path() succeeds. Now have a closer look at
> object_property_get_qobject()'s behavior:
>
> QObject *object_property_get_qobject(Object *obj, const char *name,
> Error **errp)
> {
> QObject *ret = NULL;
> Error *local_err = NULL;
> QmpOutputVisitor *mo;
>
> mo = qmp_output_visitor_new();
> object_property_get(obj, qmp_output_get_visitor(mo), name,
> &local_err);
>
> This call succeeds, and we enter the conditional.
>
> if (!local_err) {
> ret = qmp_output_get_qobject(mo);
>
> This call returns NULL.
>
> }
> error_propagate(errp, local_err);
>
> This sets *errp = NULL.
>
> qmp_output_visitor_cleanup(mo);
> return ret;
> }
>
> Function returns NULL without setting an error. Its function comment:
>
> /*
> * object_property_get_qobject:
> * @obj: the object
> * @name: the name of the property
> * @errp: returns an error if this function fails
> *
> * Returns: the value of the property, converted to QObject, or NULL if
> * an error occurs.
> */
>
> Is returning NULL without setting an error okay?
>
> Should it return qnull() instead? Then the QMP return value would be
> JSON null.
>
That smells like the StringOutputVisitor problem that was holding up HMP
qom-get:
http://patchwork.ozlabs.org/patch/449596/
IIRC I needed to add a test case - not sure if I did, and busy now.
Searching for that subject should find you the qom-get patch as well.
Regards,
Andreas
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton; HRB 21284 (AG Nürnberg)