[libvirt PATCH 15/16] api: add virNodeDeviceCreate()

Jonathon Jongsma jjongsma at redhat.com
Thu Jul 16 22:21:45 UTC 2020


This new API function provides a way to start a persistently-defined
mediate device that was defined by virNodeDeviceDefineXML() (or one that
was defined externally via mdevctl)

Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
---
 include/libvirt/libvirt-nodedev.h            |  2 +
 src/driver-nodedev.h                         |  4 ++
 src/libvirt-nodedev.c                        | 35 +++++++++++
 src/libvirt_public.syms                      |  1 +
 src/node_device/node_device_driver.c         | 64 ++++++++++++++++++++
 src/node_device/node_device_driver.h         |  6 ++
 src/node_device/node_device_udev.c           |  1 +
 src/remote/remote_driver.c                   |  1 +
 src/remote/remote_protocol.x                 | 14 ++++-
 src/remote_protocol-structs                  |  4 ++
 tests/nodedevmdevctldata/mdevctl-create.argv |  1 +
 tests/nodedevmdevctltest.c                   | 11 +++-
 12 files changed, 141 insertions(+), 3 deletions(-)
 create mode 100644 tests/nodedevmdevctldata/mdevctl-create.argv

diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h
index f7957499ae..cc6d4c8732 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -133,6 +133,8 @@ virNodeDevicePtr        virNodeDeviceDefineXML  (virConnectPtr conn,
 
 int                     virNodeDeviceUndefine   (virNodeDevicePtr dev);
 
+int                     virNodeDeviceCreate     (virNodeDevicePtr dev);
+
 /**
  * VIR_NODE_DEVICE_EVENT_CALLBACK:
  *
diff --git a/src/driver-nodedev.h b/src/driver-nodedev.h
index e18029ab48..d00dd5845c 100644
--- a/src/driver-nodedev.h
+++ b/src/driver-nodedev.h
@@ -82,6 +82,9 @@ typedef virNodeDevicePtr
 typedef int
 (*virDrvNodeDeviceUndefine)(virNodeDevicePtr dev);
 
+typedef int
+(*virDrvNodeDeviceCreate)(virNodeDevicePtr def);
+
 typedef int
 (*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
                                            virNodeDevicePtr dev,
@@ -123,4 +126,5 @@ struct _virNodeDeviceDriver {
     virDrvNodeDeviceDestroy nodeDeviceDestroy;
     virDrvNodeDeviceDefineXML nodeDeviceDefineXML;
     virDrvNodeDeviceUndefine nodeDeviceUndefine;
+    virDrvNodeDeviceCreate nodeDeviceCreate;
 };
diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c
index eb01ceb8b0..1b0671c92f 100644
--- a/src/libvirt-nodedev.c
+++ b/src/libvirt-nodedev.c
@@ -839,6 +839,41 @@ virNodeDeviceUndefine(virNodeDevicePtr dev)
 }
 
 
+/**
+ * virNodeDeviceCreate:
+ * @dev: a device object
+ *
+ * Start a defined node device. 
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virNodeDeviceCreate(virNodeDevicePtr dev)
+{
+    VIR_DEBUG("dev=%p", dev);
+
+    virResetLastError();
+
+    virCheckNodeDeviceReturn(dev, -1);
+    virCheckReadOnlyGoto(dev->conn->flags, error);
+
+    if (dev->conn->nodeDeviceDriver &&
+        dev->conn->nodeDeviceDriver->nodeDeviceCreate) {
+        int retval = dev->conn->nodeDeviceDriver->nodeDeviceCreate(dev);
+        if (retval < 0)
+            goto error;
+
+        return 0;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(dev->conn);
+    return -1;
+}
+
+
 /**
  * virConnectNodeDeviceEventRegisterAny:
  * @conn: pointer to the connection
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 35c88ec4b7..fa7144cec1 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -877,5 +877,6 @@ LIBVIRT_6.5.0 {
     global:
         virNodeDeviceDefineXML;
         virNodeDeviceUndefine;
+        virNodeDeviceCreate;
 } 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 ab15e82660..51b66ee3d0 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -844,6 +844,17 @@ nodeDeviceGetMdevctlUndefineCommand(const char *uuid)
 
 }
 
+virCommandPtr
+nodeDeviceGetMdevctlCreateCommand(const char *uuid)
+{
+    return virCommandNewArgList(MDEVCTL,
+                                "start",
+                                "-u",
+                                uuid,
+                                NULL);
+
+}
+
 static int
 virMdevctlStop(virNodeDeviceDefPtr def)
 {
@@ -874,6 +885,21 @@ virMdevctlUndefine(virNodeDeviceDefPtr def)
 }
 
 
+static int
+virMdevctlCreate(virNodeDeviceDefPtr def)
+{
+    int status;
+    g_autoptr(virCommand) cmd = NULL;
+
+    cmd = nodeDeviceGetMdevctlCreateCommand(def->caps->data.mdev.uuid);
+
+    if (virCommandRun(cmd, &status) < 0 || status != 0)
+        return -1;
+
+    return 0;
+}
+
+
 virCommandPtr
 nodeDeviceGetMdevctlListCommand(bool defined,
                                 char **output)
@@ -1160,6 +1186,44 @@ nodeDeviceUndefine(virNodeDevicePtr device)
 }
 
 
+int nodeDeviceCreate(virNodeDevicePtr device)
+{
+    int ret = -1;
+    virNodeDeviceObjPtr obj = NULL;
+    virNodeDeviceDefPtr def;
+    g_autofree char *parent = NULL;
+
+    if (!(obj = nodeDeviceObjFindByName(device->name)))
+        return -1;
+
+    if (virNodeDeviceObjIsActive(obj)) {
+        virReportError(VIR_ERR_OPERATION_INVALID,
+                       _("Device is already active"));
+        goto cleanup;
+    }
+    def = virNodeDeviceObjGetDef(obj);
+
+    if (virNodeDeviceCreateEnsureACL(device->conn, def) < 0)
+        goto cleanup;
+
+    if (nodeDeviceHasCapability(def, VIR_NODE_DEV_CAP_MDEV)) {
+        if (virMdevctlCreate(def) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to create mediated device"));
+            goto cleanup;
+        }
+        ret = 0;
+    } else {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Unsupported device type"));
+    }
+
+ cleanup:
+    virNodeDeviceObjEndAPI(&obj);
+    return ret;
+}
+
+
 int
 nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
                                       virNodeDevicePtr device,
diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h
index 2adb3a8073..939718effb 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -155,3 +155,9 @@ nodeDeviceGenerateName(virNodeDeviceDefPtr def,
                        const char *subsystem,
                        const char *sysname,
                        const char *s);
+
+virCommandPtr
+nodeDeviceGetMdevctlCreateCommand(const char *uuid);
+
+int
+nodeDeviceCreate(virNodeDevicePtr dev);
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 0eb3dea1d6..1e021aa913 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2200,6 +2200,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
     .nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
     .nodeDeviceDefineXML = nodeDeviceDefineXML, /* 6.5.0 */
     .nodeDeviceUndefine = nodeDeviceUndefine, /* 6.5.0 */
+    .nodeDeviceCreate = nodeDeviceCreate, /* 6.5.0 */
 };
 
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index eb102b6060..f2f4a42651 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8814,6 +8814,7 @@ static virNodeDeviceDriver node_device_driver = {
     .nodeDeviceNumOfCaps = remoteNodeDeviceNumOfCaps, /* 0.5.0 */
     .nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
     .nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
+    .nodeDeviceCreate = remoteNodeDeviceCreate, /* 6.5.0 */
     .nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 6.5.0 */
     .nodeDeviceUndefine = remoteNodeDeviceUndefine, /* 6.5.0 */
     .nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index d668074204..b019f38efd 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2152,6 +2152,10 @@ struct remote_node_device_undefine_args {
     remote_nonnull_string name;
 };
 
+struct remote_node_device_create_args {
+    remote_nonnull_string name;
+};
+
 
 /*
  * Events Register/Deregister:
@@ -6682,7 +6686,6 @@ enum remote_procedure {
     /**
      * @generate: both
      * @acl: node_device:write
-     * @acl: node_device:start
      */
     REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 423,
 
@@ -6691,6 +6694,13 @@ enum remote_procedure {
      * @priority: high
      * @acl: node_device:stop
      */
-    REMOTE_PROC_NODE_DEVICE_UNDEFINE = 424
+    REMOTE_PROC_NODE_DEVICE_UNDEFINE = 424,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: node_device:start
+     */
+    REMOTE_PROC_NODE_DEVICE_CREATE = 425
 
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 3d450a6de9..a3cfe2572e 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1610,6 +1610,9 @@ struct remote_node_device_define_xml_ret {
 struct remote_node_device_undefine_args {
         remote_nonnull_string      name;
 };
+struct remote_node_device_create_args {
+        remote_nonnull_string      name;
+};
 struct remote_connect_domain_event_register_ret {
         int                        cb_registered;
 };
@@ -3570,4 +3573,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422,
         REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 423,
         REMOTE_PROC_NODE_DEVICE_UNDEFINE = 424,
+        REMOTE_PROC_NODE_DEVICE_CREATE = 425,
 };
diff --git a/tests/nodedevmdevctldata/mdevctl-create.argv b/tests/nodedevmdevctldata/mdevctl-create.argv
new file mode 100644
index 0000000000..802109340c
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdevctl-create.argv
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ start -u 8a05ad83-3472-497d-8631-8142f31460e8
diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c
index fbc178a4ac..c768c841b4 100644
--- a/tests/nodedevmdevctltest.c
+++ b/tests/nodedevmdevctltest.c
@@ -14,7 +14,8 @@ typedef enum {
     MDEVCTL_CMD_START,
     MDEVCTL_CMD_STOP,
     MDEVCTL_CMD_DEFINE,
-    MDEVCTL_CMD_UNDEFINE
+    MDEVCTL_CMD_UNDEFINE,
+    MDEVCTL_CMD_CREATE
 } MdevctlCmd;
 
 struct startTestInfo {
@@ -186,6 +187,9 @@ testMdevctlUuidCommandHelper(const void *data)
     }else if (info->command == MDEVCTL_CMD_UNDEFINE) {
         cmd = "undefine";
         func = nodeDeviceGetMdevctlUndefineCommand;
+    }else if (info->command == MDEVCTL_CMD_CREATE) {
+        cmd = "create";
+        func = nodeDeviceGetMdevctlCreateCommand;
     } else {
         return -1;
     }
@@ -431,6 +435,9 @@ mymain(void)
 #define DO_TEST_UNDEFINE(uuid) \
     DO_TEST_UUID_COMMAND_FULL("mdevctl undefine " uuid, uuid, MDEVCTL_CMD_UNDEFINE)
 
+#define DO_TEST_CREATE(uuid) \
+    DO_TEST_UUID_COMMAND_FULL("mdevctl create " uuid, uuid, MDEVCTL_CMD_CREATE)
+
 #define DO_TEST_LIST_DEFINED() \
     do { \
         if (virTestRun("mdevctl list --defined", testMdevctlListDefined, NULL) < 0) \
@@ -461,6 +468,8 @@ mymain(void)
 
     DO_TEST_UNDEFINE("d76a6b78-45ed-4149-a325-005f9abc5281");
 
+    DO_TEST_CREATE("8a05ad83-3472-497d-8631-8142f31460e8");
+
  done:
     nodedevTestDriverFree(driver);
 
-- 
2.21.3




More information about the libvir-list mailing list