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