mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
api: add virNodeDeviceDefineXML()
With mediated devices, we can now define persistent node devices that can be started and stopped. In order to take advantage of this, we need an API to define new node devices. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
a48a2abe60
commit
7e386cde1f
@ -131,6 +131,10 @@ virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn,
|
||||
|
||||
int virNodeDeviceDestroy (virNodeDevicePtr dev);
|
||||
|
||||
virNodeDevicePtr virNodeDeviceDefineXML(virConnectPtr conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
|
||||
/**
|
||||
* VIR_NODE_DEVICE_EVENT_CALLBACK:
|
||||
*
|
||||
|
@ -74,6 +74,11 @@ typedef virNodeDevicePtr
|
||||
typedef int
|
||||
(*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev);
|
||||
|
||||
typedef virNodeDevicePtr
|
||||
(*virDrvNodeDeviceDefineXML)(virConnectPtr conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
|
||||
typedef int
|
||||
(*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
|
||||
virNodeDevicePtr dev,
|
||||
@ -113,4 +118,5 @@ struct _virNodeDeviceDriver {
|
||||
virDrvNodeDeviceListCaps nodeDeviceListCaps;
|
||||
virDrvNodeDeviceCreateXML nodeDeviceCreateXML;
|
||||
virDrvNodeDeviceDestroy nodeDeviceDestroy;
|
||||
virDrvNodeDeviceDefineXML nodeDeviceDefineXML;
|
||||
};
|
||||
|
@ -737,6 +737,48 @@ virNodeDeviceDestroy(virNodeDevicePtr dev)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virNodeDeviceDefineXML:
|
||||
* @conn: pointer to the hypervisor connection
|
||||
* @xmlDesc: string containing an XML description of the device to be defined
|
||||
* @flags: extra flags; not used yet, so callers should always pass 0
|
||||
*
|
||||
* Define a new device on the VM host machine, for example, a mediated device
|
||||
*
|
||||
* virNodeDeviceFree should be used to free the resources after the
|
||||
* node device object is no longer needed.
|
||||
*
|
||||
* Returns a node device object if successful, NULL in case of failure
|
||||
*/
|
||||
virNodeDevicePtr
|
||||
virNodeDeviceDefineXML(virConnectPtr conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags)
|
||||
{
|
||||
VIR_DEBUG("conn=%p, xmlDesc=%s, flags=0x%x", conn, NULLSTR(xmlDesc), flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
virCheckConnectReturn(conn, NULL);
|
||||
virCheckReadOnlyGoto(conn->flags, error);
|
||||
virCheckNonNullArgGoto(xmlDesc, error);
|
||||
|
||||
if (conn->nodeDeviceDriver &&
|
||||
conn->nodeDeviceDriver->nodeDeviceDefineXML) {
|
||||
virNodeDevice *dev = conn->nodeDeviceDriver->nodeDeviceDefineXML(conn, xmlDesc, flags);
|
||||
if (!dev)
|
||||
goto error;
|
||||
return dev;
|
||||
}
|
||||
|
||||
virReportUnsupportedError();
|
||||
|
||||
error:
|
||||
virDispatchError(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virConnectNodeDeviceEventRegisterAny:
|
||||
* @conn: pointer to the connection
|
||||
|
@ -889,4 +889,9 @@ LIBVIRT_7.2.0 {
|
||||
virDomainStartDirtyRateCalc;
|
||||
} LIBVIRT_7.1.0;
|
||||
|
||||
LIBVIRT_7.3.0 {
|
||||
global:
|
||||
virNodeDeviceDefineXML;
|
||||
} LIBVIRT_7.2.0;
|
||||
|
||||
# .... define new API here using predicted next version number ....
|
||||
|
@ -776,6 +776,27 @@ virMdevctlStart(virNodeDeviceDefPtr def, char **uuid, char **errmsg)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virMdevctlDefine(virNodeDeviceDefPtr def, char **uuid, char **errmsg)
|
||||
{
|
||||
int status;
|
||||
g_autoptr(virCommand) cmd = nodeDeviceGetMdevctlDefineCommand(def, uuid, errmsg);
|
||||
|
||||
if (!cmd)
|
||||
return -1;
|
||||
|
||||
/* an auto-generated uuid is returned via stdout if no uuid is specified in
|
||||
* the mdevctl args */
|
||||
if (virCommandRun(cmd, &status) < 0 || status != 0)
|
||||
return -1;
|
||||
|
||||
/* remove newline */
|
||||
*uuid = g_strstrip(*uuid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static virNodeDevicePtr
|
||||
nodeDeviceCreateXMLMdev(virConnectPtr conn,
|
||||
virNodeDeviceDefPtr def)
|
||||
@ -1116,6 +1137,57 @@ nodeDeviceDestroy(virNodeDevicePtr device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
virNodeDevice*
|
||||
nodeDeviceDefineXML(virConnect *conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags)
|
||||
{
|
||||
g_autoptr(virNodeDeviceDef) def = NULL;
|
||||
virNodeDevice *device = NULL;
|
||||
const char *virt_type = NULL;
|
||||
g_autofree char *uuid = NULL;
|
||||
g_autofree char *errmsg = NULL;
|
||||
|
||||
virCheckFlags(0, NULL);
|
||||
|
||||
if (nodeDeviceWaitInit() < 0)
|
||||
return NULL;
|
||||
|
||||
virt_type = virConnectGetType(conn);
|
||||
|
||||
if (!(def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt_type)))
|
||||
return NULL;
|
||||
|
||||
if (virNodeDeviceDefineXMLEnsureACL(conn, def) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!nodeDeviceHasCapability(def, VIR_NODE_DEV_CAP_MDEV)) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("Unsupported device type"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!def->parent) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("cannot define a mediated device without a parent"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (virMdevctlDefine(def, &uuid, &errmsg) < 0) {
|
||||
if (errmsg)
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Unable to define mediated device: %s"), errmsg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
def->caps->data.mdev.uuid = g_strdup(uuid);
|
||||
mdevGenerateDeviceName(def);
|
||||
device = nodeDeviceFindNewMediatedDevice(conn, uuid);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
||||
|
@ -102,6 +102,11 @@ nodeDeviceCreateXML(virConnectPtr conn,
|
||||
int
|
||||
nodeDeviceDestroy(virNodeDevicePtr dev);
|
||||
|
||||
virNodeDevice*
|
||||
nodeDeviceDefineXML(virConnect *conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
|
||||
int
|
||||
nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
||||
virNodeDevicePtr dev,
|
||||
|
@ -2325,6 +2325,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
|
||||
.nodeDeviceListCaps = nodeDeviceListCaps, /* 0.7.3 */
|
||||
.nodeDeviceCreateXML = nodeDeviceCreateXML, /* 0.7.3 */
|
||||
.nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
|
||||
.nodeDeviceDefineXML = nodeDeviceDefineXML, /* 7.2.0 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -8696,6 +8696,7 @@ static virNodeDeviceDriver node_device_driver = {
|
||||
.nodeDeviceNumOfCaps = remoteNodeDeviceNumOfCaps, /* 0.5.0 */
|
||||
.nodeDeviceListCaps = remoteNodeDeviceListCaps, /* 0.5.0 */
|
||||
.nodeDeviceCreateXML = remoteNodeDeviceCreateXML, /* 0.6.3 */
|
||||
.nodeDeviceDefineXML = remoteNodeDeviceDefineXML, /* 7.2.0 */
|
||||
.nodeDeviceDestroy = remoteNodeDeviceDestroy /* 0.6.3 */
|
||||
};
|
||||
|
||||
|
@ -2145,6 +2145,15 @@ struct remote_node_device_destroy_args {
|
||||
remote_nonnull_string name;
|
||||
};
|
||||
|
||||
struct remote_node_device_define_xml_args {
|
||||
remote_nonnull_string xml_desc;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct remote_node_device_define_xml_ret {
|
||||
remote_nonnull_node_device dev;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Events Register/Deregister:
|
||||
@ -6745,5 +6754,11 @@ enum remote_procedure {
|
||||
* @generate: both
|
||||
* @acl: domain:write
|
||||
*/
|
||||
REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427
|
||||
REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
|
||||
|
||||
/**
|
||||
* @generate: both
|
||||
* @acl: node_device:write
|
||||
*/
|
||||
REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 428
|
||||
};
|
||||
|
@ -1600,6 +1600,13 @@ struct remote_node_device_create_xml_ret {
|
||||
struct remote_node_device_destroy_args {
|
||||
remote_nonnull_string name;
|
||||
};
|
||||
struct remote_node_device_define_xml_args {
|
||||
remote_nonnull_string xml_desc;
|
||||
u_int flags;
|
||||
};
|
||||
struct remote_node_device_define_xml_ret {
|
||||
remote_nonnull_node_device dev;
|
||||
};
|
||||
struct remote_connect_domain_event_register_ret {
|
||||
int cb_registered;
|
||||
};
|
||||
@ -3605,4 +3612,5 @@ enum remote_procedure {
|
||||
REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425,
|
||||
REMOTE_PROC_DOMAIN_GET_MESSAGES = 426,
|
||||
REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
|
||||
REMOTE_PROC_NODE_DEVICE_DEFINE_XML = 428,
|
||||
};
|
||||
|
@ -567,6 +567,7 @@ elsif ($mode eq "server") {
|
||||
if ($argtype =~ m/^remote_node_device_/ and
|
||||
!($argtype =~ m/^remote_node_device_lookup_by_name_/) and
|
||||
!($argtype =~ m/^remote_node_device_create_xml_/) and
|
||||
!($argtype =~ m/^remote_node_device_define_xml_/) and
|
||||
!($argtype =~ m/^remote_node_device_lookup_scsi_host_by_wwn_/)) {
|
||||
$has_node_device = 1;
|
||||
push(@vars_list, "virNodeDevicePtr dev = NULL");
|
||||
|
Loading…
Reference in New Issue
Block a user