]> xenbits.xensource.com Git - libvirt.git/commitdiff
Generate network bridge names if none passed at define/create time.
authorCole Robinson <crobinso@redhat.com>
Mon, 2 Mar 2009 17:37:03 +0000 (17:37 +0000)
committerCole Robinson <crobinso@redhat.com>
Mon, 2 Mar 2009 17:37:03 +0000 (17:37 +0000)
ChangeLog
src/bridge.c
src/bridge.h
src/libvirt_private.syms
src/network_conf.c
src/network_conf.h
src/network_driver.c

index 7cd1035ec2aad061f052ccd5a0241fbca7e9178e..3c5adb6332c04dbb5fcad61a0fbfa2f6a51bdc09 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Mar 2 12:34:25 EST 2009 Cole Robinson <crobinso@redhat.com>
+
+       * src/bridge.c src/bridge.h src/libvirt_private.syms src/network_conf.c
+         src/network_conf.h src/network_driver.c:
+         Generate network bridge names if none passed at define/create time.
+
 Mon Mar 2 12:30:08 EST 2009 Cole Robinson <crobinso@redhat.com>
 
        * src/domain_conf.c src/domain_conf.h src/qemu_driver.c:
index 668dcf04bd13944a37e29a5252661cc6752d3e04..46dc407b645f1985e59509ffcf9e9583605f3493 100644 (file)
@@ -49,7 +49,7 @@
 #include "util.h"
 #include "logging.h"
 
-#define MAX_BRIDGE_ID 256
+#define MAX_TAP_ID 256
 
 #define JIFFIES_TO_MS(j) (((j)*1000)/HZ)
 #define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
@@ -127,32 +127,13 @@ brShutdown(brControl *ctl)
 #ifdef SIOCBRADDBR
 int
 brAddBridge(brControl *ctl,
-            char **name)
+            const char *name)
 {
     if (!ctl || !ctl->fd || !name)
         return EINVAL;
 
-    if (*name) {
-        if (ioctl(ctl->fd, SIOCBRADDBR, *name) == 0)
-            return 0;
-    } else {
-        int id = 0;
-        do {
-            char try[50];
-
-            snprintf(try, sizeof(try), "virbr%d", id);
-
-            if (ioctl(ctl->fd, SIOCBRADDBR, try) == 0) {
-                if (!(*name = strdup(try))) {
-                    ioctl(ctl->fd, SIOCBRDELBR, name);
-                    return ENOMEM;
-                }
-                return 0;
-            }
-
-            id++;
-        } while (id < MAX_BRIDGE_ID);
-    }
+    if (ioctl(ctl->fd, SIOCBRADDBR, name) == 0)
+        return 0;
 
     return errno;
 }
@@ -547,7 +528,7 @@ brAddTap(brControl *ctl,
         }
 
         id++;
-    } while (subst && id <= MAX_BRIDGE_ID);
+    } while (subst && id <= MAX_TAP_ID);
 
  error:
     close(fd);
index f37ab721077f16204430af7799c8e462ed4156e5..e06ff417fefa016576bd0d9652cc681fa5e236b3 100644 (file)
@@ -47,7 +47,7 @@ int     brInit                  (brControl **ctl);
 void    brShutdown              (brControl *ctl);
 
 int     brAddBridge             (brControl *ctl,
-                                 char **name);
+                                 const char *name);
 int     brDeleteBridge          (brControl *ctl,
                                  const char *name);
 int     brHasBridge             (brControl *ctl,
index 7ad7e669ee677bb2863c67f09a5639d4b37fb846..950ecdc09757d4e6da0c7fb432796f7dcc2612e3 100644 (file)
@@ -206,6 +206,7 @@ virNetworkObjListFree;
 virNetworkDefParseNode;
 virNetworkRemoveInactive;
 virNetworkSaveConfig;
+virNetworkSetBridgeName;
 virNetworkObjLock;
 virNetworkObjUnlock;
 
index 6ad0d01fd78d1bf25dc9b2991512a4724615aa81..5de164eeeb536bf3e4d2a90a0b02b02daceac8df 100644 (file)
@@ -43,6 +43,7 @@
 #include "buf.h"
 #include "c-ctype.h"
 
+#define MAX_BRIDGE_ID 256
 #define VIR_FROM_THIS VIR_FROM_NETWORK
 
 VIR_ENUM_DECL(virNetworkForward)
@@ -743,6 +744,12 @@ virNetworkObjPtr virNetworkLoadConfig(virConnectPtr conn,
         goto error;
     }
 
+    /* Generate a bridge if none is found, but don't check for collisions
+     * if a bridge is hardcoded, so the network is at least defined
+     */
+    if (!def->bridge && !(def->bridge = virNetworkAllocateBridge(conn, nets)))
+        goto error;
+
     if (!(net = virNetworkAssignDef(conn, nets, def)))
         goto error;
 
@@ -848,6 +855,77 @@ char *virNetworkConfigFile(virConnectPtr conn,
     return ret;
 }
 
+int virNetworkBridgeInUse(const virNetworkObjListPtr nets,
+                          const char *bridge,
+                          const char *skipname)
+{
+    unsigned int i;
+    unsigned int ret = 0;
+
+    for (i = 0 ; i < nets->count ; i++) {
+        virNetworkObjLock(nets->objs[i]);
+        if (nets->objs[i]->def->bridge &&
+            STREQ(nets->objs[i]->def->bridge, bridge) &&
+            !(skipname && STREQ(nets->objs[i]->def->name, skipname)))
+                ret = 1;
+        virNetworkObjUnlock(nets->objs[i]);
+    }
+
+    return ret;
+}
+
+char *virNetworkAllocateBridge(virConnectPtr conn,
+                               const virNetworkObjListPtr nets)
+{
+
+    int id = 0;
+    char *newname;
+
+    do {
+        char try[50];
+
+        snprintf(try, sizeof(try), "virbr%d", id);
+
+        if (!virNetworkBridgeInUse(nets, try, NULL)) {
+            if (!(newname = strdup(try))) {
+                virReportOOMError(conn);
+                return NULL;
+            }
+            return newname;
+        }
+
+        id++;
+    } while (id < MAX_BRIDGE_ID);
+
+    virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                          _("Bridge generation exceeded max id %d"),
+                          MAX_BRIDGE_ID);
+    return NULL;
+}
+
+int virNetworkSetBridgeName(virConnectPtr conn,
+                            const virNetworkObjListPtr nets,
+                            virNetworkDefPtr def) {
+
+    int ret = -1;
+
+    if (def->bridge) {
+        if (virNetworkBridgeInUse(nets, def->bridge, def->name)) {
+            networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                               _("bridge name '%s' already in use."),
+                               def->bridge);
+            goto error;
+        }
+    } else {
+        /* Allocate a bridge name */
+        if (!(def->bridge = virNetworkAllocateBridge(conn, nets)))
+            goto error;
+    }
+
+    ret = 0;
+error:
+    return ret;
+}
 
 void virNetworkObjLock(virNetworkObjPtr obj)
 {
index 94a174806fb46827926f68e26967c5bac5702b9f..7e36e6872d5651725cd793f1ced27e0fdf7c9b81 100644 (file)
@@ -107,6 +107,10 @@ virNetworkIsActive(const virNetworkObjPtr net)
     return net->active;
 }
 
+#define networkReportError(conn, dom, net, code, fmt...)                \
+    virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__,         \
+                           __FUNCTION__, __LINE__, fmt)
+
 
 virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjListPtr nets,
                                       const unsigned char *uuid);
@@ -165,6 +169,16 @@ char *virNetworkConfigFile(virConnectPtr conn,
                            const char *dir,
                            const char *name);
 
+int virNetworkBridgeInUse(const virNetworkObjListPtr nets,
+                          const char *bridge,
+                          const char *skipname);
+
+char *virNetworkAllocateBridge(virConnectPtr conn,
+                               const virNetworkObjListPtr nets);
+
+int virNetworkSetBridgeName(virConnectPtr conn,
+                            const virNetworkObjListPtr nets,
+                            virNetworkDefPtr def);
 
 void virNetworkObjLock(virNetworkObjPtr obj);
 void virNetworkObjUnlock(virNetworkObjPtr obj);
index 4b9c6666233613441d4e005664301d32aee133d8..a17a7691d5586c49590bbcbf6dd38b3c5f8de6b3 100644 (file)
@@ -91,11 +91,6 @@ static int networkShutdown(void);
 
 #define networkLog(level, msg...) fprintf(stderr, msg)
 
-#define networkReportError(conn, dom, net, code, fmt...)                \
-    virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__,         \
-                           __FUNCTION__, __LINE__, fmt)
-
-
 static int networkStartNetworkDaemon(virConnectPtr conn,
                                    struct network_driver *driver,
                                    virNetworkObjPtr network);
@@ -812,7 +807,7 @@ static int networkStartNetworkDaemon(virConnectPtr conn,
         return -1;
     }
 
-    if ((err = brAddBridge(driver->brctl, &network->def->bridge))) {
+    if ((err = brAddBridge(driver->brctl, network->def->bridge))) {
         virReportSystemError(conn, err,
                              _("cannot create bridge '%s'"),
                              network->def->bridge);
@@ -1113,6 +1108,9 @@ static virNetworkPtr networkCreate(virConnectPtr conn, const char *xml) {
     if (!(def = virNetworkDefParseString(conn, xml)))
         goto cleanup;
 
+    if (virNetworkSetBridgeName(conn, &driver->networks, def))
+        goto cleanup;
+
     if (!(network = virNetworkAssignDef(conn,
                                         &driver->networks,
                                         def)))
@@ -1147,6 +1145,9 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
     if (!(def = virNetworkDefParseString(conn, xml)))
         goto cleanup;
 
+    if (virNetworkSetBridgeName(conn, &driver->networks, def))
+        goto cleanup;
+
     if (!(network = virNetworkAssignDef(conn,
                                         &driver->networks,
                                         def)))