mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 03:25:20 +00:00
api: add virNodeDeviceUndefine()
This interface allows you to undefine a persistently defined (but inactive) mediated devices. It is implemented via 'mdevctl' Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
f98c415f8a
commit
bb311cede7
@ -135,6 +135,8 @@ virNodeDevicePtr virNodeDeviceDefineXML(virConnectPtr conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
|
||||
int virNodeDeviceUndefine(virNodeDevicePtr dev);
|
||||
|
||||
/**
|
||||
* VIR_NODE_DEVICE_EVENT_CALLBACK:
|
||||
*
|
||||
|
@ -70,7 +70,7 @@ VIR_ENUM_IMPL(virAccessPermNodeDevice,
|
||||
VIR_ACCESS_PERM_NODE_DEVICE_LAST,
|
||||
"getattr", "read", "write",
|
||||
"start", "stop",
|
||||
"detach",
|
||||
"detach", "delete",
|
||||
);
|
||||
|
||||
VIR_ENUM_IMPL(virAccessPermNWFilter,
|
||||
|
@ -500,6 +500,12 @@ typedef enum {
|
||||
*/
|
||||
VIR_ACCESS_PERM_NODE_DEVICE_DETACH,
|
||||
|
||||
/**
|
||||
* @desc: Delete node device
|
||||
* @message: Deleting node device driver requires authorization
|
||||
*/
|
||||
VIR_ACCESS_PERM_NODE_DEVICE_DELETE,
|
||||
|
||||
VIR_ACCESS_PERM_NODE_DEVICE_LAST
|
||||
} virAccessPermNodeDevice;
|
||||
|
||||
|
@ -79,6 +79,9 @@ typedef virNodeDevicePtr
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
|
||||
typedef int
|
||||
(*virDrvNodeDeviceUndefine)(virNodeDevicePtr dev);
|
||||
|
||||
typedef int
|
||||
(*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
|
||||
virNodeDevicePtr dev,
|
||||
@ -119,4 +122,5 @@ struct _virNodeDeviceDriver {
|
||||
virDrvNodeDeviceCreateXML nodeDeviceCreateXML;
|
||||
virDrvNodeDeviceDestroy nodeDeviceDestroy;
|
||||
virDrvNodeDeviceDefineXML nodeDeviceDefineXML;
|
||||
virDrvNodeDeviceUndefine nodeDeviceUndefine;
|
||||
};
|
||||
|
@ -779,6 +779,42 @@ virNodeDeviceDefineXML(virConnectPtr conn,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virNodeDeviceUndefine:
|
||||
* @dev: a device object
|
||||
*
|
||||
* Undefine the device object. The virtual device is removed from the host
|
||||
* operating system. This function may require privileged access.
|
||||
*
|
||||
* Returns 0 in case of success and -1 in case of failure.
|
||||
*/
|
||||
int
|
||||
virNodeDeviceUndefine(virNodeDevicePtr dev)
|
||||
{
|
||||
VIR_DEBUG("dev=%p", dev);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
virCheckNodeDeviceReturn(dev, -1);
|
||||
virCheckReadOnlyGoto(dev->conn->flags, error);
|
||||
|
||||
if (dev->conn->nodeDeviceDriver &&
|
||||
dev->conn->nodeDeviceDriver->nodeDeviceUndefine) {
|
||||
int retval = dev->conn->nodeDeviceDriver->nodeDeviceUndefine(dev);
|
||||
if (retval < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virReportUnsupportedError();
|
||||
|
||||
error:
|
||||
virDispatchError(dev->conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virConnectNodeDeviceEventRegisterAny:
|
||||
* @conn: pointer to the connection
|
||||
|
@ -892,6 +892,7 @@ LIBVIRT_7.2.0 {
|
||||
LIBVIRT_7.3.0 {
|
||||
global:
|
||||
virNodeDeviceDefineXML;
|
||||
virNodeDeviceUndefine;
|
||||
} LIBVIRT_7.2.0;
|
||||
|
||||
# .... define new API here using predicted next version number ....
|
||||
|
@ -891,6 +891,18 @@ nodeDeviceGetMdevctlStopCommand(const char *uuid, char **errmsg)
|
||||
|
||||
}
|
||||
|
||||
virCommand *
|
||||
nodeDeviceGetMdevctlUndefineCommand(const char *uuid, char **errmsg)
|
||||
{
|
||||
virCommand *cmd = virCommandNewArgList(MDEVCTL,
|
||||
"undefine",
|
||||
"-u",
|
||||
uuid,
|
||||
NULL);
|
||||
virCommandSetErrorBuffer(cmd, errmsg);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static int
|
||||
virMdevctlStop(virNodeDeviceDefPtr def, char **errmsg)
|
||||
{
|
||||
@ -906,6 +918,22 @@ virMdevctlStop(virNodeDeviceDefPtr def, char **errmsg)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virMdevctlUndefine(virNodeDeviceDef *def, char **errmsg)
|
||||
{
|
||||
int status;
|
||||
g_autoptr(virCommand) cmd = NULL;
|
||||
|
||||
cmd = nodeDeviceGetMdevctlUndefineCommand(def->caps->data.mdev.uuid,
|
||||
errmsg);
|
||||
|
||||
if (virCommandRun(cmd, &status) < 0 || status != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virCommand*
|
||||
nodeDeviceGetMdevctlListCommand(bool defined,
|
||||
char **output,
|
||||
@ -1188,6 +1216,51 @@ nodeDeviceDefineXML(virConnect *conn,
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nodeDeviceUndefine(virNodeDevice *device)
|
||||
{
|
||||
int ret = -1;
|
||||
virNodeDeviceObj *obj = NULL;
|
||||
virNodeDeviceDef *def;
|
||||
|
||||
if (nodeDeviceWaitInit() < 0)
|
||||
return -1;
|
||||
|
||||
if (!(obj = nodeDeviceObjFindByName(device->name)))
|
||||
return -1;
|
||||
|
||||
def = virNodeDeviceObjGetDef(obj);
|
||||
|
||||
if (virNodeDeviceUndefineEnsureACL(device->conn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!virNodeDeviceObjIsPersistent(obj)) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||
_("Node device '%s' is not defined"),
|
||||
def->name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (nodeDeviceHasCapability(def, VIR_NODE_DEV_CAP_MDEV)) {
|
||||
g_autofree char *errmsg = NULL;
|
||||
|
||||
if (virMdevctlUndefine(def, &errmsg) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Unable to undefine 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,
|
||||
|
@ -107,6 +107,9 @@ nodeDeviceDefineXML(virConnect *conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
|
||||
int
|
||||
nodeDeviceUndefine(virNodeDevice *dev);
|
||||
|
||||
int
|
||||
nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
||||
virNodeDevicePtr dev,
|
||||
@ -132,6 +135,10 @@ virCommandPtr
|
||||
nodeDeviceGetMdevctlStopCommand(const char *uuid,
|
||||
char **errmsg);
|
||||
|
||||
virCommand *
|
||||
nodeDeviceGetMdevctlUndefineCommand(const char *uuid,
|
||||
char **errmsg);
|
||||
|
||||
virCommandPtr
|
||||
nodeDeviceGetMdevctlListCommand(bool defined,
|
||||
char **output,
|
||||
|
@ -2326,6 +2326,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
|
||||
.nodeDeviceCreateXML = nodeDeviceCreateXML, /* 0.7.3 */
|
||||
.nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
|
||||
.nodeDeviceDefineXML = nodeDeviceDefineXML, /* 7.2.0 */
|
||||
.nodeDeviceUndefine = nodeDeviceUndefine, /* 7.2.0 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -8697,6 +8697,7 @@ static virNodeDeviceDriver node_device_driver = {
|
||||
.nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
|
||||
.nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
|
||||
.nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 7.2.0 */
|
||||
.nodeDeviceUndefine = remoteNodeDeviceUndefine, /* 7.2.0 */
|
||||
.nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
|
||||
};
|
||||
|
||||
|
@ -2154,6 +2154,10 @@ struct remote_node_device_define_xml_ret {
|
||||
remote_nonnull_node_device dev;
|
||||
};
|
||||
|
||||
struct remote_node_device_undefine_args {
|
||||
remote_nonnull_string name;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Events Register/Deregister:
|
||||
@ -6760,5 +6764,13 @@ enum remote_procedure {
|
||||
* @generate: both
|
||||
* @acl: node_device:write
|
||||
*/
|
||||
REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 428
|
||||
REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 428,
|
||||
|
||||
/**
|
||||
* @generate: both
|
||||
* @priority: high
|
||||
* @acl: node_device:delete
|
||||
*/
|
||||
REMOTE_PROC_NODE_DEVICE_UNDEFINE = 429
|
||||
|
||||
};
|
||||
|
@ -1607,6 +1607,9 @@ struct remote_node_device_define_xml_args {
|
||||
struct remote_node_device_define_xml_ret {
|
||||
remote_nonnull_node_device dev;
|
||||
};
|
||||
struct remote_node_device_undefine_args {
|
||||
remote_nonnull_string name;
|
||||
};
|
||||
struct remote_connect_domain_event_register_ret {
|
||||
int cb_registered;
|
||||
};
|
||||
@ -3613,4 +3616,5 @@ enum remote_procedure {
|
||||
REMOTE_PROC_DOMAIN_GET_MESSAGES = 426,
|
||||
REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
|
||||
REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 428,
|
||||
REMOTE_PROC_NODE_DEVICE_UNDEFINE = 429,
|
||||
};
|
||||
|
1
tests/nodedevmdevctldata/mdevctl-undefine.argv
Normal file
1
tests/nodedevmdevctldata/mdevctl-undefine.argv
Normal file
@ -0,0 +1 @@
|
||||
$MDEVCTL_BINARY$ undefine -u d76a6b78-45ed-4149-a325-005f9abc5281
|
@ -185,6 +185,9 @@ testMdevctlUuidCommandHelper(const void *data)
|
||||
if (info->command == MDEVCTL_CMD_STOP) {
|
||||
cmd = "stop";
|
||||
func = nodeDeviceGetMdevctlStopCommand;
|
||||
} else if (info->command == MDEVCTL_CMD_UNDEFINE) {
|
||||
cmd = "undefine";
|
||||
func = nodeDeviceGetMdevctlUndefineCommand;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@ -423,6 +426,9 @@ mymain(void)
|
||||
#define DO_TEST_STOP(uuid) \
|
||||
DO_TEST_UUID_COMMAND_FULL("mdevctl stop " uuid, uuid, MDEVCTL_CMD_STOP)
|
||||
|
||||
#define DO_TEST_UNDEFINE(uuid) \
|
||||
DO_TEST_UUID_COMMAND_FULL("mdevctl undefine " uuid, uuid, MDEVCTL_CMD_UNDEFINE)
|
||||
|
||||
#define DO_TEST_LIST_DEFINED() \
|
||||
DO_TEST_FULL("mdevctl list --defined", testMdevctlListDefined, NULL)
|
||||
|
||||
@ -445,6 +451,8 @@ mymain(void)
|
||||
DO_TEST_DEFINE("mdev_fedc4916_1ca8_49ac_b176_871d16c13076");
|
||||
DO_TEST_DEFINE("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
|
||||
|
||||
DO_TEST_UNDEFINE("d76a6b78-45ed-4149-a325-005f9abc5281");
|
||||
|
||||
done:
|
||||
nodedevTestDriverFree(driver);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user