mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-23 11:52:20 +00:00
conf: Introduce new hostdev device type mdev
A mediated device will be identified by a UUID (with 'model' now being a mandatory <hostdev> attribute to represent the mediated device API) of the user pre-created mediated device. We also need to make sure that if user explicitly provides a guest address for a mdev device, the address type will be matching the device API supported on that specific mediated device and error out with an incorrect XML message. The resulting device XML: <devices> <hostdev mode='subsystem' type='mdev' model='vfio-pci'> <source> <address uuid='c2177883-f1bb-47f0-914d-32a22e3a8804'> </source> </hostdev> </devices> Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
e1ec4f88ff
commit
ec783d7c77
@ -4034,6 +4034,7 @@
|
||||
<ref name="hostdevsubsysusb"/>
|
||||
<ref name="hostdevsubsysscsi"/>
|
||||
<ref name="hostdevsubsyshost"/>
|
||||
<ref name="hostdevsubsysmdev"/>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
@ -4184,6 +4185,20 @@
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="hostdevsubsysmdev">
|
||||
<attribute name="type">
|
||||
<value>mdev</value>
|
||||
</attribute>
|
||||
<attribute name="model">
|
||||
<choice>
|
||||
<value>vfio-pci</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<element name="source">
|
||||
<ref name="mdevaddress"/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="hostdevcapsstorage">
|
||||
<attribute name="type">
|
||||
<value>storage</value>
|
||||
@ -4342,6 +4357,13 @@
|
||||
</attribute>
|
||||
</optional>
|
||||
</define>
|
||||
<define name="mdevaddress">
|
||||
<element name="address">
|
||||
<attribute name="uuid">
|
||||
<ref name="UUID"/>
|
||||
</attribute>
|
||||
</element>
|
||||
</define>
|
||||
<define name="devices">
|
||||
<element name="devices">
|
||||
<interleave>
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "virstring.h"
|
||||
#include "virnetdev.h"
|
||||
#include "virhostdev.h"
|
||||
#include "virmdev.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
||||
|
||||
@ -652,7 +653,8 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST,
|
||||
"usb",
|
||||
"pci",
|
||||
"scsi",
|
||||
"scsi_host")
|
||||
"scsi_host",
|
||||
"mdev")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend,
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST,
|
||||
@ -2356,6 +2358,7 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
break;
|
||||
}
|
||||
@ -4251,6 +4254,23 @@ virDomainHostdevDefPostParse(virDomainHostdevDefPtr dev,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: {
|
||||
int model = dev->source.subsys.u.mdev.model;
|
||||
|
||||
if (dev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
|
||||
return 0;
|
||||
|
||||
if (model == VIR_MDEV_MODEL_TYPE_VFIO_PCI &&
|
||||
dev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("Unsupported address type '%s' with mediated "
|
||||
"device model '%s'"),
|
||||
virDomainDeviceAddressTypeToString(dev->info->type),
|
||||
virMediatedDeviceModelTypeToString(model));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
|
||||
@ -6397,6 +6417,41 @@ virDomainHostdevSubsysSCSIVHostDefParseXML(xmlNodePtr sourcenode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
virDomainHostdevSubsysMediatedDevDefParseXML(virDomainHostdevDefPtr def,
|
||||
xmlXPathContextPtr ctxt)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN] = {0};
|
||||
char *uuidxml = NULL;
|
||||
xmlNodePtr node = NULL;
|
||||
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev;
|
||||
|
||||
if (!(node = virXPathNode("./source/address", ctxt))) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("Missing <address> element"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(uuidxml = virXMLPropString(node, "uuid"))) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("Missing 'uuid' attribute for element <address>"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virUUIDParse(uuidxml, uuid) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s",
|
||||
_("Cannot parse uuid attribute of element <address>"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
virUUIDFormat(uuid, mdevsrc->uuidstr);
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(uuidxml);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
||||
@ -6410,10 +6465,12 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
||||
char *sgio = NULL;
|
||||
char *rawio = NULL;
|
||||
char *backendStr = NULL;
|
||||
char *model = NULL;
|
||||
int backend;
|
||||
int ret = -1;
|
||||
virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
|
||||
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev;
|
||||
|
||||
/* @managed can be read from the xml document - it is always an
|
||||
* attribute of the toplevel element, no matter what type of
|
||||
@ -6427,6 +6484,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
||||
|
||||
sgio = virXMLPropString(node, "sgio");
|
||||
rawio = virXMLPropString(node, "rawio");
|
||||
model = virXMLPropString(node, "model");
|
||||
|
||||
/* @type is passed in from the caller rather than read from the
|
||||
* xml document, because it is specified in different places for
|
||||
@ -6493,6 +6551,29 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
||||
}
|
||||
}
|
||||
|
||||
if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) {
|
||||
if (model) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("'model' attribute in <hostdev> is only supported "
|
||||
"when type='mdev'"));
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (!model) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("Missing 'model' attribute in mediated device's "
|
||||
"<hostdev> element"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((mdevsrc->model = virMediatedDeviceModelTypeFromString(model)) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("unknown hostdev model '%s'"),
|
||||
model);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
switch (def->source.subsys.type) {
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||
if (virDomainHostdevSubsysPCIDefParseXML(sourcenode, def, flags) < 0)
|
||||
@ -6525,6 +6606,10 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
||||
if (virDomainHostdevSubsysSCSIVHostDefParseXML(sourcenode, def) < 0)
|
||||
goto error;
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
if (virDomainHostdevSubsysMediatedDevDefParseXML(def, ctxt) < 0)
|
||||
goto error;
|
||||
break;
|
||||
|
||||
default:
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
@ -6539,6 +6624,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
||||
VIR_FREE(sgio);
|
||||
VIR_FREE(rawio);
|
||||
VIR_FREE(backendStr);
|
||||
VIR_FREE(model);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -13384,6 +13470,7 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
break;
|
||||
}
|
||||
@ -14318,6 +14405,7 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
return 0;
|
||||
}
|
||||
@ -21319,6 +21407,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
|
||||
virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
|
||||
virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
|
||||
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev;
|
||||
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
|
||||
virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
|
||||
|
||||
@ -21423,6 +21512,10 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
virBufferAsprintf(buf, "<address uuid='%s'/>\n",
|
||||
mdevsrc->uuidstr);
|
||||
break;
|
||||
default:
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unexpected hostdev type %d"),
|
||||
@ -23318,6 +23411,7 @@ virDomainHostdevDefFormat(virBufferPtr buf,
|
||||
{
|
||||
const char *mode = virDomainHostdevModeTypeToString(def->mode);
|
||||
virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
|
||||
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev;
|
||||
const char *type;
|
||||
|
||||
if (!mode) {
|
||||
@ -23367,6 +23461,10 @@ virDomainHostdevDefFormat(virBufferPtr buf,
|
||||
virBufferAsprintf(buf, " rawio='%s'",
|
||||
virTristateBoolTypeToString(scsisrc->rawio));
|
||||
}
|
||||
|
||||
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV)
|
||||
virBufferAsprintf(buf, " model='%s'",
|
||||
virMediatedDeviceModelTypeToString(mdevsrc->model));
|
||||
}
|
||||
virBufferAddLit(buf, ">\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
|
@ -295,6 +295,7 @@ typedef enum {
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI,
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI,
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST,
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV,
|
||||
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST
|
||||
} virDomainHostdevSubsysType;
|
||||
@ -369,6 +370,13 @@ struct _virDomainHostdevSubsysSCSI {
|
||||
} u;
|
||||
};
|
||||
|
||||
typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediatedDev;
|
||||
typedef virDomainHostdevSubsysMediatedDev *virDomainHostdevSubsysMediatedDevPtr;
|
||||
struct _virDomainHostdevSubsysMediatedDev {
|
||||
int model; /* enum virMediatedDeviceModelType */
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN]; /* mediated device's uuid string */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_NONE,
|
||||
VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST,
|
||||
@ -394,6 +402,7 @@ struct _virDomainHostdevSubsys {
|
||||
virDomainHostdevSubsysPCI pci;
|
||||
virDomainHostdevSubsysSCSI scsi;
|
||||
virDomainHostdevSubsysSCSIVHost scsi_host;
|
||||
virDomainHostdevSubsysMediatedDev mdev;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -7105,6 +7105,7 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
break;
|
||||
}
|
||||
|
@ -3915,6 +3915,8 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
|
||||
qemuDomainRemoveSCSIVHostDevice(driver, vm, hostdev);
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
break;
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
break;
|
||||
}
|
||||
|
@ -901,6 +901,9 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
ret = 0;
|
||||
break;
|
||||
|
@ -964,6 +964,7 @@ virSecurityDACSetHostdevLabel(virSecurityManagerPtr mgr,
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
ret = 0;
|
||||
break;
|
||||
@ -1119,6 +1120,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManagerPtr mgr,
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
ret = 0;
|
||||
break;
|
||||
|
@ -1838,6 +1838,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManagerPtr mgr,
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
ret = 0;
|
||||
break;
|
||||
@ -2065,6 +2066,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManagerPtr mgr,
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||
ret = 0;
|
||||
break;
|
||||
|
@ -89,6 +89,7 @@
|
||||
<value>pci</value>
|
||||
<value>scsi</value>
|
||||
<value>scsi_host</value>
|
||||
<value>mdev</value>
|
||||
</enum>
|
||||
<enum name='capsType'>
|
||||
<value>storage</value>
|
||||
|
Loading…
x
Reference in New Issue
Block a user