]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Functionality to implicitly get interface pool from SR-IOV PF.
authorShradha Shah <sshah@solarflare.com>
Wed, 14 Dec 2011 10:50:30 +0000 (10:50 +0000)
committerEric Blake <eblake@redhat.com>
Wed, 11 Jan 2012 20:14:12 +0000 (13:14 -0700)
If a system has 64 or more VF's, it is quite tedious to mention each VF
in the interface pool.
The following modification will implicitly create an interface pool from
the SR-IOV PF.

src/network/bridge_driver.c

index 9afada73bbf31cf5e9eb718d91f4906b85ea351f..91ef229dbe4a4dabd8dd5b6a3fb49e92887caf37 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bridge_driver.c: core driver methods for managing network
  *
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -2741,6 +2741,9 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
     virNetworkObjPtr network;
     virNetworkDefPtr netdef;
     virPortGroupDefPtr portgroup;
+    unsigned int num_virt_fns = 0;
+    char **vfname = NULL;
+    int ii;
     int ret = -1;
 
     if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
@@ -2868,13 +2871,12 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
         /* If there is only a single device, just return it (caller will detect
          * any error if exclusive use is required but could not be acquired).
          */
-        if (netdef->nForwardIfs == 0) {
+        if ((netdef->nForwardIfs <= 0) && (netdef->nForwardPfs <= 0)) {
             networkReportError(VIR_ERR_INTERNAL_ERROR,
                                _("network '%s' uses a direct mode, but has no forward dev and no interface pool"),
                                netdef->name);
             goto cleanup;
         } else {
-            int ii;
             virNetworkForwardIfDefPtr dev = NULL;
 
             /* pick an interface from the pool */
@@ -2884,13 +2886,54 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
              * 0.  Other modes can share, so just search for the one with
              * the lowest usageCount.
              */
-            if ((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
-                ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
-                 iface->data.network.actual->data.direct.virtPortProfile &&
-                 (iface->data.network.actual->data.direct.virtPortProfile->virtPortType
-                  == VIR_NETDEV_VPORT_PROFILE_8021QBH))) {
+            if (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) {
+                if ((netdef->nForwardPfs > 0) && (netdef->nForwardIfs <= 0)) {
+                    if ((virNetDevGetVirtualFunctions(netdef->forwardPfs->dev,
+                                                      &vfname, &num_virt_fns)) < 0) {
+                        networkReportError(VIR_ERR_INTERNAL_ERROR,
+                                           _("Could not get Virtual functions on %s"),
+                                           netdef->forwardPfs->dev);
+                        goto cleanup;
+                    }
+
+                    if (num_virt_fns == 0) {
+                        networkReportError(VIR_ERR_INTERNAL_ERROR,
+                                           _("No Vf's present on SRIOV PF %s"),
+                                           netdef->forwardPfs->dev);
+                        goto cleanup;
+                    }
+
+                    if ((VIR_ALLOC_N(netdef->forwardIfs, num_virt_fns)) < 0) {
+                        virReportOOMError();
+                        goto cleanup;
+                    }
+
+                    netdef->nForwardIfs = num_virt_fns;
+
+                    for (ii = 0; ii < netdef->nForwardIfs; ii++) {
+                        netdef->forwardIfs[ii].dev = strdup(vfname[ii]);
+                        if (!netdef->forwardIfs[ii].dev) {
+                            virReportOOMError();
+                            goto cleanup;
+                        }
+                        netdef->forwardIfs[ii].usageCount = 0;
+                    }
+                }
+
                 /* pick first dev with 0 usageCount */
 
+                for (ii = 0; ii < netdef->nForwardIfs; ii++) {
+                    if (netdef->forwardIfs[ii].usageCount == 0) {
+                        dev = &netdef->forwardIfs[ii];
+                        break;
+                    }
+                }
+            } else if ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
+                       iface->data.network.actual->data.direct.virtPortProfile &&
+                       (iface->data.network.actual->data.direct.virtPortProfile->virtPortType
+                        == VIR_NETDEV_VPORT_PROFILE_8021QBH)) {
+
+                /* pick first dev with 0 usageCount */
                 for (ii = 0; ii < netdef->nForwardIfs; ii++) {
                     if (netdef->forwardIfs[ii].usageCount == 0) {
                         dev = &netdef->forwardIfs[ii];
@@ -2909,7 +2952,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
             if (!dev) {
                 networkReportError(VIR_ERR_INTERNAL_ERROR,
                                    _("network '%s' requires exclusive access to interfaces, but none are available"),
-                               netdef->name);
+                                   netdef->name);
                 goto cleanup;
             }
             iface->data.network.actual->data.direct.linkdev = strdup(dev->dev);
@@ -2926,6 +2969,9 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
 
     ret = 0;
 cleanup:
+    for (ii = 0; ii < num_virt_fns; ii++)
+        VIR_FREE(vfname[ii]);
+    VIR_FREE(vfname);
     if (network)
         virNetworkObjUnlock(network);
     if (ret < 0) {