Jonah Palmer <jonah.pal...@oracle.com> writes:

> No problem! Comments below:
>
> On 8/23/21 9:27 AM, Markus Armbruster wrote:

[...]

>> Hmm...  how is this enum used?  In this patch:
>>
>>      VirtioInfoList *qmp_x_debug_query_virtio(Error **errp)
>>      {
>>          VirtioInfoList *list = NULL;
>>          VirtioInfoList *node;
>>          VirtIODevice *vdev;
>>
>>          QTAILQ_FOREACH(vdev, &virtio_list, next) {
>>              DeviceState *dev = DEVICE(vdev);
>>              node = g_new0(VirtioInfoList, 1);
>>              node->value = g_new(VirtioInfo, 1);
>>              node->value->path = g_strdup(dev->canonical_path);
>> --->        node->value->type = qapi_enum_parse(&VirtioType_lookup, 
>> vdev->name,
>> --->                                            VIRTIO_TYPE_UNKNOWN, NULL);
>>              QAPI_LIST_PREPEND(list, node->value);
>>          }
>>
>>          return list;
>>      }
>>
>> This maps VirtioDevice member @name (a string) to an enum value.
>>
>> As far as I can tell, this member is set in virtio_init() only, to its
>> argument.  All callers pass string literals.  They also pass a numeric
>> device_id, and the two seem to match, e.g. "virtio-blk" and
>> VIRTIO_ID_BLOCK.
>>
>> Thus, the pairs (numeric device ID, string device ID) already exist in
>> the code, but not in a way that lets you map between them.  To get that,
>> you *duplicate* the pairs in QAPI.
>>
>> Having two copies means we get to keep them consistent.  Can we avoid
>> that?
>>
>> The enum has a special member 'unknown' that gets used when @name does
>> not parse as enum member, i.e. we failed at keeping the copies
>> consistent.  I'm afraid this sweeps a programming error under the rug.
>>
>> The enum has a bunch of dummy members like 'unknown-14' to make QAPI
>> generate numeric enum values match the device IDs.  Error prone.  Can't
>> see offhand why we need them to match.
>
> Sure, I don't mind doing this instead. Just as an FYI, from the previous
> RFC series (RFC v5 1/6), David recommended here that I create a list of
> all the types and in the same order as 
> include/standard-headers/linux/virtio_ids.h.
>
> The benefit from this was that we never have to convert between the QAPI 
> number
> and the header number.

Yes, but it comes with the disadvantages I listed above.

> Let me know if this is still something you'd like me to do!

I think it's simpler overall, especially if you can pick option
"2. Without QAPI enum VirtioType" below.

I could be wrong.  Suggest to try it out to see what you like better.

>>
>> What about the following.  Define a map from numeric device ID to
>> string, like so
>>
>>      const char *virtio_device_name[] = {
>>          [VIRTIO_ID_NET] = "virtio-net",
>>          [VIRTIO_ID_BLOCK] = "virtio-blk",
>>          ...
>>      }
>
> Sorry if this is obvious, but where should I define this mapping?
> virtio.c or virtio.h?

Variable definitions normally live in .c.

> Jonah
>
>> This lets you
>>
>> * map device ID to string by subscripting virtio_device_name[].
>>    Guarding with assert(device_id < G_N_ELEMENTS(virtio_device_name)) may
>>    be advisable.
>>
>> * map string to device ID by searching virtio_device_name[].  May want a
>>    function for that,
>>
>> Now you can have virtio_init() map parameter @device_id to string, and
>> drop parameter @name.
>>
>> Then you have two options:
>>
>> 1. With QAPI enum VirtioType
>>
>>     Define it without the special and the dummy members.
>>
>>     To map from string to QAPI enum, use qapi_enum_parse().
>>
>>     To map from QAPI enum to string, use VirtioType_str().
>>
>>     To map from QAPI enum to device ID, map through string.
>>
>> 2. Without QAPI enum VirtioType
>>
>>     Simply use uint16_t device_id, just like struct VirtioDevice.
>>
>> The choice between 1. and 2. depends on whether you actually need
>> additional functionality provided by QAPI, such as types being visible
>> in query-qmp-schema.
>>
>> [...]
>>


Reply via email to