So, here is the new suggestion: (I meant to write run level S in the last message, not 1)
Compiling ifupdown 0.7.8 in Debian 7 and fixing dhclient boothang bug with -nw option supplied to dhclient via networking script: $ sudo aptitude install noweb $ sudo aptitude install dpkg-dev Follow the instructions: The following instructions should be enough to build from nothing but ifupdown.nw. notangle -t8 -RMakefile ifupdown.nw >Makefile notangle -Rmakenwdep.sh ifupdown.nw >makenwdep.sh chmod 755 makenwdep.sh make Modify execute.c, header.h, main.c as shown in diff below - use patch, git apply, whatever. $ nano Makefile (add -s to 2 x ln commands, make soft links not hard links, easier for testing various ifup's) $ make $ sudo ifdown -a $ sudo mv /sbin/ifup /sbin/ifup.old $ sudo rm /sbin/ifdown $ sudo rm /sbin/ifquery $ sudo make install install -m 0755 -d /sbin install -m 0755 ifup /sbin ln -s /sbin/ifup /sbin/ifdown ln -s /sbin/ifup /sbin/ifquery $ sudo mkdir /opt/initbackups $ sudo cp /etc/init.d/networking /opt/initbackups $ sudo invoke-rc.d networking stop [ ok ] Deconfiguring network interfaces...done. $ sudo patch /etc/init.d/networking /-path-to-/networking.diff patching file /etc/init.d/networking $ sudo invoke-rc.d networking start ....everything works as normal, but no long wait for dhclient to go to daemon mode. (assert removal is another suggested improvement, detailed at the end of this message.) DIFF FOR C SOURCE FILES: diff --git a/execute.c b/execute.c index c607329..a3987bf 100644 --- a/execute.c +++ b/execute.c @@ -300,12 +300,27 @@ int iface_query(interface_defn *iface) { } #line 2842 "ifupdown.nw" int execute(char *command, interface_defn *ifd, execfn *exec) { - char *out; + char *out, *tmpstr; int ret; out = parse(command, ifd); if (!out) { return 0; } - + if (dhclient_nw == 1) { + if (!(strncmp(out, "dhclient ", (size_t) 9))) { + tmpstr = (char *) malloc((strlen (out)) + (size_t) 5); + if (tmpstr == NULL) { + perror("malloc -nw, out of memory"); + exit(EXIT_FAILURE); + } + memcpy(tmpstr, out, (size_t) 9); + memcpy(&tmpstr[9], "-nw ", (size_t) 4); + strcpy(&tmpstr[13], &out[9]); /* adds /0 */ + ret = (*exec)(tmpstr); + free(tmpstr); + free(out); + return ret; + } + } ret = (*exec)(out); free(out); diff --git a/header.h b/header.h index a9cf4ba..9c4f121 100644 --- a/header.h +++ b/header.h @@ -150,6 +150,7 @@ int run_mapping(char *physical, char *logical, int len, mapping_defn *map); extern int no_act; extern int verbose; extern int run_scripts; +extern int dhclient_nw; #line 3916 "ifupdown.nw" extern interfaces_file *defn; #line 5953 "ifupdown.nw" diff --git a/main.c b/main.c index b1ab23e..ba94dac 100644 --- a/main.c +++ b/main.c @@ -19,6 +19,7 @@ int no_act = 0; int run_scripts = 1; int verbose = 0; +int dhclient_nw = 0; char *statefile = RUN_DIR "ifstate"; char *tmpstatefile = RUN_DIR ".ifstate.tmp"; #line 3920 "ifupdown.nw" @@ -97,6 +98,8 @@ static void help(char *execname, int (*cmds)(interface_defn *)) { ) printf("\t-n, --no-act\t\tprint out what would happen, but don't do it\n"); printf("\t\t\t\t(note that this option doesn't disable mappings)\n"); + if (cmds == iface_up) + printf("\t-d, --dhclient-nw\tpass nw option to dhclient if relevant\n"); printf("\t-v, --verbose\t\tprint out what would happen before doing it\n"); printf("\t-o OPTION=VALUE\t\tset OPTION to VALUE as though it were in\n"); printf("\t\t\t\t/etc/network/interfaces\n"); @@ -416,6 +419,7 @@ struct option long_opts[] = { {"force", no_argument, NULL, 2 }, {"option", required_argument, NULL, 'o'}, {"list", no_argument, NULL, 'l'}, + {"dhclient-nw", no_argument, NULL, 'd'}, {0,0,0,0} }; #line 3675 "ifupdown.nw" @@ -491,7 +495,7 @@ if (strcmp(command, "ifup")==0) { #line 3757 "ifupdown.nw" for(;;) { int c; - c = getopt_long(argc, argv, "X:s:i:o:hVvnal", long_opts, NULL); + c = getopt_long(argc, argv, "X:s:i:o:hVvnald", long_opts, NULL); if (c == EOF) break; switch(c) { @@ -599,6 +603,9 @@ case 'l': cmds = iface_list; break; #line 3867 "ifupdown.nw" +case 'd': + if (cmds == iface_up) dhclient_nw = 1; + break; case 'h': help(argv[0],cmds); break; DIFF FOR NETWORKING INIT.D SCRIPT: --- /opt/initbackups/networking 2014-04-05 06:41:06.317019467 +0100 +++ /etc/init.d/networking 2014-05-23 22:41:48.874901570 +0100 @@ -107,7 +107,7 @@ done) if [ -n "$ifaces" ] then - ifup $ifaces "$@" || true + ifup -d $ifaces "$@" || true fi fi } @@ -128,7 +128,7 @@ set -f exclusions=$(process_exclusions) log_action_begin_msg "Configuring network interfaces" - if ifup -a $exclusions $verbose && ifup_hotplug $exclusions $verbose + if ifup -a -d $exclusions $verbose && ifup_hotplug $exclusions $verbose then log_action_end_msg $? else @@ -157,7 +157,7 @@ log_action_begin_msg "Reloading network interfaces configuration" state=$(cat /run/network/ifstate) ifdown -a --exclude=lo $verbose || true - if ifup --exclude=lo $state $verbose ; then + if ifup -d --exclude=lo $state $verbose ; then log_action_end_msg $? else log_action_end_msg $? @@ -175,7 +175,7 @@ ifdown -a --exclude=lo $verbose || true set -f exclusions=$(process_exclusions) - if ifup -a --exclude=lo $exclusions $verbose && ifup_hotplug $exclusions $verbose + if ifup -a -d --exclude=lo $exclusions $verbose && ifup_hotplug $exclusions $verbose then log_action_end_msg $? else ********************************************************************************************************** Earlier testing with extra information output to console and various log files: diff --git a/executenl.c b/executenl.c index 823963a..f5dafb9 100644 --- a/executenl.c +++ b/executenl.c @@ -248,11 +248,29 @@ int iface_query(interface_defn *iface) { return 0; } int execute(char *command, interface_defn *ifd, execfn *exec) { - char *out; + char *out, *tmpstr; int ret; out = parse(command, ifd); if (!out) { return 0; } + printf("out = %s\n", out);//dbug + if (dhclient_nw == 1) { + if (!(strncmp(out, "dhclient ", (size_t) 9))) { + tmpstr = (char *) malloc((strlen (out)) + (size_t) 5); + if (tmpstr == NULL) { + perror("malloc -nw, out of memory"); + exit(EXIT_FAILURE); + } + memcpy(tmpstr, out, (size_t) 9); + memcpy(&tmpstr[9], "-nw ", (size_t) 4); + strcpy(&tmpstr[13], &out[9]); /* adds /0 */ + ret = (*exec)(tmpstr); + printf("tmpstr = %s\n", tmpstr);//dbug + free(tmpstr); + free(out); + return ret; + } + } ret = (*exec)(out); 2 printf () calls in execute.c were included, as shown in the diff above. 2 envlogtest calls were included in the networking script, at the start and end of the start) case: envlogtest networking nw start starting envlogtest networking nw start ending envlogtest is a free open source C program I wrote, you can download it at my website www.cxperimental.weebly.com. The line number lines in the source code files can be removed by another C program you can download from www.cxperimental.weebly.com, noprefix: noprefix "prefix" /path/inputfile /path/outputfile (must not exist) executenl.c was execute.c with #line lines removed for legibility: $ noprefix "#line " execute.c executenl.c Wed May 28 13:17:21 2014 envlogtest networking nw start starting Real user ID = 0, real group ID = 0 Effective user ID = 0, effective group ID = 0 No supplementary groups were found CONSOLE=/dev/console HOME=/ init=/sbin/init runlevel=S INIT_VERSION=sysvinit-2.88 TERM=linux COLUMNS=175 BOOT_IMAGE=Linux PATH=/sbin:/bin:/usr/local/bin RUNLEVEL=S AUTOBOOT=YES PREVLEVEL=N SHELL=/bin/sh PWD=/ previous=N LINES=65 rootmnt=/root STDIN_FILENO = 0 : ttyname = /dev/console STDOUT_FILENO = 1 : ttyname = /dev/pts/2 STDERR_FILENO = 2 : ttyname = /dev/pts/2 FD 0 : FD_CLOEXEC not set FD 0 : O_RDONLY not set FD 0 : O_WRONLY not set FD 0 : O_RDWR set FD 0 : O_APPEND not set FD 0 : O_NONBLOCK not set FD 0 : O_ASYNC not set FD 0 : O_FSYNC not set FD 1 : FD_CLOEXEC not set FD 1 : O_RDONLY not set FD 1 : O_WRONLY not set FD 1 : O_RDWR set FD 1 : O_APPEND not set FD 1 : O_NONBLOCK not set FD 1 : O_ASYNC not set FD 1 : O_FSYNC not set FD 2 : FD_CLOEXEC not set FD 2 : O_RDONLY not set FD 2 : O_WRONLY not set FD 2 : O_RDWR set FD 2 : O_APPEND not set FD 2 : O_NONBLOCK not set FD 2 : O_ASYNC not set FD 2 : O_FSYNC not set Wed May 28 13:17:24 2014 envlogtest networking nw start ending Real user ID = 0, real group ID = 0 Effective user ID = 0, effective group ID = 0 No supplementary groups were found CONSOLE=/dev/console HOME=/ init=/sbin/init runlevel=S INIT_VERSION=sysvinit-2.88 TERM=linux COLUMNS=175 BOOT_IMAGE=Linux PATH=/sbin:/bin:/usr/local/bin RUNLEVEL=S AUTOBOOT=YES PREVLEVEL=N SHELL=/bin/sh PWD=/ previous=N LINES=65 rootmnt=/root STDIN_FILENO = 0 : ttyname = /dev/console STDOUT_FILENO = 1 : ttyname = /dev/pts/2 STDERR_FILENO = 2 : ttyname = /dev/pts/2 FD 0 : FD_CLOEXEC not set FD 0 : O_RDONLY not set FD 0 : O_WRONLY not set FD 0 : O_RDWR set FD 0 : O_APPEND not set FD 0 : O_NONBLOCK not set FD 0 : O_ASYNC not set FD 0 : O_FSYNC not set FD 1 : FD_CLOEXEC not set FD 1 : O_RDONLY not set FD 1 : O_WRONLY not set FD 1 : O_RDWR set FD 1 : O_APPEND not set FD 1 : O_NONBLOCK not set FD 1 : O_ASYNC not set FD 1 : O_FSYNC not set FD 2 : FD_CLOEXEC not set FD 2 : O_RDONLY not set FD 2 : O_WRONLY not set FD 2 : O_RDWR set FD 2 : O_APPEND not set FD 2 : O_NONBLOCK not set FD 2 : O_ASYNC not set FD 2 : O_FSYNC not set From bootlog (extract): Wed May 28 13:17:20 2014: [....] Mounting local filesystems...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0cdone. Wed May 28 13:17:20 2014: [....] Activating swapfile swap...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0cdone. Wed May 28 13:17:21 2014: [....] Cleaning up temporary files...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0c. Wed May 28 13:17:21 2014: [....] Setting kernel variables ...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0cdone. Wed May 28 13:17:21 2014: envlogtest networking nw start starting Wed May 28 13:17:21 2014: [....] Configuring network interfaces...out = ip link set dev lo up Wed May 28 13:17:21 2014: out = ip link set dev lo up Wed May 28 13:17:21 2014: out = Wed May 28 13:17:21 2014: out = dhclient -v -pf /run/dhclient.ra0.pid -lf /var/lib/dhcp/dhclient.ra0.leases ra0 Wed May 28 13:17:21 2014: tmpstr = dhclient -nw -v -pf /run/dhclient.ra0.pid -lf /var/lib/dhcp/dhclient.ra0.leases ra0 Wed May 28 13:17:23 2014: out = Wed May 28 13:17:23 2014: out = dhclient -v -pf /run/dhclient.ra0.pid -lf /var/lib/dhcp/dhclient.ra0.leases ra0 Wed May 28 13:17:23 2014: Internet Systems Consortium DHCP Client 4.2.2 Wed May 28 13:17:23 2014: Copyright 2004-2011 Internet Systems Consortium. Wed May 28 13:17:23 2014: All rights reserved. Wed May 28 13:17:23 2014: For info, please visit https://www.isc.org/software/dhcp/ Wed May 28 13:17:23 2014: Wed May 28 13:17:23 2014: Listening on LPF/ra0/00:1c:df:8d:fc:d8 Wed May 28 13:17:23 2014: Sending on LPF/ra0/00:1c:df:8d:fc:d8 Wed May 28 13:17:23 2014: Sending on Socket/fallback Wed May 28 13:17:23 2014: DHCPDISCOVER on ra0 to 255.255.255.255 port 67 interval 7 Wed May 28 13:17:23 2014: tmpstr = dhclient -nw -v -pf /run/dhclient.ra0.pid -lf /var/lib/dhcp/dhclient.ra0.leases ra0 Wed May 28 13:17:23 2014: ^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0cdone. Wed May 28 13:17:24 2014: envlogtest networking nw start ending Wed May 28 13:17:24 2014: [....] Starting rpcbind daemon...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0c. Wed May 28 13:17:24 2014: [....] Starting NFS common utilities: statd idmapd^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0c. Wed May 28 13:17:24 2014: [....] Cleaning up temporary files...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0c. Wed May 28 13:17:25 2014: [^[[36minfo^[[39;49m] Setting console screen modes. Wed May 28 13:17:25 2014: ^[[9;30]^[[14;30][^[[36minfo^[[39;49m] Skipping font and keymap setup (handled by console-setup). Wed May 28 13:17:25 2014: [....] Setting up console font and keymap...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0cdone. Wed May 28 13:17:25 2014: [....] Reading later boot files...^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0c. Wed May 28 13:17:25 2014: [....] Setting up X socket directories... /tmp/.X11-unix /tmp/.ICE-unix^[[?25l^[[?1c^[7^[[1G[^[[32m ok ^[[39;49m^[8^[[?25h^[[?0c. Wed May 28 13:17:25 2014: INIT: Entering runlevel: 2 Wed May 28 13:17:25 2014: [^[[36minfo^[[39;49m] Using makefile-style concurrent boot in runlevel 2. Notice in envlogtest logging, stdin / out / err are not redirected to /dev/null at this point, and it takes about 3 seconds for the networking script to complete, which it does within runlevel S. dhclient is writing to the console, which is recorded in bootlog - it is logging escape codes instead of printing ok in green if that looks odd, by the way. If dhclient ran normally it would block here and delay the boot for a minute while it did it's DHCPDISCOVER routine, as it does if you try ifup wlan0 or whatever in a terminal, when it cannot find a connection. But because it has the -nw (no wait) option it goes straight to daemon mode and takes no appreciable time to print out the first part of it's output. The rest of the time is used by other elements of the networking ifup call. dhclient does not establish the wireless connection with the wireless AP, wpa_supplicant does that, so the network is up, but dhclient has not completed the connection to the internet based server. It can take a long while to do this anyway - especially if the internet AP is turned off. After a minute dhclient times out and becomes a daemon regardless of whether it has made a connection or not. Also I suggest removing the assert's to make the binary smaller, these serve no function. $ ls -l /sbin/ifup.old -rwxr-xr-x 1 root root 48028 Apr 12 2013 /sbin/ifup.old $ sudo strip /sbin/ifup $ ls -l /sbin/ifup -rwxr-xr-x 3 root root 48388 Jul 16 21:52 /sbin/ifup This is with the -d option added, the binary is a little larger as expected. $ ls -l /sbin/ifup -rwxr-xr-x 3 root root 45508 Jul 16 22:09 /sbin/ifup This is with the -d option added and the asserts removed - smaller than it was originally now and hence more efficient. diff --git a/config.c b/config.c index fd042a8..245895c 100644 --- a/config.c +++ b/config.c @@ -4,7 +4,6 @@ #include <stdio.h> #include <string.h> #include <errno.h> -#include <assert.h> #line 1205 "ifupdown.nw" #include "header.h" #line 1549 "ifupdown.nw" @@ -580,7 +579,6 @@ if (pos != 0 && (*result)[pos-1] == '\n') { #line 1616 "ifupdown.nw" (*line)++; -assert( (*result)[pos] == '\0' ); #line 1572 "ifupdown.nw" #line 1687 "ifupdown.nw" @@ -645,7 +643,6 @@ if (pos != 0 && (*result)[pos-1] == '\n') { #line 1616 "ifupdown.nw" (*line)++; -assert( (*result)[pos] == '\0' ); #line 1578 "ifupdown.nw" } diff --git a/execute.c b/execute.c index a3987bf..580f23a 100644 --- a/execute.c +++ b/execute.c @@ -3,7 +3,6 @@ #include <ctype.h> #include <stdlib.h> #include <string.h> -#include <assert.h> #include "header.h" #line 3057 "ifupdown.nw" @@ -162,7 +161,6 @@ if (!result) { } #line 2642 "ifupdown.nw" int doit(char *str) { - assert(str); if (verbose || no_act) { fprintf(stderr, "%s\n", str); @@ -466,8 +464,6 @@ return result; } #line 2935 "ifupdown.nw" void addstr(char **buf, size_t *len, size_t *pos, char *str, size_t strlen) { - assert(*len >= *pos); - assert(*len == 0 || (*buf)[*pos] == '\0'); if (*pos + strlen >= *len) { char *newbuf; diff --git a/main.c b/main.c index ba94dac..6659c03 100644 --- a/main.c +++ b/main.c @@ -5,7 +5,6 @@ #include <string.h> #include <ctype.h> #include <errno.h> -#include <assert.h> #include "header.h" #line 3472 "ifupdown.nw" @@ -794,7 +793,6 @@ iface[sizeof(iface)-1] = '\0'; #line 4642 "ifupdown.nw" ) { - assert(0); } } #line 3949 "ifupdown.nw" @@ -921,7 +919,6 @@ run_mapping(iface, liface, sizeof(liface), currmap); #line 4668 "ifupdown.nw" ) { - assert(0); } } @@ -1228,7 +1225,6 @@ return 1; #line 4668 "ifupdown.nw" ) { - assert(0); } } #line 4099 "ifupdown.nw"