The parent type for hostdev hybrid needs to be VIR_DOMAIN_DEVICE_NONE as the device is passed into the guest as a PCI Device. In order to store the information of the NETDEV that is the parent of the HOSTDEV in question we use a new variable actualParent. This variable also helps during VF MAC address, vlan and virtportprofile configuration. ActualParent = Parent in case of forward mode="hostdev" --- src/conf/domain_conf.c | 8 ++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_hostdev.c | 91 +++++++++++++++++++++++++++++++++-------------- src/qemu/qemu_hotplug.c | 2 +- 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e73c07d..361850a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4366,6 +4366,8 @@ virDomainActualNetDefParseXML(xmlNodePtr node, hostdev->parent.type = VIR_DOMAIN_DEVICE_NET; hostdev->parent.data.net = parent; + hostdev->actualParent.type = VIR_DOMAIN_DEVICE_NET; + hostdev->actualParent.data.net = parent; hostdev->info = &parent->info; /* The helper function expects type to already be found and * passed in as a string, since it is in a different place in @@ -4393,6 +4395,8 @@ virDomainActualNetDefParseXML(xmlNodePtr node, virDomainHostdevDefPtr hostdev = &actual->data.hostdev.def; hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE; + hostdev->actualParent.type = VIR_DOMAIN_DEVICE_NET; + hostdev->actualParent.data.net = parent; if (VIR_ALLOC(hostdev->info) < 0) { virReportOOMError(); @@ -4760,6 +4764,8 @@ virDomainNetDefParseXML(virCapsPtr caps, hostdev = &def->data.hostdev.def; hostdev->parent.type = VIR_DOMAIN_DEVICE_NET; hostdev->parent.data.net = def; + hostdev->actualParent.type = VIR_DOMAIN_DEVICE_NET; + hostdev->actualParent.data.net = def; hostdev->info = &def->info; /* The helper function expects type to already be found and * passed in as a string, since it is in a different place in @@ -4783,6 +4789,8 @@ virDomainNetDefParseXML(virCapsPtr caps, case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: hostdev = &def->data.hostdev.def; hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE; + hostdev->actualParent.type = VIR_DOMAIN_DEVICE_NET; + hostdev->actualParent.data.net = def; if (VIR_ALLOC(hostdev->info) < 0) { virReportOOMError(); goto error; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 053c71c..4584671 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -368,6 +368,7 @@ struct _virDomainHostdevSubsys { /* basic device for direct passthrough */ struct _virDomainHostdevDef { virDomainDeviceDef parent; /* higher level Def containing this */ + virDomainDeviceDef actualParent; /*used only in the case of hybrid hostdev*/ int mode; /* enum virDomainHostdevMode */ unsigned int managed : 1; union { diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index 7619fd0..d2712f4 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -319,17 +319,36 @@ qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev, if (qemuDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0) return ret; - virtPort = virDomainNetGetActualVirtPortProfile( - hostdev->parent.data.net); - if (virtPort) - ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, - virtPort, &hostdev->parent.data.net->mac, uuid, - port_profile_associate); - else - /* Set only mac */ - ret = virNetDevReplaceNetConfig(linkdev, vf, - &hostdev->parent.data.net->mac, vlanid, - stateDir); + if (hostdev->parent.data.net) { + virtPort = virDomainNetGetActualVirtPortProfile(hostdev->parent.data.net); + if (virtPort) + ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, + virtPort, + &hostdev->parent.data.net->mac, + uuid, + port_profile_associate); + else + /* Set only mac */ + ret = virNetDevReplaceNetConfig(linkdev, vf, + &hostdev->parent.data.net->mac, + vlanid, + stateDir); + } + else if (hostdev->actualParent.data.net) { + virtPort = virDomainNetGetActualVirtPortProfile(hostdev->actualParent.data.net); + if (virtPort) + ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, + virtPort, + &hostdev->actualParent.data.net->mac, + uuid, + port_profile_associate); + else + /* Set only mac */ + ret = virNetDevReplaceNetConfig(linkdev, vf, + &hostdev->actualParent.data.net->mac, + vlanid, + stateDir); + } VIR_FREE(linkdev); return ret; @@ -357,17 +376,29 @@ qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev, if (qemuDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0) return ret; - virtPort = virDomainNetGetActualVirtPortProfile( - hostdev->parent.data.net); - if (virtPort) - ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort, - &hostdev->parent.data.net->mac, NULL, - port_profile_associate); - else - ret = virNetDevRestoreNetConfig(linkdev, vf, stateDir); - + if (hostdev->parent.data.net) { + virtPort = virDomainNetGetActualVirtPortProfile(hostdev->parent.data.net); + if (virtPort) + ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort, + &hostdev->parent.data.net->mac, + NULL, + port_profile_associate); + else + ret = virNetDevRestoreNetConfig(linkdev, vf, stateDir); + } + if (hostdev->actualParent.data.net) { + virtPort = virDomainNetGetActualVirtPortProfile(hostdev->actualParent.data.net); + if (virtPort) + ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort, + &hostdev->actualParent.data.net->mac, + NULL, + port_profile_associate); + else + ret = virNetDevRestoreNetConfig(linkdev, vf, stateDir); + } + VIR_FREE(linkdev); - + return ret; } @@ -450,8 +481,10 @@ int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver, continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; - if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && - hostdev->parent.data.net) { + if ((hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && + hostdev->parent.data.net) || + (hostdev->actualParent.type == VIR_DOMAIN_DEVICE_NET && + hostdev->actualParent.data.net)) { if (qemuDomainHostdevNetConfigReplace(hostdev, uuid, driver->stateDir) < 0) { goto resetvfnetconfig; @@ -540,8 +573,10 @@ inactivedevs: resetvfnetconfig: for (i = 0; i < last_processed_hostdev_vf; i++) { virDomainHostdevDefPtr hostdev = hostdevs[i]; - if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && - hostdev->parent.data.net) { + if ((hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && + hostdev->parent.data.net) || + (hostdev->actualParent.type == VIR_DOMAIN_DEVICE_NET && + hostdev->actualParent.data.net)) { qemuDomainHostdevNetConfigRestore(hostdev, driver->stateDir); } } @@ -799,8 +834,10 @@ void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver, continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; - if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && - hostdev->parent.data.net) { + if ((hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && + hostdev->parent.data.net) || + (hostdev->actualParent.type == VIR_DOMAIN_DEVICE_NET && + hostdev->actualParent.data.net)) { qemuDomainHostdevNetConfigRestore(hostdev, driver->stateDir); } } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 3eeeb29..1822289 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1994,7 +1994,7 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, * For SRIOV net host devices, unset mac and port profile before * reset and reattach device */ - if (detach->parent.data.net) + if (detach->parent.data.net || detach->actualParent.data.net) qemuDomainHostdevNetConfigRestore(detach, driver->stateDir); pci = pciGetDevice(subsys->u.pci.domain, subsys->u.pci.bus, -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list