mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-06 09:55:46 +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,
|
const char *xmlDesc,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
int virNodeDeviceUndefine(virNodeDevicePtr dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VIR_NODE_DEVICE_EVENT_CALLBACK:
|
* VIR_NODE_DEVICE_EVENT_CALLBACK:
|
||||||
*
|
*
|
||||||
|
@ -70,7 +70,7 @@ VIR_ENUM_IMPL(virAccessPermNodeDevice,
|
|||||||
VIR_ACCESS_PERM_NODE_DEVICE_LAST,
|
VIR_ACCESS_PERM_NODE_DEVICE_LAST,
|
||||||
"getattr", "read", "write",
|
"getattr", "read", "write",
|
||||||
"start", "stop",
|
"start", "stop",
|
||||||
"detach",
|
"detach", "delete",
|
||||||
);
|
);
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virAccessPermNWFilter,
|
VIR_ENUM_IMPL(virAccessPermNWFilter,
|
||||||
|
@ -500,6 +500,12 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
VIR_ACCESS_PERM_NODE_DEVICE_DETACH,
|
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
|
VIR_ACCESS_PERM_NODE_DEVICE_LAST
|
||||||
} virAccessPermNodeDevice;
|
} virAccessPermNodeDevice;
|
||||||
|
|
||||||
|
@ -79,6 +79,9 @@ typedef virNodeDevicePtr
|
|||||||
const char *xmlDesc,
|
const char *xmlDesc,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virDrvNodeDeviceUndefine)(virNodeDevicePtr dev);
|
||||||
|
|
||||||
typedef int
|
typedef int
|
||||||
(*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
|
(*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
|
||||||
virNodeDevicePtr dev,
|
virNodeDevicePtr dev,
|
||||||
@ -119,4 +122,5 @@ struct _virNodeDeviceDriver {
|
|||||||
virDrvNodeDeviceCreateXML nodeDeviceCreateXML;
|
virDrvNodeDeviceCreateXML nodeDeviceCreateXML;
|
||||||
virDrvNodeDeviceDestroy nodeDeviceDestroy;
|
virDrvNodeDeviceDestroy nodeDeviceDestroy;
|
||||||
virDrvNodeDeviceDefineXML nodeDeviceDefineXML;
|
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:
|
* virConnectNodeDeviceEventRegisterAny:
|
||||||
* @conn: pointer to the connection
|
* @conn: pointer to the connection
|
||||||
|
@ -892,6 +892,7 @@ LIBVIRT_7.2.0 {
|
|||||||
LIBVIRT_7.3.0 {
|
LIBVIRT_7.3.0 {
|
||||||
global:
|
global:
|
||||||
virNodeDeviceDefineXML;
|
virNodeDeviceDefineXML;
|
||||||
|
virNodeDeviceUndefine;
|
||||||
} LIBVIRT_7.2.0;
|
} LIBVIRT_7.2.0;
|
||||||
|
|
||||||
# .... define new API here using predicted next version number ....
|
# .... 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
|
static int
|
||||||
virMdevctlStop(virNodeDeviceDefPtr def, char **errmsg)
|
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*
|
virCommand*
|
||||||
nodeDeviceGetMdevctlListCommand(bool defined,
|
nodeDeviceGetMdevctlListCommand(bool defined,
|
||||||
char **output,
|
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
|
int
|
||||||
nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
||||||
|
@ -107,6 +107,9 @@ nodeDeviceDefineXML(virConnect *conn,
|
|||||||
const char *xmlDesc,
|
const char *xmlDesc,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
int
|
||||||
|
nodeDeviceUndefine(virNodeDevice *dev);
|
||||||
|
|
||||||
int
|
int
|
||||||
nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
||||||
virNodeDevicePtr dev,
|
virNodeDevicePtr dev,
|
||||||
@ -132,6 +135,10 @@ virCommandPtr
|
|||||||
nodeDeviceGetMdevctlStopCommand(const char *uuid,
|
nodeDeviceGetMdevctlStopCommand(const char *uuid,
|
||||||
char **errmsg);
|
char **errmsg);
|
||||||
|
|
||||||
|
virCommand *
|
||||||
|
nodeDeviceGetMdevctlUndefineCommand(const char *uuid,
|
||||||
|
char **errmsg);
|
||||||
|
|
||||||
virCommandPtr
|
virCommandPtr
|
||||||
nodeDeviceGetMdevctlListCommand(bool defined,
|
nodeDeviceGetMdevctlListCommand(bool defined,
|
||||||
char **output,
|
char **output,
|
||||||
|
@ -2326,6 +2326,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
|
|||||||
.nodeDeviceCreateXML = nodeDeviceCreateXML, /* 0.7.3 */
|
.nodeDeviceCreateXML = nodeDeviceCreateXML, /* 0.7.3 */
|
||||||
.nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
|
.nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
|
||||||
.nodeDeviceDefineXML = nodeDeviceDefineXML, /* 7.2.0 */
|
.nodeDeviceDefineXML = nodeDeviceDefineXML, /* 7.2.0 */
|
||||||
|
.nodeDeviceUndefine = nodeDeviceUndefine, /* 7.2.0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -8697,6 +8697,7 @@ static virNodeDeviceDriver node_device_driver = {
|
|||||||
.nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
|
.nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
|
||||||
.nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
|
.nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
|
||||||
.nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 7.2.0 */
|
.nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 7.2.0 */
|
||||||
|
.nodeDeviceUndefine = remoteNodeDeviceUndefine, /* 7.2.0 */
|
||||||
.nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
|
.nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2154,6 +2154,10 @@ struct remote_node_device_define_xml_ret {
|
|||||||
remote_nonnull_node_device dev;
|
remote_nonnull_node_device dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct remote_node_device_undefine_args {
|
||||||
|
remote_nonnull_string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Events Register/Deregister:
|
* Events Register/Deregister:
|
||||||
@ -6760,5 +6764,13 @@ enum remote_procedure {
|
|||||||
* @generate: both
|
* @generate: both
|
||||||
* @acl: node_device:write
|
* @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 {
|
struct remote_node_device_define_xml_ret {
|
||||||
remote_nonnull_node_device dev;
|
remote_nonnull_node_device dev;
|
||||||
};
|
};
|
||||||
|
struct remote_node_device_undefine_args {
|
||||||
|
remote_nonnull_string name;
|
||||||
|
};
|
||||||
struct remote_connect_domain_event_register_ret {
|
struct remote_connect_domain_event_register_ret {
|
||||||
int cb_registered;
|
int cb_registered;
|
||||||
};
|
};
|
||||||
@ -3613,4 +3616,5 @@ enum remote_procedure {
|
|||||||
REMOTE_PROC_DOMAIN_GET_MESSAGES = 426,
|
REMOTE_PROC_DOMAIN_GET_MESSAGES = 426,
|
||||||
REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
|
REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
|
||||||
REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 428,
|
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) {
|
if (info->command == MDEVCTL_CMD_STOP) {
|
||||||
cmd = "stop";
|
cmd = "stop";
|
||||||
func = nodeDeviceGetMdevctlStopCommand;
|
func = nodeDeviceGetMdevctlStopCommand;
|
||||||
|
} else if (info->command == MDEVCTL_CMD_UNDEFINE) {
|
||||||
|
cmd = "undefine";
|
||||||
|
func = nodeDeviceGetMdevctlUndefineCommand;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -423,6 +426,9 @@ mymain(void)
|
|||||||
#define DO_TEST_STOP(uuid) \
|
#define DO_TEST_STOP(uuid) \
|
||||||
DO_TEST_UUID_COMMAND_FULL("mdevctl stop " uuid, uuid, MDEVCTL_CMD_STOP)
|
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() \
|
#define DO_TEST_LIST_DEFINED() \
|
||||||
DO_TEST_FULL("mdevctl list --defined", testMdevctlListDefined, NULL)
|
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_fedc4916_1ca8_49ac_b176_871d16c13076");
|
||||||
DO_TEST_DEFINE("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
|
DO_TEST_DEFINE("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
|
||||||
|
|
||||||
|
DO_TEST_UNDEFINE("d76a6b78-45ed-4149-a325-005f9abc5281");
|
||||||
|
|
||||||
done:
|
done:
|
||||||
nodedevTestDriverFree(driver);
|
nodedevTestDriverFree(driver);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user