[libvirt] [PATCH 10/15] ActualParent is used to store the information about the NETDEV that contains HOSTDEV in hybrid case.

Shradha Shah sshah at solarflare.com
Fri Aug 10 16:25:59 UTC 2012


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





More information about the libvir-list mailing list