[Babel-users] [PATCH] Add option to consider sysctl write failures as non-fatal.

Toke Høiland-Jørgensen toke at toke.dk
Mon Aug 10 16:02:34 UTC 2015


Babeld will exit with a fatal error if it is unable to write sysctls.
When running in a container, however, /proc/sys may be mounted
read-only, which causes babeld to fail.

This adds a switch to consider sysctl failures as non-fatal, in which
case a warning will be issues rather than having the daemon fail to
start.

Signed-off-by: Toke Høiland-Jørgensen <toke at toke.dk>
---
 babeld.c         |  8 ++++++--
 babeld.h         |  1 +
 babeld.man       | 12 ++++++++++++
 configuration.c  |  3 +++
 kernel_netlink.c |  7 ++++++-
 5 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/babeld.c b/babeld.c
index 943f042..45b14fa 100644
--- a/babeld.c
+++ b/babeld.c
@@ -67,6 +67,7 @@ int default_wired_hello_interval = -1;
 int resend_delay = -1;
 int random_id = 0;
 int do_daemonise = 0;
+int sysctl_nonfatal = 0;
 const char *logfile = NULL,
     *pidfile = "/var/run/babeld.pid",
     *state_file = "/var/lib/babel-state";
@@ -128,7 +129,7 @@ main(int argc, char **argv)
 
     while(1) {
         opt = getopt(argc, argv,
-                     "m:p:h:H:i:k:A:srR:uS:d:g:lwz:M:t:T:c:C:DL:I:");
+                     "m:p:h:H:i:k:A:srR:uS:d:g:lwz:M:t:T:c:C:DL:I:F");
         if(opt < 0)
             break;
 
@@ -263,6 +264,9 @@ main(int argc, char **argv)
         case 'D':
             do_daemonise = 1;
             break;
+	case 'F':
+            sysctl_nonfatal = 1;
+            break;
         case 'L':
             logfile = optarg;
             break;
@@ -800,7 +804,7 @@ main(int argc, char **argv)
             "                "
             "[-t table] [-T table] [-c file] [-C statement]\n"
             "                "
-            "[-d level] [-D] [-L logfile] [-I pidfile]\n"
+            "[-d level] [-D] [-F] [-L logfile] [-I pidfile]\n"
             "                "
             "[id] interface...\n",
             argv[0]);
diff --git a/babeld.h b/babeld.h
index 92ce9b5..c1f26fe 100644
--- a/babeld.h
+++ b/babeld.h
@@ -86,6 +86,7 @@ extern time_t reboot_time;
 extern int default_wireless_hello_interval, default_wired_hello_interval;
 extern int resend_delay;
 extern int random_id;
+extern int sysctl_nonfatal;
 extern int do_daemonise;
 extern const char *logfile, *pidfile, *state_file;
 extern int link_detect;
diff --git a/babeld.man b/babeld.man
index ec600c2..7182f30 100644
--- a/babeld.man
+++ b/babeld.man
@@ -135,6 +135,11 @@ Specify a configuration statement directly on the command line.
 .B \-D
 Daemonise at startup.
 .TP
+.B \-F
+Don't consider failures writing to sysctl as fatal. Warn of the failures, but
+continue running. This is useful when running babeld in a container that mounts
+/proc/sys as read-only (as systemd-nspawn does, for instance).
+.TP
 .BI \-L " logfile"
 Specify a file to log random ``how do you do?'' messages to.  This
 defaults to standard error if not daemonising, and to
@@ -253,6 +258,13 @@ This specifies whether to daemonize at startup, and is equivalent to
 the command-line option
 .BR \-D .
 .TP
+.BR sysctl-nonfatal " {" true | false }
+This controls whether to consider failures writing to sysctl as fatal. If set,
+warn of the failures, but continue running. This is useful when running babeld
+in a container that mounts /proc/sys as read-only (as systemd-nspawn does, for
+instance). Equivalent to the command line option
+.BR \-F .
+.TP
 .BI state-file " filename"
 This specifies the name of the file used for preserving long-term
 information between invocations of the
diff --git a/configuration.c b/configuration.c
index 6a9c09d..571e220 100644
--- a/configuration.c
+++ b/configuration.c
@@ -691,6 +691,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
               strcmp(token, "link-detect") == 0 ||
               strcmp(token, "random-id") == 0 ||
               strcmp(token, "daemonise") == 0 ||
+              strcmp(token, "sysctl-nonfatal") == 0 ||
               strcmp(token, "ipv6-subtrees") == 0 ||
               strcmp(token, "reflect-kernel-metric") == 0) {
         int b;
@@ -706,6 +707,8 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
             random_id = b;
         else if(strcmp(token, "daemonise") == 0)
             do_daemonise = b;
+        else if(strcmp(token, "sysctl-nonfatal") == 0)
+            sysctl_nonfatal = b;
         else if(strcmp(token, "ipv6-subtrees") == 0)
             has_ipv6_subtrees = b;
         else if(strcmp(token, "reflect-kernel-metric") == 0)
diff --git a/kernel_netlink.c b/kernel_netlink.c
index ab63d33..0154c63 100644
--- a/kernel_netlink.c
+++ b/kernel_netlink.c
@@ -183,8 +183,13 @@ write_proc(char *filename, int value)
     n = snprintf(buf, 100, "%d", value);
 
     fd = open(filename, O_WRONLY);
-    if(fd < 0)
+    if(fd < 0 && sysctl_nonfatal) {
+        fprintf(stderr, "Warning: writing sysctl %s failed (non-fatal): %s.\n",
+                filename, strerror(errno));
+        return 1;
+    } else if(fd < 0) {
         return -1;
+    }
 
     rc = write(fd, buf, n);
     if(rc < n) {
-- 
2.5.0



More information about the Babel-users mailing list