[libvirt] [PATCH v3 36/36] conf: switch over to use network port APIs for virt drivers

Daniel P. Berrangé berrange at redhat.com
Tue Mar 19 12:47:00 UTC 2019


Change the domain conf so invoke the new network port public APIs instead
of the network callbacks.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/conf/domain_conf.c      | 262 ++++++++++++++++++++++++------------
 src/conf/domain_conf.h      |  26 ----
 src/libvirt_private.syms    |   1 -
 src/network/bridge_driver.c | 200 ---------------------------
 4 files changed, 178 insertions(+), 311 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index fee5df8f40..486638135b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30252,6 +30252,7 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDefPtr iface,
         if (VIR_STRDUP(actual->data.bridge.brname,
                        port->plug.bridge.brname) < 0)
             goto error;
+        actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
         actual->data.bridge.macTableManager = port->plug.bridge.macTableManager;
         break;
 
@@ -30259,10 +30260,12 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDefPtr iface,
         if (VIR_STRDUP(actual->data.direct.linkdev,
                        port->plug.direct.linkdev) < 0)
             goto error;
+        actual->type = VIR_DOMAIN_NET_TYPE_DIRECT;
         actual->data.direct.mode = port->plug.direct.mode;
         break;
 
     case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
+        actual->type = VIR_DOMAIN_NET_TYPE_HOSTDEV;
         actual->data.hostdev.def.parent = iface;
         actual->data.hostdev.def.info = &iface->info;
         actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
@@ -30454,45 +30457,100 @@ virDomainNetDefActualToNetworkPort(virDomainDefPtr dom,
     return NULL;
 }
 
-static virDomainNetAllocateActualDeviceImpl netAllocate;
-static virDomainNetNotifyActualDeviceImpl netNotify;
-static virDomainNetReleaseActualDeviceImpl netRelease;
-static virDomainNetBandwidthUpdateImpl netBandwidthUpdate;
 
-
-void
-virDomainNetSetDeviceImpl(virDomainNetAllocateActualDeviceImpl allocate,
-                          virDomainNetNotifyActualDeviceImpl notify,
-                          virDomainNetReleaseActualDeviceImpl release,
-                          virDomainNetBandwidthUpdateImpl bandwidthUpdate)
-{
-    netAllocate = allocate;
-    netNotify = notify;
-    netRelease = release;
-    netBandwidthUpdate = bandwidthUpdate;
-}
-
-int
-virDomainNetAllocateActualDevice(virConnectPtr conn,
-                                 virDomainDefPtr dom,
-                                 virDomainNetDefPtr iface)
+static int
+virDomainNetCreatePort(virConnectPtr conn,
+                       virDomainDefPtr dom,
+                       virDomainNetDefPtr iface,
+                       unsigned int flags)
 {
     virNetworkPtr net = NULL;
     int ret = -1;
+    virNetworkPortDefPtr portdef = NULL;
+    virNetworkPortPtr port = NULL;
+    char *portxml = NULL;
+    virErrorPtr saved;
 
-    if (!netAllocate) {
-        virReportError(VIR_ERR_NO_SUPPORT, "%s",
-                       _("Virtual networking driver is not available"));
+    if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
         return -1;
+
+    if (flags & VIR_NETWORK_PORT_CREATE_RECLAIM) {
+        virDomainNetType actualType = virDomainNetGetActualType(iface);
+
+        /* 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_NETWORK &&
+            !iface->data.network.actual->data.bridge.brname) {
+            char *bridge = virNetworkGetBridgeName(net);
+            if (!bridge)
+                goto cleanup;
+            VIR_FREE(iface->data.network.actual->data.bridge.brname);
+            iface->data.network.actual->data.bridge.brname = bridge;
+        }
+
+        /* 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 (!(portdef = virDomainNetDefActualToNetworkPort(dom, iface)))
+            goto cleanup;
+    } else {
+        if (!(portdef = virDomainNetDefToNetworkPort(dom, iface)))
+            goto cleanup;
     }
 
-    if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
-        return -1;
+    if (!(portxml = virNetworkPortDefFormat(portdef)))
+        goto cleanup;
 
-    ret = netAllocate(net, dom, iface);
+    virNetworkPortDefFree(portdef);
+    portdef = NULL;
 
+    if (!(port = virNetworkPortCreateXML(net, portxml, flags)))
+        goto cleanup;
+
+    VIR_FREE(portxml);
+
+    if (!(portxml = virNetworkPortGetXMLDesc(port, 0)))
+        goto deleteport;
+
+    if (!(portdef = virNetworkPortDefParseString(portxml)))
+        goto deleteport;
+
+    if (virDomainNetDefActualFromNetworkPort(iface, portdef) < 0)
+        goto deleteport;
+
+    virNetworkPortGetUUID(port, iface->data.network.portid);
+
+    ret = 0;
+ cleanup:
+    virNetworkPortDefFree(portdef);
+    VIR_FREE(portxml);
+    virObjectUnref(port);
     virObjectUnref(net);
     return ret;
+
+ deleteport:
+    saved = virSaveLastError();
+    virNetworkPortDelete(port, 0);
+    virSetError(saved);
+    virFreeError(saved);
+    goto cleanup;
+}
+
+int
+virDomainNetAllocateActualDevice(virConnectPtr conn,
+                                 virDomainDefPtr dom,
+                                 virDomainNetDefPtr iface)
+{
+    return virDomainNetCreatePort(conn, dom, iface, 0);
 }
 
 void
@@ -30500,94 +30558,130 @@ virDomainNetNotifyActualDevice(virConnectPtr conn,
                                virDomainDefPtr dom,
                                virDomainNetDefPtr iface)
 {
-    virDomainNetType actualType = virDomainNetGetActualType(iface);
-    virNetworkPtr net = NULL;
-
-    if (!netNotify)
-        return;
-
-    if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
-        return;
-
-    /* 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_NETWORK &&
-        !iface->data.network.actual->data.bridge.brname) {
-        char *bridge = virNetworkGetBridgeName(net);
-        if (!bridge)
-            goto cleanup;
-        VIR_FREE(iface->data.network.actual->data.bridge.brname);
-        iface->data.network.actual->data.bridge.brname = bridge;
-    }
-
-    /* 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 (!virUUIDIsValid(iface->data.network.portid)) {
+        if (virDomainNetCreatePort(conn, dom, iface,
+                                   VIR_NETWORK_PORT_CREATE_RECLAIM) < 0)
+            return;
     }
 
-
-    if (netNotify(net, dom, iface) < 0)
-        goto cleanup;
-
     if (virDomainNetGetActualType(iface) == VIR_DOMAIN_NET_TYPE_BRIDGE) {
         /*
          * NB: we can't notify the guest of any MTU change anyway,
          * so there is no point in trying to learn the actualMTU
          * (final arg to virNetDevTapReattachBridge())
          */
-        if (virNetDevTapReattachBridge(iface->ifname,
-                                       iface->data.network.actual->data.bridge.brname,
-                                       &iface->mac, dom->uuid,
-                                       virDomainNetGetActualVirtPortProfile(iface),
-                                       virDomainNetGetActualVlan(iface),
-                                       iface->mtu, NULL) < 0)
-            goto cleanup;
+        ignore_value(virNetDevTapReattachBridge(iface->ifname,
+                                                iface->data.network.actual->data.bridge.brname,
+                                                &iface->mac, dom->uuid,
+                                                virDomainNetGetActualVirtPortProfile(iface),
+                                                virDomainNetGetActualVlan(iface),
+                                                iface->mtu, NULL));
     }
-
- cleanup:
-    virObjectUnref(net);
 }
 
 
 int
 virDomainNetReleaseActualDevice(virConnectPtr conn,
-                                virDomainDefPtr dom,
+                                virDomainDefPtr dom ATTRIBUTE_UNUSED,
                                 virDomainNetDefPtr iface)
 {
     virNetworkPtr net = NULL;
-    int ret;
-
-    if (!netRelease)
-        return 0;
+    virNetworkPortPtr port = NULL;
+    int ret = -1;
 
     if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
-        return -1;
+        goto cleanup;
 
-    ret = netRelease(net, dom, iface);
+    if (!(port = virNetworkPortLookupByUUID(net, iface->data.network.portid)))
+        goto cleanup;
+
+    if (virNetworkPortDelete(port, 0) < 0)
+        goto cleanup;
 
+ cleanup:
+    virObjectUnref(port);
     virObjectUnref(net);
     return ret;
 }
 
 
+static int
+virDomainNetBandwidthToTypedParams(virNetDevBandwidthPtr bandwidth,
+                                   virTypedParameterPtr *params,
+                                   int *nparams)
+{
+    int maxparams = 0;
+
+    if ((bandwidth->in != NULL) &&
+        (virTypedParamsAddUInt(params, nparams, &maxparams,
+                               VIR_NETWORK_PORT_BANDWIDTH_IN_AVERAGE,
+                               bandwidth->in->average) < 0 ||
+         virTypedParamsAddUInt(params, nparams, &maxparams,
+                               VIR_NETWORK_PORT_BANDWIDTH_IN_PEAK,
+                               bandwidth->in->peak) < 0 ||
+         virTypedParamsAddUInt(params, nparams, &maxparams,
+                               VIR_NETWORK_PORT_BANDWIDTH_IN_FLOOR,
+                               bandwidth->in->floor) < 0 ||
+         virTypedParamsAddUInt(params, nparams, &maxparams,
+                               VIR_NETWORK_PORT_BANDWIDTH_IN_BURST,
+                               bandwidth->in->burst) < 0))
+        goto error;
+
+    if ((bandwidth->out != NULL) &&
+        (virTypedParamsAddUInt(params, nparams, &maxparams,
+                               VIR_NETWORK_PORT_BANDWIDTH_OUT_AVERAGE,
+                               bandwidth->out->average) < 0 ||
+         virTypedParamsAddUInt(params, nparams, &maxparams,
+                               VIR_NETWORK_PORT_BANDWIDTH_OUT_PEAK,
+                               bandwidth->out->peak) < 0 ||
+         virTypedParamsAddUInt(params, nparams, &maxparams,
+                               VIR_NETWORK_PORT_BANDWIDTH_OUT_BURST,
+                               bandwidth->out->burst) < 0))
+        goto error;
+
+    return 0;
+
+ error:
+    virTypedParamsFree(*params, *nparams);
+    *params = NULL;
+    *nparams = 0;
+    return -1;
+}
+
+
 int
 virDomainNetBandwidthUpdate(virDomainNetDefPtr iface,
                             virNetDevBandwidthPtr newBandwidth)
 {
-    if (!netBandwidthUpdate) {
-        virReportError(VIR_ERR_NO_SUPPORT, "%s",
-                       _("Virtual networking driver is not available"));
-        return -1;
-    }
+    virNetworkPtr net = NULL;
+    virNetworkPortPtr port = NULL;
+    virTypedParameterPtr params = NULL;
+    int nparams = 0;
+    virConnectPtr conn = NULL;
+    int ret = -1;
+
+    if (!(conn = virGetConnectNetwork()))
+        goto cleanup;
 
-    return netBandwidthUpdate(iface, newBandwidth);
+    if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
+        goto cleanup;
+
+    if (!(port = virNetworkPortLookupByUUID(net, iface->data.network.portid)))
+        goto cleanup;
+
+    if (virDomainNetBandwidthToTypedParams(newBandwidth, &params, &nparams) < 0)
+        goto cleanup;
+
+    if (virNetworkPortSetParameters(port, params, nparams, 0) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virObjectUnref(conn);
+    virTypedParamsFree(params, nparams);
+    virObjectUnref(port);
+    virObjectUnref(net);
+    return ret;
 }
 
 /* virDomainNetResolveActualType:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 4df4c51474..7b1ee33c72 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3531,32 +3531,6 @@ virNetworkPortDefPtr
 virDomainNetDefActualToNetworkPort(virDomainDefPtr dom,
                                    virDomainNetDefPtr iface);
 
-typedef int
-(*virDomainNetAllocateActualDeviceImpl)(virNetworkPtr net,
-                                        virDomainDefPtr dom,
-                                        virDomainNetDefPtr iface);
-
-typedef int
-(*virDomainNetNotifyActualDeviceImpl)(virNetworkPtr net,
-                                      virDomainDefPtr dom,
-                                      virDomainNetDefPtr iface);
-
-typedef int
-(*virDomainNetReleaseActualDeviceImpl)(virNetworkPtr net,
-                                       virDomainDefPtr dom,
-                                       virDomainNetDefPtr iface);
-
-typedef int
-(*virDomainNetBandwidthUpdateImpl)(virDomainNetDefPtr iface,
-                                   virNetDevBandwidthPtr newBandwidth);
-
-
-void
-virDomainNetSetDeviceImpl(virDomainNetAllocateActualDeviceImpl allocate,
-                          virDomainNetNotifyActualDeviceImpl notify,
-                          virDomainNetReleaseActualDeviceImpl release,
-                          virDomainNetBandwidthUpdateImpl bandwidthUpdate);
-
 int
 virDomainNetAllocateActualDevice(virConnectPtr conn,
                                  virDomainDefPtr dom,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 640ac00d1c..3cff1a5c1a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -483,7 +483,6 @@ virDomainNetReleaseActualDevice;
 virDomainNetRemove;
 virDomainNetRemoveHostdev;
 virDomainNetResolveActualType;
-virDomainNetSetDeviceImpl;
 virDomainNetTypeFromString;
 virDomainNetTypeSharesHostView;
 virDomainNetTypeToString;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index daeedf2995..5ef5b91581 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4686,52 +4686,6 @@ networkAllocatePort(virNetworkObjPtr obj,
 }
 
 
-static int
-networkAllocateActualDevice(virNetworkPtr net,
-                            virDomainDefPtr dom,
-                            virDomainNetDefPtr iface)
-{
-    virNetworkDriverStatePtr driver = networkGetDriver();
-    virNetworkPortDefPtr port = NULL;
-    virNetworkObjPtr obj;
-    int ret =  -1;
-
-    obj = virNetworkObjFindByName(driver->networks, net->name);
-    if (!obj) {
-        virReportError(VIR_ERR_NO_NETWORK,
-                       _("no network with matching name '%s'"),
-                       net->name);
-        return -1;
-    }
-
-    if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Expected a interface for a virtual network"));
-        goto cleanup;
-    }
-
-    if (!(port = virDomainNetDefToNetworkPort(dom, iface)))
-        goto cleanup;
-
-    if (networkAllocatePort(obj, port) < 0)
-        goto cleanup;
-
-    VIR_DEBUG("Populating net def");
-    if (virDomainNetDefActualFromNetworkPort(iface, port) < 0)
-        goto cleanup;
-
-    ret = 0;
- cleanup:
-    if (ret < 0) {
-        virDomainActualNetDefFree(iface->data.network.actual);
-        iface->data.network.actual = NULL;
-    }
-    virNetworkPortDefFree(port);
-    virNetworkObjEndAPI(&obj);
-    return ret;
-}
-
-
 /* networkNotifyPort:
  * @obj: the network to notify
  * @port: the port definition to notify
@@ -4887,54 +4841,6 @@ networkNotifyPort(virNetworkObjPtr obj,
 }
 
 
-static int
-networkNotifyActualDevice(virNetworkPtr net,
-                          virDomainDefPtr dom,
-                          virDomainNetDefPtr iface)
-{
-    virNetworkDriverStatePtr driver = networkGetDriver();
-    virNetworkObjPtr obj;
-    virNetworkDefPtr netdef;
-    virNetworkPortDefPtr port = NULL;
-    int ret = -1;
-
-    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 (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
-        goto cleanup;
-
-    if (networkNotifyPort(obj, port) < 0)
-        goto cleanup;
-
-    ret = 0;
- cleanup:
-    virNetworkObjEndAPI(&obj);
-    virNetworkPortDefFree(port);
-    return ret;
-}
-
-
 /* networkReleasePort:
  * @obj: the network to release from
  * @port: the port definition to release
@@ -5050,63 +4956,6 @@ networkReleasePort(virNetworkObjPtr obj,
 }
 
 
-/* networkReleaseActualDevice:
- * @dom: domain definition that @iface belongs to
- * @iface:  a domain's NetDef (interface definition)
- *
- * Given a domain <interface> element that previously had its <actual>
- * element filled in (and possibly a physical device allocated to it),
- * free up the physical device for use by someone else, and free the
- * virDomainActualNetDef.
- *
- * Returns 0 on success, -1 on failure.
- */
-static int
-networkReleaseActualDevice(virNetworkPtr net,
-                           virDomainDefPtr dom,
-                           virDomainNetDefPtr iface)
-{
-    virNetworkDriverStatePtr driver = networkGetDriver();
-    virNetworkObjPtr obj;
-    virNetworkPortDefPtr port = NULL;
-    int ret = -1;
-
-    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;
-    }
-
-    if (iface->data.network.actual == NULL) {
-        ret = 0;
-        goto cleanup;
-    }
-
-    if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
-        goto cleanup;
-
-    if (networkReleasePort(obj, port) < 0)
-        goto cleanup;
-
-    ret = 0;
- cleanup:
-    virNetworkObjEndAPI(&obj);
-    if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
-        virDomainActualNetDefFree(iface->data.network.actual);
-        iface->data.network.actual = NULL;
-    }
-    virNetworkPortDefFree(port);
-    return ret;
-}
-
 
 /**
  * networkCheckBandwidth:
@@ -5474,48 +5323,6 @@ networkUpdatePortBandwidth(virNetworkObjPtr obj,
 }
 
 
-static int
-networkBandwidthUpdate(virDomainNetDefPtr iface,
-                       virNetDevBandwidthPtr newBandwidth)
-{
-    virNetworkDriverStatePtr driver = networkGetDriver();
-    virNetworkObjPtr obj = NULL;
-    virNetDevBandwidthPtr oldBandwidth = virDomainNetGetActualBandwidth(iface);
-    int ret = -1;
-
-    if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Expected a interface for a virtual network"));
-        return -1;
-    }
-
-    if (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_BRIDGE ||
-        iface->data.network.actual->data.bridge.brname == NULL) {
-        /* This is not an interface that's plugged into a network.
-         * We don't care. Thus from our POV bandwidth change is allowed. */
-        return 0;
-    }
-
-    obj = virNetworkObjFindByName(driver->networks, iface->data.network.name);
-    if (!obj) {
-        virReportError(VIR_ERR_NO_NETWORK,
-                       _("no network with matching name '%s'"),
-                       iface->data.network.name);
-        return ret;
-    }
-
-    ret = networkUpdatePortBandwidth(obj,
-                                     &iface->mac,
-                                     iface->data.network.actual ?
-                                     &iface->data.network.actual->class_id : NULL,
-                                     newBandwidth,
-                                     oldBandwidth);
-
-    virNetworkObjEndAPI(&obj);
-    return ret;
-}
-
-
 static virNetworkPortPtr
 networkPortLookupByUUID(virNetworkPtr net,
                         const unsigned char *uuid)
@@ -5972,12 +5779,5 @@ networkRegister(void)
         return -1;
     if (virRegisterStateDriver(&networkStateDriver) < 0)
         return -1;
-
-    virDomainNetSetDeviceImpl(
-        networkAllocateActualDevice,
-        networkNotifyActualDevice,
-        networkReleaseActualDevice,
-        networkBandwidthUpdate);
-
     return 0;
 }
-- 
2.20.1




More information about the libvir-list mailing list