[Libvir] PATCH 15/20: remove use of libsysfs in bridge code
Daniel P. Berrange
berrange at redhat.com
Fri Jun 22 02:17:07 UTC 2007
Sigh, missed another attachment...
On Fri, Jun 22, 2007 at 03:12:11AM +0100, Daniel P. Berrange wrote:
> The current code for setting up bridges in virtual networks links against
> the libsysfs library. This is use to get/set the spanning-tree-protocol and
> forward-delay parameters on the bridge device. None of the four methods
> using libsysfs are ever called though. The fact that the setters are not
> called during network start is a bug. There is no need for getters at all
> since we have the config in memory all the time. The libsysfs is also not
> exactly an ABI stable library - we're unable to compile libvirt on FC5
> for example because of this. This patch changes the bridge code to just
> invoke the brctl command directly which is much more portable & avoids
> the need for us to link libvirt.so against libsysfs.so It also fixes the
> network creation process to actually set STP & forward-delay parameters
> if specified.
>
> configure.in | 16 --
> libvirt.spec.in | 4
> qemud/Makefile.am | 2
> qemud/bridge.c | 298 +++++++++++++++++++++++-------------------------------
> qemud/driver.c | 16 ++
> 5 files changed, 146 insertions(+), 190 deletions(-)
>
>
> Dan.
> --
> |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
> |=- Perl modules: http://search.cpan.org/~danberr/ -=|
> |=- Projects: http://freshmeat.net/~danielpb/ -=|
> |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
>
> --
> Libvir-list mailing list
> Libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
-------------- next part --------------
diff -r 385caba1d568 configure.in
--- a/configure.in Thu Jun 21 20:39:58 2007 -0400
+++ b/configure.in Thu Jun 21 20:39:59 2007 -0400
@@ -219,22 +219,6 @@ else
if test "$WITH_XEN" != "0" ; then
LIBVIRT_FEATURES="$LIBVIRT_FEATURES -DWITH_XEN"
fi
-fi
-
-dnl
-dnl check for libsyfs (>= 2.0.0); allow disabling bridge parameters support altogether
-dnl
-AC_ARG_ENABLE(bridge-params,
- AC_HELP_STRING([--disable-bridge-params],
- [disable support for setting bridge parameters using libsysfs [default=no]]),,
- enable_bridge_params=yes)
-
-if test x"$enable_bridge_params" == "xyes"; then
- AC_CHECK_LIB(sysfs, sysfs_open_device,
- [AC_CHECK_HEADER(sysfs/libsysfs.h,
- AC_DEFINE(ENABLE_BRIDGE_PARAMS, , [enable setting bridge parameters using libsysfs])
- SYSFS_LIBS="-lsysfs" AC_SUBST(SYSFS_LIBS),
- AC_MSG_ERROR([You must install libsysfs in order to compile libvirt]))])
fi
dnl
diff -r 385caba1d568 libvirt.spec.in
--- a/libvirt.spec.in Thu Jun 21 20:39:58 2007 -0400
+++ b/libvirt.spec.in Thu Jun 21 20:39:59 2007 -0400
@@ -14,13 +14,13 @@ Requires: readline
Requires: readline
Requires: ncurses
Requires: dnsmasq
+Requires: bridge-utils
+Requires: iptables
BuildRequires: xen-devel
BuildRequires: libxml2-devel
BuildRequires: readline-devel
BuildRequires: ncurses-devel
BuildRequires: gettext
-BuildRequires: libsysfs-devel
-BuildRequires: /sbin/iptables
BuildRequires: gnutls-devel
Obsoletes: libvir
ExclusiveArch: i386 x86_64 ia64
diff -r 385caba1d568 qemud/Makefile.am
--- a/qemud/Makefile.am Thu Jun 21 20:39:58 2007 -0400
+++ b/qemud/Makefile.am Thu Jun 21 20:39:59 2007 -0400
@@ -28,7 +28,7 @@ libvirt_qemud_CFLAGS = \
-DREMOTE_PID_FILE="\"$(REMOTE_PID_FILE)\"" \
-DGETTEXT_PACKAGE=\"$(PACKAGE)\"
-libvirt_qemud_LDFLAGS = $(WARN_CFLAGS) $(LIBXML_LIBS) $(SYSFS_LIBS)
+libvirt_qemud_LDFLAGS = $(WARN_CFLAGS) $(LIBXML_LIBS)
libvirt_qemud_DEPENDENCIES = ../src/libvirt.la
libvirt_qemud_LDADD = ../src/libvirt.la
diff -r 385caba1d568 qemud/bridge.c
--- a/qemud/bridge.c Thu Jun 21 20:39:58 2007 -0400
+++ b/qemud/bridge.c Thu Jun 21 20:39:59 2007 -0400
@@ -33,6 +33,8 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <paths.h>
+#include <sys/wait.h>
#include <linux/param.h> /* HZ */
#include <linux/sockios.h> /* SIOCBRADDBR etc. */
@@ -43,6 +45,7 @@
#define MAX_BRIDGE_ID 256
+#define BRCTL_PATH "/usr/sbin/brctl"
#define JIFFIES_TO_MS(j) (((j)*1000)/HZ)
#define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
@@ -423,184 +426,137 @@ brGetInetNetmask(brControl *ctl,
return brGetInetAddr(ctl, ifname, SIOCGIFNETMASK, addr, maxlen);
}
-#ifdef ENABLE_BRIDGE_PARAMS
-
-#include <sysfs/libsysfs.h>
-
static int
-brSysfsPrep(struct sysfs_class_device **dev,
- struct sysfs_attribute **attr,
- const char *bridge,
- const char *attrname)
-{
- *dev = NULL;
- *attr = NULL;
-
- if (!(*dev = sysfs_open_class_device("net", bridge)))
- return errno;
-
- if (!(*attr = sysfs_get_classdev_attr(*dev, attrname))) {
- int err = errno;
-
- sysfs_close_class_device(*dev);
- *dev = NULL;
-
- return err;
- }
-
- return 0;
-}
-
-static int
-brSysfsWriteInt(struct sysfs_attribute *attr,
- int value)
-{
- char buf[32];
- int len;
-
- len = snprintf(buf, sizeof(buf), "%d\n", value);
-
- if (len > (int)sizeof(buf))
- len = sizeof(buf); /* paranoia, shouldn't happen */
-
- return sysfs_write_attribute(attr, buf, len) == 0 ? 0 : errno;
-}
-
-int
-brSetForwardDelay(brControl *ctl,
+brctlSpawn(char * const *argv)
+{
+ pid_t pid, ret;
+ int status;
+ int null = -1;
+
+ if ((null = open(_PATH_DEVNULL, O_RDONLY)) < 0)
+ return errno;
+
+ pid = fork();
+ if (pid == -1) {
+ int saved_errno = errno;
+ close(null);
+ return saved_errno;
+ }
+
+ if (pid == 0) { /* child */
+ dup2(null, STDIN_FILENO);
+ dup2(null, STDOUT_FILENO);
+ dup2(null, STDERR_FILENO);
+ close(null);
+
+ execvp(argv[0], argv);
+
+ _exit (1);
+ }
+
+ close(null);
+
+ while ((ret = waitpid(pid, &status, 0) == -1) && errno == EINTR);
+ if (ret == -1)
+ return errno;
+
+ return (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? 0 : EINVAL;
+}
+
+int
+brSetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED,
const char *bridge,
int delay)
{
- struct sysfs_class_device *dev;
- struct sysfs_attribute *attr;
- int err = 0;
-
- if (!ctl || !bridge)
- return EINVAL;
-
- if ((err = brSysfsPrep(&dev, &attr, bridge, SYSFS_BRIDGE_ATTR "/forward_delay")))
- return err;
-
- err = brSysfsWriteInt(attr, MS_TO_JIFFIES(delay));
-
- sysfs_close_class_device(dev);
-
- return err;
-}
-
-int
-brGetForwardDelay(brControl *ctl,
- const char *bridge,
- int *delayp)
-{
- struct sysfs_class_device *dev;
- struct sysfs_attribute *attr;
- int err = 0;
-
- if (!ctl || !bridge || !delayp)
- return EINVAL;
-
- if ((err = brSysfsPrep(&dev, &attr, bridge, SYSFS_BRIDGE_ATTR "/forward_delay")))
- return err;
-
- *delayp = strtoul(attr->value, NULL, 0);
-
- if (errno != ERANGE) {
- *delayp = JIFFIES_TO_MS(*delayp);
- } else {
- err = errno;
- }
-
- sysfs_close_class_device(dev);
-
- return err;
-}
-
-int
-brSetEnableSTP(brControl *ctl,
+ char **argv;
+ int retval = ENOMEM;
+ int n;
+ char delayStr[30];
+
+ n = 1 + /* brctl */
+ 1 + /* setfd */
+ 1 + /* brige name */
+ 1; /* value */
+
+ snprintf(delayStr, sizeof(delayStr), "%d", delay);
+
+ if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
+ goto error;
+
+ n = 0;
+
+ if (!(argv[n++] = strdup(BRCTL_PATH)))
+ goto error;
+
+ if (!(argv[n++] = strdup("setfd")))
+ goto error;
+
+ if (!(argv[n++] = strdup(bridge)))
+ goto error;
+
+ if (!(argv[n++] = strdup(delayStr)))
+ goto error;
+
+ argv[n++] = NULL;
+
+ retval = brctlSpawn(argv);
+
+ error:
+ if (argv) {
+ n = 0;
+ while (argv[n])
+ free(argv[n++]);
+ free(argv);
+ }
+
+ return retval;
+}
+
+int
+brSetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED,
const char *bridge,
int enable)
{
- struct sysfs_class_device *dev;
- struct sysfs_attribute *attr;
- int err = 0;
-
- if (!ctl || !bridge)
- return EINVAL;
-
- if ((err = brSysfsPrep(&dev, &attr, bridge, SYSFS_BRIDGE_ATTR "/stp_state")))
- return err;
-
- err = brSysfsWriteInt(attr, (enable == 0) ? 0 : 1);
-
- sysfs_close_class_device(dev);
-
- return err;
-}
-
-int
-brGetEnableSTP(brControl *ctl,
- const char *bridge,
- int *enablep)
-{
- struct sysfs_class_device *dev;
- struct sysfs_attribute *attr;
- int err = 0;
-
- if (!ctl || !bridge || !enablep)
- return EINVAL;
-
- if ((err = brSysfsPrep(&dev, &attr, bridge, SYSFS_BRIDGE_ATTR "/stp_state")))
- return err;
-
- *enablep = strtoul(attr->value, NULL, 0);
-
- if (errno != ERANGE) {
- *enablep = (*enablep == 0) ? 0 : 1;
- } else {
- err = errno;
- }
-
- sysfs_close_class_device(dev);
-
- return err;
-}
-
-#else /* ENABLE_BRIDGE_PARAMS */
-
-int
-brSetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED,
- const char *bridge ATTRIBUTE_UNUSED,
- int delay ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-int
-brGetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED,
- const char *bridge ATTRIBUTE_UNUSED,
- int *delay ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-int
-brSetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED,
- const char *bridge ATTRIBUTE_UNUSED,
- int enable ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-int
-brGetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED,
- const char *bridge ATTRIBUTE_UNUSED,
- int *enable ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-#endif /* ENABLE_BRIDGE_PARAMS */
+ char **argv;
+ int retval = ENOMEM;
+ int n;
+
+ n = 1 + /* brctl */
+ 1 + /* setfd */
+ 1 + /* brige name */
+ 1; /* value */
+
+ if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
+ goto error;
+
+ n = 0;
+
+ if (!(argv[n++] = strdup(BRCTL_PATH)))
+ goto error;
+
+ if (!(argv[n++] = strdup("setfd")))
+ goto error;
+
+ if (!(argv[n++] = strdup(bridge)))
+ goto error;
+
+ if (!(argv[n++] = strdup(enable ? "on" : "off")))
+ goto error;
+
+ argv[n++] = NULL;
+
+ retval = brctlSpawn(argv);
+
+ error:
+ if (argv) {
+ n = 0;
+ while (argv[n])
+ free(argv[n++]);
+ free(argv);
+ }
+
+ return retval;
+}
/*
* Local variables:
diff -r 385caba1d568 qemud/driver.c
--- a/qemud/driver.c Thu Jun 21 20:39:58 2007 -0400
+++ b/qemud/driver.c Thu Jun 21 20:39:59 2007 -0400
@@ -1152,6 +1152,22 @@ int qemudStartNetworkDaemon(struct qemud
qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot create bridge '%s' : %s", name, strerror(err));
return -1;
+ }
+
+
+ if (network->def->forwardDelay &&
+ (err = brSetForwardDelay(driver->brctl, network->bridge, network->def->forwardDelay))) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "failed to set bridge forward delay to %d\n",
+ network->def->forwardDelay);
+ goto err_delbr;
+ }
+
+ if ((err = brSetForwardDelay(driver->brctl, network->bridge, network->def->disableSTP ? 0 : 1))) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "failed to set bridge STP to %s\n",
+ network->def->disableSTP ? "off" : "on");
+ goto err_delbr;
}
if (network->def->ipAddress[0] &&
More information about the libvir-list
mailing list