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(a)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 | 63 ++++++++++++++++++++
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 | 13 +++-
src/remote_protocol-structs | 4 ++
tests/nodedevmdevctldata/mdevctl-create.argv | 1 +
tests/nodedevmdevctltest.c | 11 +++-
12 files changed, 140 insertions(+), 2 deletions(-)
create mode 100644 tests/nodedevmdevctldata/mdevctl-create.argv
diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h
index d9dac97147..71626bd837 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -138,6 +138,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 618778517b..1d13466fc1 100644
--- a/src/libvirt-nodedev.c
+++ b/src/libvirt-nodedev.c
@@ -843,6 +843,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 16022a74bf..7c812ebb6e 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -879,6 +879,7 @@ LIBVIRT_6.10.0 {
virDomainAuthorizedSSHKeysSet;
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 e38aef0656..dc41e937cd 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -889,6 +889,17 @@ nodeDeviceGetMdevctlUndefineCommand(const char *uuid)
}
+virCommandPtr
+nodeDeviceGetMdevctlCreateCommand(const char *uuid)
+{
+ return virCommandNewArgList(MDEVCTL,
+ "start",
+ "-u",
+ uuid,
+ NULL);
+
+}
+
static int
virMdevctlStop(virNodeDeviceDefPtr def)
{
@@ -919,6 +930,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)
@@ -1225,6 +1251,43 @@ nodeDeviceUndefine(virNodeDevicePtr device)
}
+int nodeDeviceCreate(virNodeDevicePtr device)
+{
+ int ret = -1;
+ virNodeDeviceObjPtr obj = NULL;
+ virNodeDeviceDefPtr def;
+
+ 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)) {
+ 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 e06d62cee6..58a5958f02 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -150,3 +150,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 d7521a9c18..54c9bb5f2b 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2340,6 +2340,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 de569b74e5..a592fcb31d 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 */
+ .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 7fee7539f0..a7cf227e53 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2155,6 +2155,10 @@ struct remote_node_device_undefine_args {
remote_nonnull_string name;
};
+struct remote_node_device_create_args {
+ remote_nonnull_string name;
+};
+
/*
* Events Register/Deregister:
@@ -6740,6 +6744,13 @@ enum remote_procedure {
* @priority: high
* @acl: node_device:delete
*/
- REMOTE_PROC_NODE_DEVICE_UNDEFINE = 427
+ REMOTE_PROC_NODE_DEVICE_UNDEFINE = 427,
+
+ /**
+ * @generate: both
+ * @priority: high
+ * @acl: node_device:start
+ */
+ REMOTE_PROC_NODE_DEVICE_CREATE = 428
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 6d136bdb66..0f35efc5b3 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;
};
@@ -3600,4 +3603,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425,
REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 426,
REMOTE_PROC_NODE_DEVICE_UNDEFINE = 427,
+ REMOTE_PROC_NODE_DEVICE_CREATE = 428,
};
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 753cfd273e..bc0b94f441 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;
}
@@ -426,6 +430,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)
@@ -450,6 +457,8 @@ mymain(void)
DO_TEST_UNDEFINE("d76a6b78-45ed-4149-a325-005f9abc5281");
+ DO_TEST_CREATE("8a05ad83-3472-497d-8631-8142f31460e8");
+
done:
nodedevTestDriverFree(driver);
--
2.26.2