SHA256
1
0
forked from pool/libvirt
libvirt/suse-network.patch

192 lines
5.0 KiB
Diff

Index: libvirt-0.7.5/src/conf/network_conf.c
===================================================================
--- libvirt-0.7.5.orig/src/conf/network_conf.c
+++ libvirt-0.7.5/src/conf/network_conf.c
@@ -863,6 +863,137 @@ 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(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))) {
+ 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;
+
+ 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;
+}
+
+static 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 +1033,7 @@ int virNetworkLoadAllConfigs(virConnectP
closedir(dir);
+ virNetworkLoadSuseNetworks(conn, nets);
return 0;
}
Index: libvirt-0.7.5/src/conf/network_conf.h
===================================================================
--- libvirt-0.7.5.orig/src/conf/network_conf.h
+++ libvirt-0.7.5/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 readonly : 1;
virNetworkDefPtr def; /* The current definition */
virNetworkDefPtr newDef; /* New definition to activate at shutdown */
Index: libvirt-0.7.5/src/network/bridge_driver.c
===================================================================
--- libvirt-0.7.5.orig/src/network/bridge_driver.c
+++ libvirt-0.7.5/src/network/bridge_driver.c
@@ -1010,6 +1010,11 @@ static int networkShutdownNetworkDaemon(
unlink(stateFile);
VIR_FREE(stateFile);
+ if (network->readonly) {
+ VIR_WARN("Network '%s' is readonly\n", network->def->name);
+ return -1;
+ }
+
if (network->dnsmasqPid > 0)
kill(network->dnsmasqPid, SIGTERM);
@@ -1510,6 +1515,12 @@ static int networkSetAutostart(virNetwor
goto cleanup;
}
+ if (network->readonly) {
+ networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
+ ": Network '%s' is readonly", network->def->name);
+ return -1;
+ }
+
autostart = (autostart != 0);
if (network->autostart != autostart) {