On 7/22/20 7:42 AM, Richard W.M. Jones wrote:
Updated proposal, taking into account the default export. Instead
of
adding a second call, I made a couple of changes to list_exports:
(1) If the plugin has a concept of a default export, it should add it
as the first element in the exports list.
(2) There is a new default_only flag which tells the plugin that the
client is trying to request the name of the default export, so the
plugin may return only a single element. However it's fine for
plugins to ignore this flag.
Works for me. Also, a plugin can implement the callback and set 0
exports, which is different from omitting the callback which always
provides "" as one export. Returning 0 exports may make it harder for
clients to actually make a meaningful connection, but that situation can
indeed make sense (such as the file plugin set to serve all files in a
directory by exportname, but the directory is empty).
What about plugins that don't have any concept of a default export?
This makes the default export be whatever happens to be first in the
list. Not sure if this is a bad thing or not.
I'm not seeing it as too bad of a problem. A client that does not call
NBD_OPT_LIST will never know the difference, and the plugin can still
choose whether to accept or reject "" as a valid export name.
So far, the patch is just about public interface. Implementation-wise,
I see no problem with providing either of two implementations, with the
user none the wiser other than observing memory usage and timing:
idea 1:
struct nbdkit_exports is merely a vector of {name,description} pairs.
During .list_exports, nbdkit_add_export merely strdup's its input onto
the growing list stored in memory, and then after .list_exports returns,
that list is used by the various clients:
- implementing NBD_OPT_LIST traverses the list calling NBD_REP_SERVER
for each list element, then ends with NBD_REP_ACK
- implementing NBD_OPT_INFO("") scrapes the first element out of the
list, and ignores the rest
nbdkit then has to free the list after use.
idea 2:
struct nbdkit_exports wraps a function pointer. nbdkit_add_export then
triggers a call to that underlying function.
- implementing NBD_OPT_LIST sets a function pointer that directly
replies with NBD_REP_SERVER each time it is called (works since
handshake phase is synchronous - there is no other traffic in parallel
on that connection to worry about). When .list_exports returns, all that
is left is sending NBD_REP_ACK
- implementing NBD_OPT_INFO("") sets an initial function pointer that
grabs info on the first call, then alters to a second function pointer
that is a no-op for remaining calls
since there was no copying of strings, there is no further cleanup needed
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org