[libvirt] [PATCH 09/15] Hostdev-hybrid mode requires a direct linkdev and direct mode.

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


In this mode the guest contains a Virtual network device along with a
SRIOV VF passed through to the guest as a pci device.
---
 src/conf/domain_conf.c   |   37 +++++++++++++++++++++++++++++++++++--
 src/conf/domain_conf.h   |    5 +++++
 src/libvirt_private.syms |    1 +
 src/util/pci.c           |    2 +-
 src/util/pci.h           |    2 ++
 src/util/virnetdev.c     |   40 ++++++++++++++++++++++++++++++++++++++++
 src/util/virnetdev.h     |    6 ++++++
 7 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 39b5cdb..e73c07d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1025,6 +1025,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def)
         VIR_FREE(def->data.hostdev.virtPortProfile);
         break;
     case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID:
+        VIR_FREE(def->data.hostdev.linkdev);
         virDomainHostdevDefClear(&def->data.hostdev.def);
         VIR_FREE(def->data.hostdev.virtPortProfile);
         break;
@@ -1084,6 +1085,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
         break;
 
     case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID:
+        VIR_FREE(def->data.hostdev.linkdev);
         virDomainHostdevDefClear(&def->data.hostdev.def);
         VIR_FREE(def->data.hostdev.virtPortProfile);
         break;
@@ -4475,6 +4477,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
     char *mode = NULL;
     char *linkstate = NULL;
     char *addrtype = NULL;
+    char *pfname = NULL;
     virNWFilterHashTablePtr filterparams = NULL;
     virNetDevVPortProfilePtr virtPort = NULL;
     virDomainActualNetDefPtr actual = NULL;
@@ -4795,6 +4798,26 @@ virDomainNetDefParseXML(virCapsPtr caps,
                                        hostdev, flags) < 0) {
             goto error;
         }
+        if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+            if (virNetDevGetPhysicalFunctionFromVfPciAddr(hostdev->source.subsys.u.pci.domain,
+                                                          hostdev->source.subsys.u.pci.bus,
+                                                          hostdev->source.subsys.u.pci.slot,
+                                                          hostdev->source.subsys.u.pci.function,
+                                                          &pfname) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("Could not get Physical Function of the hostdev"));
+                goto error;
+            }
+        }
+        if (pfname != NULL)
+            def->data.hostdev.linkdev = strdup(pfname);
+        else {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Linkdev is required in %s mode"),
+                           virDomainNetTypeToString(def->type));
+            goto error;
+        }
+        def->data.hostdev.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE;
         def->data.hostdev.virtPortProfile = virtPort;
         virtPort = NULL;
         break;
@@ -15033,11 +15056,16 @@ virDomainNetGetActualDirectDev(virDomainNetDefPtr iface)
 {
     if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT)
         return iface->data.direct.linkdev;
+    if (iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)
+        return iface->data.hostdev.linkdev;
     if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
         return NULL;
     if (!iface->data.network.actual)
         return NULL;
-    return iface->data.network.actual->data.direct.linkdev;
+    if (iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) 
+        return iface->data.network.actual->data.hostdev.linkdev;
+    else
+        return iface->data.network.actual->data.direct.linkdev;
 }
 
 int
@@ -15045,11 +15073,16 @@ virDomainNetGetActualDirectMode(virDomainNetDefPtr iface)
 {
     if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT)
         return iface->data.direct.mode;
+    if (iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)
+        return iface->data.hostdev.mode;
     if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
         return 0;
     if (!iface->data.network.actual)
         return 0;
-    return iface->data.network.actual->data.direct.mode;
+    if (iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) 
+        return iface->data.network.actual->data.hostdev.mode;
+    else 
+        return iface->data.network.actual->data.direct.mode;
 }
 
 virDomainHostdevDefPtr
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7bcaee4..053c71c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -43,6 +43,7 @@
 # include "virnetdevvportprofile.h"
 # include "virnetdevopenvswitch.h"
 # include "virnetdevbandwidth.h"
+# include "virnetdev.h"
 # include "virobject.h"
 # include "device_conf.h"
 
@@ -762,6 +763,8 @@ struct _virDomainActualNetDef {
             virNetDevVPortProfilePtr virtPortProfile;
         } direct;
         struct {
+            char *linkdev;
+            int mode;
             virDomainHostdevDef def;
             virNetDevVPortProfilePtr virtPortProfile;
         } hostdev;
@@ -819,6 +822,8 @@ struct _virDomainNetDef {
             virNetDevVPortProfilePtr virtPortProfile;
         } direct;
         struct {
+            char *linkdev;
+            int mode;
             virDomainHostdevDef def;
             virNetDevVPortProfilePtr virtPortProfile;
         } hostdev;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f752f49..fae69ef 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1366,6 +1366,7 @@ virNetDevGetMTU;
 virNetDevGetPhysicalFunction;
 virNetDevGetVLanID;
 virNetDevGetVirtualFunctionIndex;
+virNetDevGetPhysicalFunctionFromVfPciAddr;
 virNetDevGetVirtualFunctionInfo;
 virNetDevGetVirtualFunctions;
 virNetDevIsOnline;
diff --git a/src/util/pci.c b/src/util/pci.c
index 137521b..5bf1758 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -803,7 +803,7 @@ pciDriverFile(char **buffer, const char *driver, const char *file)
     return 0;
 }
 
-static int
+int
 pciDeviceFile(char **buffer, const char *device, const char *file)
 {
     VIR_FREE(*buffer);
diff --git a/src/util/pci.h b/src/util/pci.h
index 8bbab07..936fee4 100644
--- a/src/util/pci.h
+++ b/src/util/pci.h
@@ -116,6 +116,8 @@ int pciConfigAddressToSysfsFile(struct pci_config_address *dev,
 
 int pciDeviceNetName(char *device_link_sysfs_path, char **netname);
 
+int pciDeviceFile(char **buffer, const char *device, const char *file);
+
 int pciSysfsFile(char *pciDeviceName, char **pci_sysfs_device_link)
     ATTRIBUTE_RETURN_CHECK;
 
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 8103aff..46d0cda 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1099,6 +1099,46 @@ virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname,
 }
 
 /**
+ * virNetDevGetPhyscialFunctionFromVfPciAddr
+ *
+ * @domain : Domain part of VF PCI addr 
+ * @bus : Bus part of VF PCI addr
+ * @slot : Slot part of VF PCI addr
+ * @function : Function part of VF PCI addr
+ * @pfname : Contains sriov physical function for Vf upon 
+ *           successful return
+ *
+ * Returns 0 on success, -1 on failure
+ *
+ */
+int 
+virNetDevGetPhysicalFunctionFromVfPciAddr(unsigned domain,
+                                          unsigned bus,
+                                          unsigned slot,
+                                          unsigned function,
+                                          char **pfname)
+{
+    char *pciConfigAddr;
+    char *physfn_sysfs_path = NULL;
+    int ret = -1;
+    
+    if (pciGetDeviceAddrString(domain, bus, slot, function, 
+                               &pciConfigAddr) < 0) {
+        goto cleanup;
+    }
+    if (pciDeviceFile(&physfn_sysfs_path, pciConfigAddr, "physfn") < 0) {
+        goto cleanup;
+    }
+    ret = pciDeviceNetName(physfn_sysfs_path, pfname);
+    
+cleanup:
+    VIR_FREE(pciConfigAddr);
+    VIR_FREE(physfn_sysfs_path);
+    
+    return ret;
+}
+
+/**
  * virNetDevGetPhysicalFunction
  *
  * @ifname : name of the physical function interface name
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index 705ad9c..66b57db 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -99,6 +99,12 @@ int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname,
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
     ATTRIBUTE_RETURN_CHECK;
 
+int virNetDevGetPhysicalFunctionFromVfPciAddr(unsigned domain, unsigned bus, 
+                                              unsigned slot, unsigned function,
+                                              char **pfname)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+    ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK; 
+
 int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
 
-- 
1.7.4.4





More information about the libvir-list mailing list