[libvirt] [PATCH 19/27] network: introduce networkNotifyPort

Daniel P. Berrangé berrange at redhat.com
Mon Dec 24 14:59:07 UTC 2018


Separate network port notification code from the domain driver network
callback implementation.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/network/bridge_driver.c | 159 ++++++++++++++++++++----------------
 1 file changed, 89 insertions(+), 70 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ebce90d89a..25e856a7e2 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4806,46 +4806,26 @@ networkAllocateActualDevice(virNetworkPtr net,
 }
 
 
-/* networkNotifyActualDevice:
- * @dom: domain definition that @iface belongs to
- * @iface:  the domain's NetDef with an "actual" device already filled in.
+/* networkNotifyPort:
+ * @obj: the network to notify
+ * @port: the port definition to notify
  *
  * Called to notify the network driver when libvirtd is restarted and
  * finds an already running domain. If appropriate it will force an
  * allocation of the actual->direct.linkdev to get everything back in
  * order, or re-attach the interface's tap device to the network's
  * bridge.
- *
- * No return value (but does log any failures)
  */
-static void
-networkNotifyActualDevice(virNetworkPtr net,
-                          virDomainDefPtr dom,
-                          virDomainNetDefPtr iface)
+static int
+networkNotifyPort(virNetworkObjPtr obj,
+                  virNetworkPortDefPtr port)
 {
-    virNetworkDriverStatePtr driver = networkGetDriver();
-    virDomainNetType actualType = virDomainNetGetActualType(iface);
-    virNetworkObjPtr obj;
     virNetworkDefPtr netdef;
     virNetworkForwardIfDefPtr dev = NULL;
-    virNetworkPortDefPtr port = NULL;
     size_t i;
     char *master = NULL;
     bool useOVS = false;
-
-    obj = virNetworkObjFindByName(driver->networks, net->name);
-    if (!obj) {
-        virReportError(VIR_ERR_NO_NETWORK,
-                       _("no network with matching name '%s'"),
-                       net->name);
-        goto error;
-    }
-
-    if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Expected a interface for a virtual network"));
-        goto error;
-    }
+    int ret = -1;
 
     netdef = virNetworkObjGetDef(obj);
 
@@ -4853,55 +4833,32 @@ networkNotifyActualDevice(virNetworkPtr net,
         virReportError(VIR_ERR_OPERATION_INVALID,
                        _("network '%s' is not active"),
                        netdef->name);
-        goto error;
-    }
-
-    /* if we're restarting libvirtd after an upgrade from a version
-     * that didn't save bridge name in actualNetDef for
-     * actualType==network, we need to copy it in so that it will be
-     * available in all cases
-     */
-    if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
-        !iface->data.network.actual->data.bridge.brname &&
-        (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
-                    netdef->bridge) < 0))
-            goto error;
-
-    /* Older libvirtd uses actualType==network, but we now
-     * just use actualType==bridge, as nothing needs to
-     * distinguish the two cases, and this simplifies virt
-     * drive code */
-    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
-        iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
-        actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
-    }
-
-    if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
         goto cleanup;
+    }
 
     switch (port->plugtype) {
     case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Unexpectedly got a network port without a plug"));
-        goto error;
+        goto cleanup;
 
     case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
         /* see if we're connected to the correct bridge */
         if (!netdef->bridge) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Unexpectedly got a network port plugged into a bridge"));
-            goto error;
+            goto cleanup;
         }
 
         if (virNetDevGetMaster(port->plug.bridge.brname, &master) < 0)
-            goto error;
+            goto cleanup;
 
         /* IFLA_MASTER for a tap on an OVS switch is always "ovs-system" */
         if (STREQ_NULLABLE(master, "ovs-system")) {
             useOVS = true;
             VIR_FREE(master);
             if (virNetDevOpenvswitchInterfaceGetMaster(port->plug.bridge.brname, &master) < 0)
-                goto error;
+                goto cleanup;
         }
 
         if (STRNEQ_NULLABLE(netdef->bridge, master)) {
@@ -4926,14 +4883,14 @@ networkNotifyActualDevice(virNetworkPtr net,
                                          port->virtPortProfile,
                                          &port->vlan,
                                          0, NULL) < 0) {
-                goto error;
+                goto cleanup;
             }
         }
         break;
 
     case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
         if (networkCreateInterfacePool(netdef) < 0)
-            goto error;
+            goto cleanup;
 
         /* find the matching interface and increment its connections */
         for (i = 0; i < netdef->forward.nifs; i++) {
@@ -4952,7 +4909,7 @@ networkNotifyActualDevice(virNetworkPtr net,
                              "in use by network port '%s'"),
                            netdef->name, port->plug.direct.linkdev,
                            port->uuid);
-            goto error;
+            goto cleanup;
         }
 
         /* PASSTHROUGH mode and PRIVATE Mode + 802.1Qbh both require
@@ -4968,14 +4925,14 @@ networkNotifyActualDevice(virNetworkPtr net,
                            _("network '%s' claims dev='%s' is already in "
                              "use by a different port"),
                            netdef->name, port->plug.direct.linkdev);
-            goto error;
+            goto cleanup;
         }
         break;
 
     case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
 
         if (networkCreateInterfacePool(netdef) < 0)
-            goto error;
+            goto cleanup;
 
         /* find the matching interface and increment its connections */
         for (i = 0; i < netdef->forward.nifs; i++) {
@@ -4997,7 +4954,7 @@ networkNotifyActualDevice(virNetworkPtr net,
                            port->plug.hostdevpci.addr.bus,
                            port->plug.hostdevpci.addr.slot,
                            port->plug.hostdevpci.addr.function);
-            goto error;
+            goto cleanup;
         }
 
         /* PASSTHROUGH mode, PRIVATE Mode + 802.1Qbh, and hostdev (PCI
@@ -5013,7 +4970,7 @@ networkNotifyActualDevice(virNetworkPtr net,
                            netdef->name,
                            dev->device.pci.domain, dev->device.pci.bus,
                            dev->device.pci.slot, dev->device.pci.function);
-            goto error;
+            goto cleanup;
         }
 
         break;
@@ -5021,7 +4978,7 @@ networkNotifyActualDevice(virNetworkPtr net,
     case VIR_NETWORK_PORT_PLUG_TYPE_LAST:
     default:
         virReportEnumRangeError(virNetworkPortPlugType, port->plugtype);
-        goto error;
+        goto cleanup;
     }
 
     netdef->connections++;
@@ -5034,18 +4991,80 @@ networkNotifyActualDevice(virNetworkPtr net,
         if (dev)
             dev->connections--;
         netdef->connections--;
-        goto error;
+        goto cleanup;
     }
-    networkLogAllocation(netdef, dev, &iface->mac, true);
+    networkLogAllocation(netdef, dev, &port->mac, true);
 
+    ret = 0;
  cleanup:
-    virNetworkObjEndAPI(&obj);
-    virNetworkPortDefFree(port);
     VIR_FREE(master);
-    return;
+    return ret;
+}
 
- error:
-    goto cleanup;
+
+static void
+networkNotifyActualDevice(virNetworkPtr net,
+                          virDomainDefPtr dom,
+                          virDomainNetDefPtr iface)
+{
+    virNetworkDriverStatePtr driver = networkGetDriver();
+    virDomainNetType actualType = virDomainNetGetActualType(iface);
+    virNetworkObjPtr obj;
+    virNetworkDefPtr netdef;
+    virNetworkPortDefPtr port = NULL;
+
+    obj = virNetworkObjFindByName(driver->networks, net->name);
+    if (!obj) {
+        virReportError(VIR_ERR_NO_NETWORK,
+                       _("no network with matching name '%s'"),
+                       net->name);
+        goto cleanup;
+    }
+
+    if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Expected a interface for a virtual network"));
+        goto cleanup;
+    }
+
+    netdef = virNetworkObjGetDef(obj);
+
+    if (!virNetworkObjIsActive(obj)) {
+        virReportError(VIR_ERR_OPERATION_INVALID,
+                       _("network '%s' is not active"),
+                       netdef->name);
+        goto cleanup;
+    }
+
+    /* if we're restarting libvirtd after an upgrade from a version
+     * that didn't save bridge name in actualNetDef for
+     * actualType==network, we need to copy it in so that it will be
+     * available in all cases
+     */
+    if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
+        !iface->data.network.actual->data.bridge.brname &&
+        (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
+                    netdef->bridge) < 0))
+            goto cleanup;
+
+    /* Older libvirtd uses actualType==network, but we now
+     * just use actualType==bridge, as nothing needs to
+     * distinguish the two cases, and this simplifies virt
+     * drive code */
+    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+        iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+        actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
+    }
+
+    if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
+        goto cleanup;
+
+    if (networkNotifyPort(obj, port) < 0)
+        goto cleanup;
+
+ cleanup:
+    virNetworkObjEndAPI(&obj);
+    virNetworkPortDefFree(port);
 }
 
 
-- 
2.19.2




More information about the libvir-list mailing list