[libvirt PATCH v3 12/21] api: add virNodeDeviceDefineXML()

Jonathon Jongsma jjongsma at redhat.com
Thu Dec 24 14:14:36 UTC 2020


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                       |  1 +
 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                  | 17 +++-
 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, 239 insertions(+), 23 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 a473563857..3e57e9522a 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -132,6 +132,10 @@ virNodeDevicePtr        virNodeDeviceCreateXML  (virConnectPtr conn,
 
 int                     virNodeDeviceDestroy    (virNodeDevicePtr dev);
 
+virNodeDevicePtr virNodeDeviceDefineXML(virConnectPtr conn,
+                                        const char *xmlDesc,
+                                        unsigned int flags);
+
 /**
  * VIR_NODE_DEVICE_EVENT_CALLBACK:
  *
diff --git a/src/driver-nodedev.h b/src/driver-nodedev.h
index d0fc7f19cf..16d787f3fc 100644
--- a/src/driver-nodedev.h
+++ b/src/driver-nodedev.h
@@ -74,6 +74,11 @@ typedef virNodeDevicePtr
 typedef int
 (*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev);
 
+typedef virNodeDevicePtr
+(*virDrvNodeDeviceDefineXML)(virConnectPtr conn,
+                             const char *xmlDesc,
+                             unsigned int flags);
+
 typedef int
 (*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
                                            virNodeDevicePtr dev,
@@ -113,4 +118,5 @@ struct _virNodeDeviceDriver {
     virDrvNodeDeviceListCaps nodeDeviceListCaps;
     virDrvNodeDeviceCreateXML nodeDeviceCreateXML;
     virDrvNodeDeviceDestroy nodeDeviceDestroy;
+    virDrvNodeDeviceDefineXML nodeDeviceDefineXML;
 };
diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c
index 375b907852..15eb70218a 100644
--- a/src/libvirt-nodedev.c
+++ b/src/libvirt-nodedev.c
@@ -765,6 +765,48 @@ virNodeDeviceDestroy(virNodeDevicePtr dev)
 }
 
 
+/**
+ * virNodeDeviceDefineXML:
+ * @conn: pointer to the hypervisor connection
+ * @xmlDesc: string containing an XML description of the device to be defined
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Define a new device on the VM host machine, for example, a mediated device
+ *
+ * virNodeDeviceFree should be used to free the resources after the
+ * node device object is no longer needed.
+ *
+ * Returns a node device object if successful, NULL in case of failure
+ */
+virNodeDevicePtr
+virNodeDeviceDefineXML(virConnectPtr conn,
+                       const char *xmlDesc,
+                       unsigned int flags)
+{
+    VIR_DEBUG("conn=%p, xmlDesc=%s, flags=0x%x", conn, NULLSTR(xmlDesc), flags);
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, NULL);
+    virCheckReadOnlyGoto(conn->flags, error);
+    virCheckNonNullArgGoto(xmlDesc, error);
+
+    if (conn->nodeDeviceDriver &&
+        conn->nodeDeviceDriver->nodeDeviceDefineXML) {
+        virNodeDevicePtr dev = conn->nodeDeviceDriver->nodeDeviceDefineXML(conn, xmlDesc, flags);
+        if (dev == NULL)
+            goto error;
+        return dev;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(conn);
+    return NULL;
+}
+
+
 /**
  * virConnectNodeDeviceEventRegisterAny:
  * @conn: pointer to the connection
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index cf31f937d5..8fae4352ff 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -877,6 +877,7 @@ LIBVIRT_6.10.0 {
     global:
         virDomainAuthorizedSSHKeysGet;
         virDomainAuthorizedSSHKeysSet;
+        virNodeDeviceDefineXML;
 } LIBVIRT_6.0.0;
 
 # .... 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 0bebd534d0..4fbe8743b4 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -698,9 +698,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;
@@ -718,7 +722,7 @@ nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
         return NULL;
     }
 
-    cmd = virCommandNewArgList(MDEVCTL, "start",
+    cmd = virCommandNewArgList(MDEVCTL, subcommand,
                                "-p", parent_addr,
                                "--jsonfile", "/dev/stdin",
                                NULL);
@@ -729,6 +733,22 @@ nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
     return cmd;
 }
 
+virCommandPtr
+nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
+                                 char **uuid_out)
+{
+    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)
 {
@@ -749,6 +769,26 @@ virMdevctlStart(virNodeDeviceDefPtr def, char **uuid)
 }
 
 
+static int
+virMdevctlDefine(virNodeDeviceDefPtr def, char **uuid)
+{
+    int status;
+    g_autoptr(virCommand) cmd = nodeDeviceGetMdevctlDefineCommand(def, uuid);
+    if (!cmd)
+        return -1;
+
+    /* an auto-generated uuid is returned via stdout if no uuid is specified in
+     * the mdevctl args */
+    if (virCommandRun(cmd, &status) < 0 || status != 0)
+        return -1;
+
+    /* remove newline */
+    *uuid = g_strstrip(*uuid);
+
+    return 0;
+}
+
+
 static virNodeDevicePtr
 nodeDeviceCreateXMLMdev(virConnectPtr conn,
                         virNodeDeviceDefPtr def)
@@ -1068,6 +1108,55 @@ nodeDeviceDestroy(virNodeDevicePtr device)
     return ret;
 }
 
+virNodeDevicePtr
+nodeDeviceDefineXML(virConnectPtr conn,
+                    const char *xmlDesc,
+                    unsigned int flags)
+{
+    g_autoptr(virNodeDeviceDef) def = NULL;
+    virNodeDevicePtr device = NULL;
+    const char *virt_type = NULL;
+    g_autofree char *uuid = NULL;
+
+    virCheckFlags(0, NULL);
+
+    if (nodeDeviceWaitInit() < 0)
+        return NULL;
+
+    virt_type  = virConnectGetType(conn);
+
+    if (!(def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt_type)))
+        return NULL;
+
+    if (virNodeDeviceDefineXMLEnsureACL(conn, def) < 0)
+        return NULL;
+
+    if (!nodeDeviceHasCapability(def, VIR_NODE_DEV_CAP_MDEV)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Unsupported device type"));
+        return NULL;
+    }
+
+    if (!def->parent) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("cannot define a mediated device without a parent"));
+        return NULL;
+    }
+
+    if (virMdevctlDefine(def, &uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Unable to define mediated device"));
+        return NULL;
+    }
+
+    def->caps->data.mdev.uuid = g_strdup(uuid);
+    mdevGenerateDeviceName(def);
+    device = nodeDeviceFindNewMediatedDevice(conn, uuid);
+
+    return device;
+}
+
+
 
 int
 nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h
index 4315f6d6ed..e58bb0f124 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -102,6 +102,11 @@ nodeDeviceCreateXML(virConnectPtr conn,
 int
 nodeDeviceDestroy(virNodeDevicePtr dev);
 
+virNodeDevicePtr
+nodeDeviceDefineXML(virConnectPtr conn,
+                    const char *xmlDesc,
+                    unsigned int flags);
+
 int
 nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
                                       virNodeDevicePtr dev,
@@ -116,6 +121,11 @@ nodeConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
 virCommandPtr
 nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
                                  char **uuid_out);
+
+virCommandPtr
+nodeDeviceGetMdevctlDefineCommand(virNodeDeviceDefPtr def,
+                                  char **uuid_out);
+
 virCommandPtr
 nodeDeviceGetMdevctlStopCommand(const char *uuid);
 
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 5729fea264..2532c3189e 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2338,6 +2338,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
     .nodeDeviceListCaps = nodeDeviceListCaps, /* 0.7.3 */
     .nodeDeviceCreateXML = nodeDeviceCreateXML, /* 0.7.3 */
     .nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
+    .nodeDeviceDefineXML = nodeDeviceDefineXML, /* 6.5.0 */
 };
 
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index b0af3ee88e..f826b6f73e 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8665,6 +8665,7 @@ static virNodeDeviceDriver node_device_driver = {
     .nodeDeviceNumOfCaps = remoteNodeDeviceNumOfCaps, /* 0.5.0 */
     .nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
     .nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
+    .nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 6.5.0 */
     .nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
 };
 
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 2df38cef77..d2250502b4 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2142,6 +2142,15 @@ struct remote_node_device_destroy_args {
     remote_nonnull_string name;
 };
 
+struct remote_node_device_define_xml_args {
+    remote_nonnull_string xml_desc;
+    unsigned int flags;
+};
+
+struct remote_node_device_define_xml_ret {
+    remote_nonnull_node_device dev;
+};
+
 
 /*
  * Events Register/Deregister:
@@ -6714,5 +6723,11 @@ enum remote_procedure {
      * @generate: none
      * @acl: domain:write
      */
-    REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425
+    REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425,
+
+    /**
+     * @generate: both
+     * @acl: node_device:write
+     */
+    REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 426
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 9bcd14603d..565c1673f1 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1600,6 +1600,13 @@ struct remote_node_device_create_xml_ret {
 struct remote_node_device_destroy_args {
         remote_nonnull_string      name;
 };
+struct remote_node_device_define_xml_args {
+        remote_nonnull_string      xml_desc;
+        u_int                      flags;
+};
+struct remote_node_device_define_xml_ret {
+        remote_nonnull_node_device dev;
+};
 struct remote_connect_domain_event_register_ret {
         int                        cb_registered;
 };
@@ -3588,4 +3595,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_EVENT_MEMORY_FAILURE = 423,
         REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_GET = 424,
         REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425,
+        REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 426,
 };
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index 0020273d9e..30108272f1 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -567,6 +567,7 @@ elsif ($mode eq "server") {
             if ($argtype =~ m/^remote_node_device_/ and
                 !($argtype =~ m/^remote_node_device_lookup_by_name_/) and
                 !($argtype =~ m/^remote_node_device_create_xml_/) and
+                !($argtype =~ m/^remote_node_device_define_xml_/) and
                 !($argtype =~ m/^remote_node_device_lookup_scsi_host_by_wwn_/)) {
                 $has_node_device = 1;
                 push(@vars_list, "virNodeDevicePtr dev = NULL");
diff --git a/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.argv b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.argv
new file mode 100644
index 0000000000..773e98b963
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.argv
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ define -p 0000:00:02.0 --jsonfile /dev/stdin
diff --git a/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.json b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.json
new file mode 100644
index 0000000000..bfc6dcace3
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-define.json
@@ -0,0 +1 @@
+{"mdev_type":"i915-GVTg_V5_8","start":"manual"}
\ No newline at end of file
diff --git a/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.argv b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.argv
new file mode 100644
index 0000000000..773e98b963
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.argv
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ define -p 0000:00:02.0 --jsonfile /dev/stdin
diff --git a/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.json b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.json
new file mode 100644
index 0000000000..e5b22b2c44
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-define.json
@@ -0,0 +1 @@
+{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute-1":"attribute-value-1"},{"example-attribute-2":"attribute-value-2"}]}
\ No newline at end of file
diff --git a/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.argv b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.argv
new file mode 100644
index 0000000000..773e98b963
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.argv
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ define -p 0000:00:02.0 --jsonfile /dev/stdin
diff --git a/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.json b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.json
new file mode 100644
index 0000000000..2e03d0bd8e
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-define.json
@@ -0,0 +1 @@
+{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute":"attribute-value"}]}
\ No newline at end of file
diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c
index 8bc464d59f..981276d180 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;
+
 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 {
+        return -1;
+    }
 
-    g_autofree char *mdevxml = g_strdup_printf("%s/nodedevschemadata/%s.xml",
-                                               abs_srcdir, info->filename);
-    g_autofree char *cmdlinefile = g_strdup_printf("%s/nodedevmdevctldata/%s-start.argv",
-                                                   abs_srcdir, info->filename);
-    g_autofree char *jsonfile = g_strdup_printf("%s/nodedevmdevctldata/%s-start.json",
-                                                   abs_srcdir, info->filename);
+    mdevxml = g_strdup_printf("%s/nodedevschemadata/%s.xml", abs_srcdir,
+                              info->filename);
+    cmdlinefile = g_strdup_printf("%s/nodedevmdevctldata/%s-%s.argv",
+                                  abs_srcdir, info->filename, cmd);
+    jsonfile = g_strdup_printf("%s/nodedevmdevctldata/%s-%s.json", abs_srcdir,
+                               info->filename, cmd);
 
-    return testMdevctlStart(info->virt_type,
-                            info->create, mdevxml, cmdlinefile,
-                            jsonfile);
+    return testMdevctlStart(info->virt_type, info->create, func,
+                            mdevxml, cmdlinefile, jsonfile);
 }
 
 static int
@@ -347,15 +372,18 @@ mymain(void)
     if (virTestRun(desc, func, info) < 0) \
         ret = -1;
 
-#define DO_TEST_START_FULL(virt_type, create, filename) \
+#define DO_TEST_START_FULL(desc, virt_type, create, filename, command) \
     do { \
-        struct startTestInfo info = { virt_type, create, filename }; \
-        DO_TEST_FULL("mdevctl start " filename, testMdevctlStartHelper, &info); \
+        struct startTestInfo info = { virt_type, create, filename, command }; \
+        DO_TEST_FULL(desc, testMdevctlStartHelper, &info); \
        } \
     while (0)
 
 #define DO_TEST_START(filename) \
-    DO_TEST_START_FULL("QEMU", CREATE_DEVICE, filename)
+    DO_TEST_START_FULL("mdevctl start " filename, "QEMU", CREATE_DEVICE, filename, MDEVCTL_CMD_START)
+
+#define DO_TEST_DEFINE(filename) \
+    DO_TEST_START_FULL("mdevctl define " filename, "QEMU", CREATE_DEVICE, filename, MDEVCTL_CMD_DEFINE)
 
 #define DO_TEST_STOP(uuid) \
     DO_TEST_FULL("mdevctl stop " uuid, testMdevctlStop, uuid)
@@ -378,6 +406,10 @@ mymain(void)
 
     DO_TEST_PARSE_JSON("mdevctl-list-multiple");
 
+    DO_TEST_DEFINE("mdev_d069d019_36ea_4111_8f0a_8c9a70e21366");
+    DO_TEST_DEFINE("mdev_fedc4916_1ca8_49ac_b176_871d16c13076");
+    DO_TEST_DEFINE("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
+
  done:
     nodedevTestDriverFree(driver);
 
-- 
2.26.2




More information about the libvir-list mailing list