diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 2493be595f..eafd6b3396 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -4837,6 +4837,22 @@ support in the hypervisor and the guest network driver). ... +The second interface in this example is referencing a network that is +a pool of SRIOV VFs (i.e. a "hostdev network"). You could instead +directly reference an SRIOV VF device: + +:: + + ... + + +
+ + + + + ... + The ```` element required attribute ``type`` will be set to either ``"persistent"`` to indicate a device that should always be present in the domain, or ``"transient"`` to indicate a device that may periodically be @@ -4858,6 +4874,41 @@ once migration is completed; while migration is taking place, network traffic will use the virtio NIC. (Of course the emulated virtio NIC and the hostdev NIC must be connected to the same subnet for bonding to work properly). +:since:`Since 7.1.0` The ```` element can also be added to a +plain ```` device. + +:: + + ... + + +
+ + + + + ... + +This device must be a network device, but not necessarily an SRIOV +VF. Using plain ```` rather than ```` or ```` is useful if the +device that will be assigned with VFIO is a standard NIC (not a VF) or +if libvirt doesn't have the necessary resources and privileges to set +the VF's MAC address (e.g. if libvirt is running unprivileged, or in a +container). This of course means that the user (or another +application) is responsible for setting the MAC address of the device +in a way such that it will survive guest driver initialization. For +standard NICs (i.e. not an SRIOV VF) this probably means that the +NIC's factory-programmed MAC address will need to be used for the +teaming pair (since any driver init in the guest will reset the MAC +back to factory). If it is an SRIOV VF, then its MAC address will need +to be set via the VF's PF, e.g. if you are going to use VF 2 of the PF +enp2s0f1, you would use something like this command: + +:: + + ip link set enp2s0f1 vf 2 mac 52:54:00:11:22:33 + NB1: Since you must know the alias name of the virtio NIC when configuring the hostdev NIC, it will need to be manually set in the virtio NIC's configuration (as with all other manually set alias names, this means it must start with diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 31960fb7cf..e6de934456 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5156,6 +5156,9 @@ + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3fe8517f39..17e0d1ed31 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3024,6 +3024,8 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def) if (!def->parentnet) virDomainDeviceInfoFree(def->info); + virDomainNetTeamingInfoFree(def->teaming); + switch (def->mode) { case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES: switch ((virDomainHostdevCapsType) def->source.caps.type) { @@ -15015,6 +15017,9 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt, } } + if (virDomainNetTeamingInfoParseXML(ctxt, &def->teaming) < 0) + goto error; + return def; error: @@ -27433,6 +27438,8 @@ virDomainHostdevDefFormat(virBufferPtr buf, break; } + virDomainNetTeamingInfoFormat(def->teaming, buf); + if (def->readonly) virBufferAddLit(buf, "\n"); if (def->shareable) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index fb695a212b..e263e6098b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -354,6 +354,7 @@ struct _virDomainHostdevDef { virDomainHostdevCaps caps; } source; virDomainHostdevOrigStates origstates; + virDomainNetTeamingInfoPtr teaming; virDomainDeviceInfoPtr info; /* Guest address */ }; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 703946b3e5..b47ecba86b 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1585,6 +1585,25 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev) break; } } + + if (hostdev->teaming) { + if (hostdev->teaming->type != VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("teaming hostdev devices must have type='transient'")); + return -1; + } + if (!hostdev->teaming->persistent) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("missing required persistent attribute in hostdev teaming element")); + return -1; + } + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("teaming is only supported for pci hostdev devices")); + return -1; + } + } return 0; } diff --git a/tests/qemuxml2argvdata/net-virtio-teaming-hostdev.xml b/tests/qemuxml2argvdata/net-virtio-teaming-hostdev.xml new file mode 100644 index 0000000000..a7edab63bd --- /dev/null +++ b/tests/qemuxml2argvdata/net-virtio-teaming-hostdev.xml @@ -0,0 +1,64 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-i386 + + + + +
+ + +
+ + + +
+ + + + + + +
+ + + + + + +
+ + + + + +
+ + +
+ + + +
+ + +
+ + +
+ + + diff --git a/tests/qemuxml2xmloutdata/net-virtio-teaming-hostdev.xml b/tests/qemuxml2xmloutdata/net-virtio-teaming-hostdev.xml new file mode 120000 index 0000000000..f7a3c3ada0 --- /dev/null +++ b/tests/qemuxml2xmloutdata/net-virtio-teaming-hostdev.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/net-virtio-teaming-hostdev.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index a00ebd7d76..5cd945f28f 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -438,6 +438,9 @@ mymain(void) DO_TEST("net-virtio-teaming-network", QEMU_CAPS_VIRTIO_NET_FAILOVER, QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST("net-virtio-teaming-hostdev", + QEMU_CAPS_VIRTIO_NET_FAILOVER, + QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_CAPS_LATEST("net-isolated-port"); DO_TEST("net-hostdev", NONE); DO_TEST("net-hostdev-bootorder", NONE);