Index: libvirt-0.4.6/src/network_conf.c =================================================================== --- libvirt-0.4.6.orig/src/network_conf.c +++ libvirt-0.4.6/src/network_conf.c @@ -752,6 +752,131 @@ error: return NULL; } +static 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(char *netName, 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, + virNetworkObjPtr *nets, + char *name) +{ + virNetworkDefPtr def; + virNetworkObjPtr network; + int err; + + if ((network = virNetworkFindByName(*nets, name))) { + return network; + } + + if (VIR_ALLOC(network) < 0) { + virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL); + return NULL; + } + + network->autostart = 1; + network->active = 1; + network->readonly = 1; + network->next = *nets; + + 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 */ + *nets = network; + return network; + + error: + virNetworkObjFree(network); + return NULL; +} + +static void virNetworkLoadSuseNetworks(virConnectPtr conn, + virNetworkObjPtr *nets) +{ + DIR *dir = NULL; + struct dirent *de; + int count = 0; + + dir = opendir("/sys/class/net"); + if (dir == NULL) + return NULL; + + while ((de = readdir(dir))) { + if (virNetworkIsBridge(de->d_name)) { + virNetworkLoadSuseNet(conn, nets, de->d_name); + } + } + closedir(dir); +} + int virNetworkLoadAllConfigs(virConnectPtr conn, virNetworkObjPtr *nets, const char *configDir, @@ -787,6 +912,7 @@ int virNetworkLoadAllConfigs(virConnectP closedir(dir); + virNetworkLoadSuseNetworks(conn, nets); return 0; } Index: libvirt-0.4.6/src/network_conf.h =================================================================== --- libvirt-0.4.6.orig/src/network_conf.h +++ libvirt-0.4.6/src/network_conf.h @@ -82,6 +82,7 @@ struct _virNetworkObj { unsigned int active : 1; unsigned int autostart : 1; unsigned int persistent : 1; + unsigned int readonly : 1; char *configFile; /* Persistent config file path */ char *autostartLink; /* Symlink path for autostart */ Index: libvirt-0.4.6/src/qemu_driver.c =================================================================== --- libvirt-0.4.6.orig/src/qemu_driver.c +++ libvirt-0.4.6/src/qemu_driver.c @@ -1601,6 +1601,12 @@ static int qemudShutdownNetworkDaemon(vi if (!virNetworkIsActive(network)) return 0; + if (network->readonly) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + ": Network '%s' is readonly", network->def->name); + return -1; + } + if (network->dnsmasqPid > 0) kill(network->dnsmasqPid, SIGTERM); @@ -3974,6 +3980,12 @@ static int qemudNetworkSetAutostart(virN return -1; } + if (network->readonly) { + qemudReportError(net->conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + ": Network '%s' is readonly", network->def->name); + return -1; + } + autostart = (autostart != 0); if (network->autostart == autostart)