Generate network bridge names if none passed at define/create time.

This commit is contained in:
Cole Robinson 2009-03-02 17:37:03 +00:00
parent adecc8fc9e
commit 1f11e3bb61
7 changed files with 112 additions and 31 deletions

View File

@ -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:

View 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);

View 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,

View File

@ -206,6 +206,7 @@ virNetworkObjListFree;
virNetworkDefParseNode;
virNetworkRemoveInactive;
virNetworkSaveConfig;
virNetworkSetBridgeName;
virNetworkObjLock;
virNetworkObjUnlock;

View 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)
{

View 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);

View 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)))