[libvirt] [PATCH 5/5] Supporting managed option for forward devs when using HOSTDEV mode

Shradha Shah sshah at solarflare.com
Fri Jun 8 15:30:03 UTC 2012


This patch supports the managed option in a network xml for network devices.
This option is used for pci network devices when forward mode=hostdev.

Hence the example network xml would be:

<network>
  <name>direct-network</name>
  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a8f</uuid>
  <forward mode="hostdev">
    <pf dev="eth2" managed='yes'/>
  </forward>
</network>

OR

<network>
  <name>direct-network</name>
  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a8f</uuid>
  <forward mode="hostdev">
    <interface dev="0000:04:00.1" managed='yes'/>
    <interface dev="0000:04:00.2" managed='yes'/>
    <interface dev="0000:04:00.3" managed='yes'/>
  </forward>
</network>

Signed-off-by: Shradha Shah <sshah at solarflare.com>
---
 src/conf/network_conf.c     |   61 ++++++++++++++++++++++++++++++++++++++++--
 src/conf/network_conf.h     |    2 +
 src/network/bridge_driver.c |    5 +++-
 3 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 6b346c3..18e4ee3 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -986,6 +986,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
     char *forwardDev = NULL;
     xmlNodePtr save = ctxt->node;
     xmlNodePtr bandwidthNode = NULL;
+    char *managed = NULL;
 
     if (VIR_ALLOC(def) < 0) {
         virReportOOMError();
@@ -1128,6 +1129,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
         }
 
         forwardDev = virXPathString("string(./@dev)", ctxt);
+        managed = virXPathString("string(./managed)", ctxt); 
 
         /* all of these modes can use a pool of physical interfaces */
         nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes);
@@ -1151,6 +1153,12 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
                 goto error;
             }
 
+            if (managed) {
+                virNetworkReportError(VIR_ERR_XML_ERROR,
+                                      _("A managed field should not be used in this location when using a SRIOV PF"));
+                goto error;
+            }
+
             forwardDev = virXMLPropString(*forwardPfNodes, "dev");
             if (!forwardDev) {
                 virNetworkReportError(VIR_ERR_XML_ERROR,
@@ -1159,9 +1167,16 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
                 goto error;
             }
 
+            managed = virXMLPropString(*forwardPfNodes, "managed");
+            if(managed != NULL) {
+                if (STREQ(managed, "yes"))
+                    def->forwardPfs->managed = 1; 
+            }
+
             def->forwardPfs->usageCount = 0;
             def->forwardPfs->dev = forwardDev;
             forwardDev = NULL;
+            managed = NULL;
             def->nForwardPfs++;
         } else if (nForwardPfs > 1) {
             virNetworkReportError(VIR_ERR_XML_ERROR,
@@ -1170,6 +1185,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
         }
         if (nForwardIfs > 0 || forwardDev) {
             int ii;
+            unsigned int managedvalue = 0;
 
             /* allocate array to hold all the portgroups */
             if (VIR_ALLOC_N(def->forwardIfs, MAX(nForwardIfs, 1)) < 0) {
@@ -1181,12 +1197,24 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
                 def->forwardIfs[0].usageCount = 0;
                 def->forwardIfs[0].dev = forwardDev;
                 forwardDev = NULL;
+                if (managed != NULL) {
+                    if (STREQ(managed, "yes"))
+                        def->forwardIfs[0].managed = 1;
+                }
+                managed = NULL;
                 def->nForwardIfs++;
             }
 
             /* parse each forwardIf */
             for (ii = 0; ii < nForwardIfs; ii++) {
                 forwardDev = virXMLPropString(forwardIfNodes[ii], "dev");
+                managed = virXMLPropString(forwardIfNodes[ii], "managed");
+                if (managed != NULL) {
+                    if (STREQ(managed, "yes"))
+                        managedvalue = 1;
+                    else
+                        managedvalue = 0;
+                }
                 if (!forwardDev) {
                     virNetworkReportError(VIR_ERR_XML_ERROR,
                                           _("Missing required dev attribute in network '%s' forward interface element"),
@@ -1204,12 +1232,22 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
                                               forwardDev, def->name);
                         goto error;
                     }
+                    
+                    if (managedvalue != def->forwardIfs[0].managed) {
+                        virNetworkReportError(VIR_ERR_XML_ERROR,
+                                              _("managed field of forward dev must match that of the first interface element dev in network '%s'"),
+                                              def->name);
+                        goto error;
+                    }
+                    VIR_FREE(managed);
                     VIR_FREE(forwardDev);
                     continue;
                 }
 
                 def->forwardIfs[ii].dev = forwardDev;
+                def->forwardIfs[ii].managed = managedvalue;
                 forwardDev = NULL;
+                managed = NULL;
                 def->forwardIfs[ii].usageCount = 0;
                 def->nForwardIfs++;
             }
@@ -1224,6 +1262,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
         }
         
         VIR_FREE(forwardDev);
+        VIR_FREE(managed);
         VIR_FREE(forwardPfNodes);
         VIR_FREE(forwardIfNodes);
 
@@ -1541,15 +1580,31 @@ char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags)
                           (def->nForwardIfs || def->nForwardPfs) ? "" : "/");
 
         /* For now, hard-coded to at most 1 forwardPfs */
-        if (def->nForwardPfs)
-            virBufferEscapeString(&buf, "    <pf dev='%s'/>\n",
+        if (def->nForwardPfs) {
+            virBufferEscapeString(&buf, "    <pf dev='%s'",
                                   def->forwardPfs[0].dev);
 
+            if (def->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
+                if (def->forwardPfs[0].managed == 1)
+                    virBufferAddLit(&buf, " managed='yes'");
+                else
+                    virBufferAddLit(&buf, " managed='no'");
+            }
+            virBufferAddLit(&buf, "/>\n");
+        }
+        
         if (def->nForwardIfs &&
             (!def->nForwardPfs || !(flags & VIR_NETWORK_XML_INACTIVE))) {
             for (ii = 0; ii < def->nForwardIfs; ii++) {
-                virBufferEscapeString(&buf, "    <interface dev='%s'/>\n",
+                virBufferEscapeString(&buf, "    <interface dev='%s'",
                                       def->forwardIfs[ii].dev);
+                if (def->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
+                    if (def->forwardIfs[ii].managed == 1)
+                        virBufferAddLit(&buf, " managed='yes'");
+                    else
+                        virBufferAddLit(&buf, " managed='no'");
+                }
+                virBufferAddLit(&buf, "/>\n");
             }
         }
         if (def->nForwardPfs || def->nForwardIfs)
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index d473c71..4276934 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -135,6 +135,7 @@ struct _virNetworkForwardIfDef {
     char *dev;      /* name of device */
     int usageCount; /* how many guest interfaces are bound to this device? */
     bool isPciAddr; /* Differentiate a VF based on interface name or pci addr*/
+    unsigned int managed:1;
 };
 
 typedef struct _virNetworkForwardPfDef virNetworkForwardPfDef;
@@ -142,6 +143,7 @@ typedef virNetworkForwardPfDef *virNetworkForwardPfDefPtr;
 struct _virNetworkForwardPfDef {
     char *dev;      /* name of device */ 
     int usageCount; /* how many guest interfaces are bound to this device? */
+    unsigned int managed:1;
 };
 
 typedef struct _virPortGroupDef virPortGroupDef;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 691ab07..a2293e6 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2807,6 +2807,9 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) {
             netdef->forwardIfs[ii].isPciAddr = true;
         else 
             netdef->forwardIfs[ii].isPciAddr = false;
+
+        if (netdef->forwardPfs[0].managed == 1)
+            netdef->forwardIfs[ii].managed = 1;
     }
     
     ret = 0;
@@ -2942,7 +2945,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
         iface->data.network.actual->data.hostdev.def.parent.data.net = iface;
         iface->data.network.actual->data.hostdev.def.info = &iface->info;
         iface->data.network.actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
-        iface->data.network.actual->data.hostdev.def.managed = 1;
+        iface->data.network.actual->data.hostdev.def.managed = dev->managed;
         iface->data.network.actual->data.hostdev.def.source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
         
         if (dev->isPciAddr == true) {
-- 
1.7.4.4




More information about the libvir-list mailing list