api: add virNodeDeviceCreate()

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>
This commit is contained in:
Jonathon Jongsma 2020-06-18 10:21:13 -05:00
parent 5dc935805e
commit c0db1af2f8
12 changed files with 146 additions and 2 deletions

View File

@ -137,6 +137,8 @@ virNodeDevicePtr virNodeDeviceDefineXML(virConnectPtr conn,
int virNodeDeviceUndefine(virNodeDevicePtr dev);
int virNodeDeviceCreate(virNodeDevicePtr dev);
/**
* VIR_NODE_DEVICE_EVENT_CALLBACK:
*

View 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;
};

View 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

View 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 ....

View 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,

View 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);

View 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 */
};

View 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 */

View 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
};

View 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,
};

View File

@ -0,0 +1 @@
$MDEVCTL_BINARY$ start -u 8a05ad83-3472-497d-8631-8142f31460e8

View 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);