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"

Reply via email to