mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 19:32:19 +00:00
Generate network bridge names if none passed at define/create time.
This commit is contained in:
parent
adecc8fc9e
commit
1f11e3bb61
@ -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:
|
||||
|
27
src/bridge.c
27
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)
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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,
|
||||
|
@ -206,6 +206,7 @@ virNetworkObjListFree;
|
||||
virNetworkDefParseNode;
|
||||
virNetworkRemoveInactive;
|
||||
virNetworkSaveConfig;
|
||||
virNetworkSetBridgeName;
|
||||
virNetworkObjLock;
|
||||
virNetworkObjUnlock;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user