]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
api: add virNodeDeviceCreate()
authorJonathon Jongsma <jjongsma@redhat.com>
Thu, 18 Jun 2020 15:21:13 +0000 (10:21 -0500)
committerJonathon Jongsma <jjongsma@redhat.com>
Wed, 7 Apr 2021 20:14:01 +0000 (15:14 -0500)
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@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
12 files changed:
include/libvirt/libvirt-nodedev.h
src/driver-nodedev.h
src/libvirt-nodedev.c
src/libvirt_public.syms
src/node_device/node_device_driver.c
src/node_device/node_device_driver.h
src/node_device/node_device_udev.c
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs
tests/nodedevmdevctldata/mdevctl-create.argv [new file with mode: 0644]
tests/nodedevmdevctltest.c

index 623017f1fd59d1054ad40bf6115e334074e76117..cf51c3d085884aa526ded7abb1d107c8199865e0 100644 (file)
@@ -137,6 +137,8 @@ virNodeDevicePtr virNodeDeviceDefineXML(virConnectPtr conn,
 
 int virNodeDeviceUndefine(virNodeDevicePtr dev);
 
+int virNodeDeviceCreate(virNodeDevicePtr dev);
+
 /**
  * VIR_NODE_DEVICE_EVENT_CALLBACK:
  *
index e18029ab48e1c59f6a18c8d2643a6beedc5732b5..d2c7f7fe17b98b0d38d079bd7eb2be3cf8b1bf60 100644 (file)
@@ -82,6 +82,9 @@ typedef virNodeDevicePtr
 typedef int
 (*virDrvNodeDeviceUndefine)(virNodeDevicePtr dev);
 
+typedef int
+(*virDrvNodeDeviceCreate)(virNodeDevicePtr dev);
+
 typedef int
 (*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
                                            virNodeDevicePtr dev,
@@ -123,4 +126,5 @@ struct _virNodeDeviceDriver {
     virDrvNodeDeviceDestroy nodeDeviceDestroy;
     virDrvNodeDeviceDefineXML nodeDeviceDefineXML;
     virDrvNodeDeviceUndefine nodeDeviceUndefine;
+    virDrvNodeDeviceCreate nodeDeviceCreate;
 };
index 803fe7a1a64342e79ea0338d5b5c5ad4a7405cc4..477232f630a74bfded94ad4ca3672478147fbbd5 100644 (file)
@@ -815,6 +815,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
index f56d430495ebb57323fc5cd79b9b1a7a1b260057..5678a13cda26c668dbbbd9e181f937fae1aeddb1 100644 (file)
@@ -893,6 +893,7 @@ LIBVIRT_7.3.0 {
     global:
         virNodeDeviceDefineXML;
         virNodeDeviceUndefine;
+        virNodeDeviceCreate;
 } LIBVIRT_7.2.0;
 
 # .... define new API here using predicted next version number ....
index bf7fc08f8d36da72ef8355a03a6c281dd048a88a..e2e5c1cf4c91f07507a3476c85f8d3bdbcb47528 100644 (file)
@@ -903,6 +903,18 @@ nodeDeviceGetMdevctlUndefineCommand(const char *uuid, char **errmsg)
     return cmd;
 }
 
+virCommand*
+nodeDeviceGetMdevctlCreateCommand(const char *uuid, char **errmsg)
+{
+    virCommand *cmd = virCommandNewArgList(MDEVCTL,
+                                           "start",
+                                           "-u",
+                                           uuid,
+                                           NULL);
+    virCommandSetErrorBuffer(cmd, errmsg);
+    return cmd;
+}
+
 static int
 virMdevctlStop(virNodeDeviceDefPtr def, char **errmsg)
 {
@@ -934,6 +946,21 @@ virMdevctlUndefine(virNodeDeviceDef *def, char **errmsg)
 }
 
 
+static int
+virMdevctlCreate(virNodeDeviceDef *def, char **errmsg)
+{
+    int status;
+    g_autoptr(virCommand) cmd = NULL;
+
+    cmd = nodeDeviceGetMdevctlCreateCommand(def->caps->data.mdev.uuid, errmsg);
+
+    if (virCommandRun(cmd, &status) < 0 || status != 0)
+        return -1;
+
+    return 0;
+}
+
+
 virCommand*
 nodeDeviceGetMdevctlListCommand(bool defined,
                                 char **output,
@@ -1262,6 +1289,47 @@ nodeDeviceUndefine(virNodeDevice *device)
 }
 
 
+int
+nodeDeviceCreate(virNodeDevice *device)
+{
+    int ret = -1;
+    virNodeDeviceObj *obj = NULL;
+    virNodeDeviceDef *def = NULL;
+
+    if (!(obj = nodeDeviceObjFindByName(device->name)))
+        return -1;
+
+    if (virNodeDeviceObjIsActive(obj)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("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)) {
+        g_autofree char *errmsg = NULL;
+
+        if (virMdevctlCreate(def, &errmsg) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Unable to create mediated device: %s"),
+                           errmsg && errmsg[0] ? errmsg : "Unknown Error");
+            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,
index 0ec388d68d476fa8dede642f92e0f9933f3190ed..4d10be2611142efa225a053a2c82ef925f334c75 100644 (file)
@@ -159,3 +159,10 @@ nodeDeviceGenerateName(virNodeDeviceDef *def,
 
 bool nodeDeviceDefCopyFromMdevctl(virNodeDeviceDef *dst,
                                   virNodeDeviceDef *src);
+
+virCommand*
+nodeDeviceGetMdevctlCreateCommand(const char *uuid,
+                                  char **errmsg);
+
+int
+nodeDeviceCreate(virNodeDevice *dev);
index 0fb1630c9735c340d96dc608b503dd6c15455e98..77b5a56f3d53dcecb807f9bb5c421900c26b2825 100644 (file)
@@ -2327,6 +2327,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
     .nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
     .nodeDeviceDefineXML = nodeDeviceDefineXML, /* 7.2.0 */
     .nodeDeviceUndefine = nodeDeviceUndefine, /* 7.2.0 */
+    .nodeDeviceCreate = nodeDeviceCreate, /* 7.2.0 */
 };
 
 
index d3e21ea797d2dd7642b28a9ae71bca92996b7074..31b293ac4accf952a093a396741e2a4aee5d1c33 100644 (file)
@@ -8696,6 +8696,7 @@ static virNodeDeviceDriver node_device_driver = {
     .nodeDeviceNumOfCaps = remoteNodeDeviceNumOfCaps, /* 0.5.0 */
     .nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
     .nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
+    .nodeDeviceCreate = remoteNodeDeviceCreate, /* 7.2.0 */
     .nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 7.2.0 */
     .nodeDeviceUndefine = remoteNodeDeviceUndefine, /* 7.2.0 */
     .nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
index 9efaf00ac934c92f58479f56956afcf54b7f8b90..ecfc708fb70ce1a96e146951ccf078cc9ddea65a 100644 (file)
@@ -2158,6 +2158,10 @@ struct remote_node_device_undefine_args {
     remote_nonnull_string name;
 };
 
+struct remote_node_device_create_args {
+    remote_nonnull_string name;
+};
+
 
 /*
  * Events Register/Deregister:
@@ -6771,6 +6775,13 @@ enum remote_procedure {
      * @priority: high
      * @acl: node_device:delete
      */
-    REMOTE_PROC_NODE_DEVICE_UNDEFINE = 429
+    REMOTE_PROC_NODE_DEVICE_UNDEFINE = 429,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: node_device:start
+     */
+    REMOTE_PROC_NODE_DEVICE_CREATE = 430
 
 };
index 792e858770b4fcf478a8824a7fe1ad8cb2afcb60..15bd7ae8f0a90b120dfbf58f9ca1acc97e633ea8 100644 (file)
@@ -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;
 };
@@ -3617,4 +3620,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
         REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 428,
         REMOTE_PROC_NODE_DEVICE_UNDEFINE = 429,
+        REMOTE_PROC_NODE_DEVICE_CREATE = 430,
 };
diff --git a/tests/nodedevmdevctldata/mdevctl-create.argv b/tests/nodedevmdevctldata/mdevctl-create.argv
new file mode 100644 (file)
index 0000000..8021093
--- /dev/null
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ start -u 8a05ad83-3472-497d-8631-8142f31460e8
index 61a18c6e8d0ace8152f52e850dcfae43eaa5813e..050424116fe43f597437cc07a19b2f142547b89c 100644 (file)
@@ -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 {
@@ -188,6 +189,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;
     }
@@ -429,6 +433,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_TEST_FULL("mdevctl list --defined", testMdevctlListDefined, NULL)
 
@@ -453,6 +460,8 @@ mymain(void)
 
     DO_TEST_UNDEFINE("d76a6b78-45ed-4149-a325-005f9abc5281");
 
+    DO_TEST_CREATE("8a05ad83-3472-497d-8631-8142f31460e8");
+
  done:
     nodedevTestDriverFree(driver);