For network devices allocated from a network with <forward mode='hostdev-hybrid'>, there is a need to add the newly minted hostdev to the hostdevs array. In this case we also need to call qemuPrepareHostDevices just for this one device, as the standard call to initialize all the hostdevs that were defined directly in the domain's configuration has already been made by the time we allocate a device from a libvirt network, and thus have something that needs initializing. --- src/qemu/qemu_command.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_hostdev.c | 2 +- src/qemu/qemu_hotplug.c | 24 ++++++++++++++++-- src/qemu/qemu_process.c | 3 +- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a83d6de..e5388b3 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -27,6 +27,7 @@ #include "qemu_hostdev.h" #include "qemu_capabilities.h" #include "qemu_bridge_filter.h" +#include "qemu_hostdev.h" #include "cpu/cpu.h" #include "memory.h" #include "logging.h" @@ -4357,10 +4358,16 @@ qemuBuildCommandLine(virConnectPtr conn, bool emitBootindex = false; int usbcontroller = 0; bool usblegacy = false; + + virDomainObjPtr vm = NULL; + virDomainObjListPtr doms = &driver->domains; + uname_normalize(&ut); virUUIDFormat(def->uuid, uuid); + vm = virHashLookup(doms->objs, uuid); + emulator = def->emulator; /* @@ -5309,6 +5316,60 @@ qemuBuildCommandLine(virConnectPtr conn, continue; } + if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) { + if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { + virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net); + virDomainHostdevDefPtr found; + if (vmop == VIR_NETDEV_VPORT_PROFILE_OP_CREATE) { + if (qemuAssignDeviceHostdevAlias(def, hostdev, + (def->nhostdevs-1)) < 0) { + goto error; + } + + if (virDomainHostdevFind(def, hostdev, &found) < 0) { + qemuDomainObjPrivatePtr priv = vm->privateData; + if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, + hostdev->info) < 0) { + goto error; + } + if (virDomainHostdevInsert(def, hostdev) < 0) { + virReportOOMError(); + goto error; + } + if (qemuPrepareHostdevPCIDevices(driver, def->name, + def->uuid, &hostdev, 1) < 0) { + goto error; + } + } + else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("PCI device %04x:%02x:%02x.%x " + "allocated from network %s is already " + "in use by domain %s"), + hostdev->source.subsys.u.pci.domain, + hostdev->source.subsys.u.pci.bus, + hostdev->source.subsys.u.pci.slot, + hostdev->source.subsys.u.pci.function, + net->data.network.name, + def->name); + goto error; + } + } + } + + int tapfd = qemuPhysIfaceConnect(def, driver, net, + qemuCaps, vmop); + if (tapfd < 0) + goto error; + + last_good_net = i; + virCommandTransferFD(cmd, tapfd); + + if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", + tapfd) >= sizeof(tapfd_name)) + goto no_memory; + } + if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK || actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) { /* diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index a060a7e..4851e11 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -362,7 +362,7 @@ qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev, } } else if (hostdev->actualParent.data.net) { - vlan = virDomainNetGetActualVlan(hostdev->actualParent.data.net); + vlan = virDomainNetGetActualVlan(hostdev->actualParent.data.net); virtPort = virDomainNetGetActualVirtPortProfile(hostdev->actualParent.data.net); if (virtPort) { if (vlan) { diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index e8860f3..e26ffc9 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -694,6 +694,21 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto cleanup; } + if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) { + ret = qemuDomainAttachHostDevice(driver, vm, + virDomainNetGetActualHostdev(net)); + if (ret < 0) + goto cleanup; + + if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net, + priv->qemuCaps, + VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0) + goto cleanup; + iface_connected = true; + if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) + goto cleanup; + } + if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || actualType == VIR_DOMAIN_NET_TYPE_NETWORK) { /* @@ -2109,7 +2124,8 @@ int qemuDomainDetachThisHostDevice(struct qemud_driver *driver, VIR_WARN("Failed to restore host device labelling"); } virDomainHostdevRemove(vm->def, idx); - virDomainHostdevDefFree(detach); + if (detach->ephemeral == 0) + virDomainHostdevDefFree(detach); } return ret; } @@ -2199,7 +2215,8 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver, goto cleanup; } - if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) { + if ((virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) || + (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) { ret = qemuDomainDetachThisHostDevice(driver, vm, virDomainNetGetActualHostdev(detach), -1); @@ -2272,7 +2289,8 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver, virDomainConfNWFilterTeardown(detach); - if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) { + if ((virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) || + (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) { ignore_value(virNetDevMacVLanDeleteWithVPortProfile( detach->ifname, &detach->mac, virDomainNetGetActualDirectDev(detach), diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 77d679a..112c113 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4169,7 +4169,8 @@ void qemuProcessStop(struct qemud_driver *driver, def = vm->def; for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; - if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) { + if ((virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) || + (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) { ignore_value(virNetDevMacVLanDeleteWithVPortProfile( net->ifname, &net->mac, virDomainNetGetActualDirectDev(net), -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list