From 1f11e3bb618aee45b4ba1eb3d9e1d53c02e3064f Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Mon, 2 Mar 2009 17:37:03 +0000 Subject: [PATCH] Generate network bridge names if none passed at define/create time. --- ChangeLog | 6 ++++ src/bridge.c | 29 +++------------ src/bridge.h | 2 +- src/libvirt_private.syms | 1 + src/network_conf.c | 78 ++++++++++++++++++++++++++++++++++++++++ src/network_conf.h | 14 ++++++++ src/network_driver.c | 13 +++---- 7 files changed, 112 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cd1035ec2..3c5adb6332 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Mon Mar 2 12:34:25 EST 2009 Cole Robinson + + * 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 * src/domain_conf.c src/domain_conf.h src/qemu_driver.c: diff --git a/src/bridge.c b/src/bridge.c index 668dcf04bd..46dc407b64 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -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); diff --git a/src/bridge.h b/src/bridge.h index f37ab72107..e06ff417fe 100644 --- a/src/bridge.h +++ b/src/bridge.h @@ -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, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7ad7e669ee..950ecdc097 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -206,6 +206,7 @@ virNetworkObjListFree; virNetworkDefParseNode; virNetworkRemoveInactive; virNetworkSaveConfig; +virNetworkSetBridgeName; virNetworkObjLock; virNetworkObjUnlock; diff --git a/src/network_conf.c b/src/network_conf.c index 6ad0d01fd7..5de164eeeb 100644 --- a/src/network_conf.c +++ b/src/network_conf.c @@ -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) { diff --git a/src/network_conf.h b/src/network_conf.h index 94a174806f..7e36e6872d 100644 --- a/src/network_conf.h +++ b/src/network_conf.h @@ -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); diff --git a/src/network_driver.c b/src/network_driver.c index 4b9c666623..a17a7691d5 100644 --- a/src/network_driver.c +++ b/src/network_driver.c @@ -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))) -- GitLab