Index: libvirt-0.7.6/src/conf/network_conf.c =================================================================== --- libvirt-0.7.6.orig/src/conf/network_conf.c +++ libvirt-0.7.6/src/conf/network_conf.c @@ -863,6 +863,138 @@ error: return NULL; } +int virNetworkIsBridge(const char *name) +{ + char *path = NULL; + int ret = 0; + struct stat s; + + if (asprintf(&path, "/sys/class/net/%s/bridge", name) < 0) + goto out; + + if (stat(path, &s) != 0) + goto out; + + if (S_ISDIR(s.st_mode)) + ret = 1; + + out: + free(path); + return ret; +} + +static unsigned long virNetworkDefSuseGetValue(const char *netName, const char *valName) +{ + unsigned long ret = 0; + char *path = NULL; + FILE *f; + + if (asprintf(&path, "/sys/class/net/%s/bridge/%s", netName, valName) < 0) + return ret; + + if ((f = fopen(path, "r")) == NULL) + goto out; + + if (fscanf(f, "%lu", &ret) != 1) { + ret = 0; + goto out; + } + + + out: + if (f != NULL) + fclose(f); + free(path); + return ret; +} + +static virNetworkObjPtr virNetworkLoadSuseNet(virConnectPtr conn, + virNetworkObjListPtr nets, + const char *name) +{ + virNetworkDefPtr def; + virNetworkObjPtr network; + int err; + + if ((network = virNetworkFindByName(nets, name))) { + virNetworkObjUnlock(network); + return network; + } + + if (VIR_ALLOC(network) < 0) { + virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); + return NULL; + } + + network->autostart = 1; + network->active = 1; + network->suse = 1; + + if (VIR_ALLOC(def) < 0) { + virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); + goto error; + } + + network->def = def; + + /* name */ + def->name = strdup(name); + if (def->name == NULL) { + virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); + goto error; + } + + /* uuid */ + if ((err = virUUIDGenerate(def->uuid))) { + virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("Failed to generate UUID: %s"), strerror(err)); + goto error; + } + + /* bridge information */ + def->bridge = strdup(name); + if (def->bridge == NULL) { + virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); + goto error; + } + def->stp = (int)virNetworkDefSuseGetValue(name, "stp_state"); + def->delay = virNetworkDefSuseGetValue(name, "forward_delay"); + + /* Add network to the list */ + if (VIR_REALLOC_N(nets->objs, nets->count + 1) < 0) { + virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); + VIR_FREE(network); + return NULL; + } + + nets->objs[nets->count] = network; + nets->count++; + + return network; + + error: + virNetworkObjFree(network); + return NULL; +} + +void virNetworkLoadSuseNetworks(virConnectPtr conn, + virNetworkObjListPtr nets) +{ + DIR *dir = NULL; + struct dirent *de; + + dir = opendir("/sys/class/net"); + if (dir == NULL) + return; + + while ((de = readdir(dir))) { + if (virNetworkIsBridge(de->d_name)) { + virNetworkLoadSuseNet(conn, nets, de->d_name); + } + } + closedir(dir); +} + int virNetworkLoadAllConfigs(virConnectPtr conn, virNetworkObjListPtr nets, const char *configDir, @@ -902,6 +1034,7 @@ int virNetworkLoadAllConfigs(virConnectP closedir(dir); + virNetworkLoadSuseNetworks(conn, nets); return 0; } Index: libvirt-0.7.6/src/conf/network_conf.h =================================================================== --- libvirt-0.7.6.orig/src/conf/network_conf.h +++ libvirt-0.7.6/src/conf/network_conf.h @@ -94,6 +94,7 @@ struct _virNetworkObj { unsigned int active : 1; unsigned int autostart : 1; unsigned int persistent : 1; + unsigned int suse : 1; virNetworkDefPtr def; /* The current definition */ virNetworkDefPtr newDef; /* New definition to activate at shutdown */ @@ -190,4 +191,8 @@ int virNetworkSetBridgeName(virConnectPt void virNetworkObjLock(virNetworkObjPtr obj); void virNetworkObjUnlock(virNetworkObjPtr obj); +int virNetworkIsBridge(const char *name); +void virNetworkLoadSuseNetworks(virConnectPtr conn, + virNetworkObjListPtr nets); + #endif /* __NETWORK_CONF_H__ */ Index: libvirt-0.7.6/src/network/bridge_driver.c =================================================================== --- libvirt-0.7.6.orig/src/network/bridge_driver.c +++ libvirt-0.7.6/src/network/bridge_driver.c @@ -817,7 +817,8 @@ networkReloadIptablesRules(struct networ for (i = 0 ; i < driver->networks.count ; i++) { virNetworkObjLock(driver->networks.objs[i]); - if (virNetworkObjIsActive(driver->networks.objs[i])) { + if (virNetworkObjIsActive(driver->networks.objs[i]) && + !(driver->networks.objs[i]->suse)) { networkRemoveIptablesRules(driver, driver->networks.objs[i]); if (!networkAddIptablesRules(NULL, driver, driver->networks.objs[i])) { /* failed to add but already logged */ @@ -1010,6 +1011,12 @@ static int networkShutdownNetworkDaemon( unlink(stateFile); VIR_FREE(stateFile); + if (network->suse) { + VIR_WARN("Network '%s' is not under libvirt control and will not be " + "shutdown\n", network->def->name); + return -1; + } + if (network->dnsmasqPid > 0) kill(network->dnsmasqPid, SIGTERM); @@ -1105,11 +1112,26 @@ static int networkCloseNetwork(virConnec return 0; } +static void networkDriverSuseRefresh(virConnectPtr conn, + struct network_driver *driver) { + int i = 0; + virNetworkObjPtr netObj; + + virNetworkLoadSuseNetworks(conn, &driver->networks); + while (i < driver->networks.count) { + netObj = driver->networks.objs[i]; + if (netObj->suse && !virNetworkIsBridge(netObj->def->name)) + virNetworkRemoveInactive(&driver->networks, netObj); + i++; + } +} + static int networkNumNetworks(virConnectPtr conn) { int nactive = 0, i; struct network_driver *driver = conn->networkPrivateData; networkDriverLock(driver); + networkDriverSuseRefresh(conn, driver); for (i = 0 ; i < driver->networks.count ; i++) { virNetworkObjLock(driver->networks.objs[i]); if (virNetworkObjIsActive(driver->networks.objs[i])) @@ -1126,6 +1148,7 @@ static int networkListNetworks(virConnec int got = 0, i; networkDriverLock(driver); + networkDriverSuseRefresh(conn, driver); for (i = 0 ; i < driver->networks.count && got < nnames ; i++) { virNetworkObjLock(driver->networks.objs[i]); if (virNetworkObjIsActive(driver->networks.objs[i])) { @@ -1510,6 +1533,13 @@ static int networkSetAutostart(virNetwor goto cleanup; } + if (network->suse) { + networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR, + ": Network '%s' is not under libvirt control", + network->def->name); + return -1; + } + autostart = (autostart != 0); if (network->autostart != autostart) { Index: libvirt-0.7.6/src/libvirt_private.syms =================================================================== --- libvirt-0.7.6.orig/src/libvirt_private.syms +++ libvirt-0.7.6/src/libvirt_private.syms @@ -408,6 +408,8 @@ virNetworkSaveConfig; virNetworkSetBridgeName; virNetworkObjLock; virNetworkObjUnlock; +virNetworkLoadSuseNetworks; +virNetworkIsBridge; # nodeinfo.h