[libvirt PATCH v2 10/16] api: add virNodeDeviceDefineXML()
Erik Skultety
eskultet at redhat.com
Tue Aug 25 11:36:32 UTC 2020
On Tue, Aug 18, 2020 at 09:48:00AM -0500, Jonathon Jongsma wrote:
> With mediated devices, we can now define persistent node devices that
> can be started and stopped. In order to take advantage of this, we need
> an API to define new node devices.
>
> Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
> ---
> include/libvirt/libvirt-nodedev.h | 4 +
> src/driver-nodedev.h | 6 ++
> src/libvirt-nodedev.c | 42 ++++++++
> src/libvirt_public.syms | 4 +
> src/node_device/node_device_driver.c | 97 +++++++++++++++++--
> src/node_device/node_device_driver.h | 10 ++
> src/node_device/node_device_udev.c | 1 +
> src/remote/remote_driver.c | 1 +
> src/remote/remote_protocol.x | 18 +++-
> src/remote_protocol-structs | 8 ++
> src/rpc/gendispatch.pl | 1 +
> ...19_36ea_4111_8f0a_8c9a70e21366-define.argv | 1 +
> ...19_36ea_4111_8f0a_8c9a70e21366-define.json | 1 +
> ...39_495e_4243_ad9f_beb3f14c23d9-define.argv | 1 +
> ...39_495e_4243_ad9f_beb3f14c23d9-define.json | 1 +
> ...16_1ca8_49ac_b176_871d16c13076-define.argv | 1 +
> ...16_1ca8_49ac_b176_871d16c13076-define.json | 1 +
> tests/nodedevmdevctltest.c | 68 +++++++++----
> 18 files changed, 241 insertions(+), 25 deletions(-)
> create mode 100644 tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.argv
> create mode 100644 tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.json
> create mode 100644 tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.argv
> create mode 100644 tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.json
> create mode 100644 tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.argv
> create mode 100644 tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.json
>
> diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h
> index 423a583d45..02aa9d9750 100644
> --- a/include/libvirt/libvirt-nodedev.h
> +++ b/include/libvirt/libvirt-nodedev.h
> @@ -127,6 +127,10 @@ virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn,
>
> int virNodeDeviceDestroy (virNodeDevicePtr dev);
>
> +virNodeDevicePtr virNodeDeviceDefineXML (virConnectPtr conn,
> + const char *xmlDesc,
> + unsigned int flags);
Pre-existing, but this forced space-padded alignment feels weird nowadays and
we should use the same policy as for the internal headers - no padding, 1 blank
line separating the function declarations. In fact at the end of the header,
we're breaking the padded "consistency" anyway. So, I'd suggest to abandon
the padding, use a single space as a delimiter and we can send a follow-up
to fix the rest.
the public side of things looks good to me
...
>
> +LIBVIRT_6.5.0 {
> + global:
> + virNodeDeviceDefineXML;
> +} LIBVIRT_6.0.0;
6.8.0 - this is just a reminder as we've managed to push new symbols
referencing an old release once IIRC :)
> # .... define new API here using predicted next version number ....
> diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
> index affd707a65..16f3537776 100644
> --- a/src/node_device/node_device_driver.c
> +++ b/src/node_device/node_device_driver.c
> @@ -658,9 +658,13 @@ nodeDeviceFindAddressByName(const char *name)
> }
>
>
> -virCommandPtr
> -nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
> - char **uuid_out)
> +/* the mdevctl 'start' and 'define' commands accept almost the exact same
> + * arguments, so provide a common implementation that can be wrapped by a more
> + * specific function */
> +static virCommandPtr
> +nodeDeviceGetMdevctlDefineStartCommand(virNodeDeviceDefPtr def,
> + const char *subcommand,
> + char **uuid_out)
> {
> virCommandPtr cmd;
> g_autofree char *json = NULL;
> @@ -678,7 +682,7 @@ nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
> return NULL;
> }
>
> - cmd = virCommandNewArgList(MDEVCTL, "start",
> + cmd = virCommandNewArgList(MDEVCTL, subcommand,
> "-p", parent_pci,
> "--jsonfile", "/dev/stdin",
> NULL);
Okay, but could we actually make ^this function the internal "public" gateway
to all the mdevctl commands accepting a larger set of arguments and...
> @@ -689,11 +693,29 @@ nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
> return cmd;
> }
>
> +virCommandPtr
> +nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
> + char **uuid_out)
...make ^these the static implementations handling the subcommand nuances?
> +{
> + return nodeDeviceGetMdevctlDefineStartCommand(def, "start", uuid_out);
> +}
> +
> +virCommandPtr
> +nodeDeviceGetMdevctlDefineCommand(virNodeDeviceDefPtr def,
> + char **uuid_out)
> +{
> + return nodeDeviceGetMdevctlDefineStartCommand(def, "define", uuid_out);
> +}
> +
> +
> +
> static int
> -virMdevctlStart(virNodeDeviceDefPtr def, char **uuid)
> +virMdevctlDefineCommon(virNodeDeviceDefPtr def,
> + virCommandPtr (*func)(virNodeDeviceDefPtr, char**),
> + char **uuid)
> {
> int status;
> - g_autoptr(virCommand) cmd = nodeDeviceGetMdevctlStartCommand(def, uuid);
> + g_autoptr(virCommand) cmd = func(def, uuid);
> if (!cmd)
> return -1;
I'm not sure whether this standalone function brings that much value in terms
of abstracting code.
>
> @@ -709,6 +731,20 @@ virMdevctlStart(virNodeDeviceDefPtr def, char **uuid)
> }
>
>
> +static int
> +virMdevctlStart(virNodeDeviceDefPtr def, char **uuid)
> +{
> + return virMdevctlDefineCommon(def, nodeDeviceGetMdevctlStartCommand, uuid);
I wouldn't mind doing what virMdevctlDefineCommon does right here. In a later
patch you're introducing a virMdevctlCreate command which I think should
actually be part of this function with a bool selector whether we're starting a
transient or a persistent device.
> +}
> +
> +
> +static int
> +virMdevctlDefine(virNodeDeviceDefPtr def, char **uuid)
> +{
> + return virMdevctlDefineCommon(def, nodeDeviceGetMdevctlDefineCommand, uuid);
here too..
[snip]
> diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c
> index cee0d913dd..f821622ff6 100644
> --- a/tests/nodedevmdevctltest.c
> +++ b/tests/nodedevmdevctltest.c
> @@ -10,10 +10,16 @@
>
> #define VIR_FROM_THIS VIR_FROM_NODEDEV
>
> +typedef enum {
> + MDEVCTL_CMD_START,
> + MDEVCTL_CMD_DEFINE,
> +} MdevctlCmd;
Hmm, with the suggestion I outlined above, we could define all the commands
we're going to use as an enum in node_device_driver.h like VIR_ENUM_DECL.
> +
> struct startTestInfo {
> const char *virt_type;
> int create;
> const char *filename;
> + MdevctlCmd command;
> };
>
> /* capture stdin passed to command */
> @@ -45,12 +51,17 @@ nodedevCompareToFile(const char *actual,
> return virTestCompareToFile(replacedCmdline, filename);
> }
>
> +
> +typedef virCommandPtr (*GetStartDefineCmdFunc)(virNodeDeviceDefPtr, char **);
> +
> +
> static int
> testMdevctlStart(const char *virt_type,
> int create,
> + GetStartDefineCmdFunc get_cmd_func,
> const char *mdevxml,
> - const char *startcmdfile,
> - const char *startjsonfile)
> + const char *cmdfile,
> + const char *jsonfile)
> {
> g_autoptr(virNodeDeviceDef) def = NULL;
> virNodeDeviceObjPtr obj = NULL;
> @@ -66,7 +77,7 @@ testMdevctlStart(const char *virt_type,
>
> /* this function will set a stdin buffer containing the json configuration
> * of the device. The json value is captured in the callback above */
> - cmd = nodeDeviceGetMdevctlStartCommand(def, &uuid);
> + cmd = get_cmd_func(def, &uuid);
>
> if (!cmd)
> goto cleanup;
> @@ -78,10 +89,10 @@ testMdevctlStart(const char *virt_type,
> if (!(actualCmdline = virBufferCurrentContent(&buf)))
> goto cleanup;
>
> - if (nodedevCompareToFile(actualCmdline, startcmdfile) < 0)
> + if (nodedevCompareToFile(actualCmdline, cmdfile) < 0)
> goto cleanup;
>
> - if (virTestCompareToFile(stdinbuf, startjsonfile) < 0)
> + if (virTestCompareToFile(stdinbuf, jsonfile) < 0)
> goto cleanup;
>
> ret = 0;
> @@ -96,17 +107,31 @@ static int
> testMdevctlStartHelper(const void *data)
> {
> const struct startTestInfo *info = data;
> + const char *cmd;
> + GetStartDefineCmdFunc func;
> + g_autofree char *mdevxml = NULL;
> + g_autofree char *cmdlinefile = NULL;
> + g_autofree char *jsonfile = NULL;
> +
> + if (info->command == MDEVCTL_CMD_START) {
> + cmd = "start";
> + func = nodeDeviceGetMdevctlStartCommand;
> + } else if (info->command == MDEVCTL_CMD_DEFINE) {
> + cmd = "define";
> + func = nodeDeviceGetMdevctlDefineCommand;
> + } else {
^This would then not be needed and we'd simply call
virMdevctlGetCommand(def, MDEVCTL_COMMAND_<SUBCOMMAND>, ...)
More information about the libvir-list
mailing list