提交 ec783d7c 编写于 作者: E Erik Skultety

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: NErik Skultety <eskultet@redhat.com>
上级 e1ec4f88
......@@ -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>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册