14 March 1999 Hi, This is a patch for dhcpcd-1.3.16 that prevents it from hanging the Linux PCMCIA "cardmgr" when cardmgr uses it to bring up a new network interface. I am using v3.0.9 of the Linux PCMCIA package on a Toshiba Libretto 70 running RedHat 5.2, plus linux kernel 2.2.3, and the half-a-dozen or so packages that RedHat released to make RH 5.2 work under Linux 2.2.3. Those RedHat upgrades include dhcpcd v1.3.16. (As an aside -- the old dhcpcd, version 0.70, no longer works under Linux 2.1/2.2 because those kernels do not allow network interfaces bound to 0.0.0.0). I noticed that cardmgr was hanging every time I inserted a network card that was using DHCP to get an IP address. When I say "hanging", I mean cardmgr was unresponsive to all future events -- both a removal of the card that caused the hang, and insertions of other cards in the same slot or other slots. Finally, I tracked this down to the following: 1- cardmgr uses popen() to run the card's initialization script, such as "network start eth0". It does this so it can read the output of the script and copy it to the syslog. 2- cardmgr keeps reading from the pipe until it receives an EOF on it. In other words, cardmgr keeps reading the output of the "network" script, and does not respond to any other card events, until the pipe closes. 3- For interfaces that use DHCP to get an IP address, the "network" script launches dhcpcd. dhcpcd forks and turns itself into a daemon that runs forever, so it can renew your IP lease. The dhcpcd inherits the pipe that network has open to cardmgr. 4- dhcpcd never closes its standard output, so cardmgr never sees an EOF on its pipe. Even though the "network" script itself terminates, the forked dhcpcd still has an open pipe to cardmgr. Since cardmgr never sees EOF, it hangs -- blocked forever waiting for output from a process that will never generate any. You can unhang it by killing dhcpcd manually, but this is annoying. The patch below is a simple fix to dhcpcd that has dhcpcd close stdin, stdout, and stderr after it forks. The patch works in the simple case where dhcpcd succeeds in getting your IP address, forks off a daemon, and then exits. But if you can't see a DHCP server, dhcpcd never forks and the cardmgr will hang until dhcpcd times out and dies. This solution isn't perfect - my next project is to patch cardmgr so that it forks every time it needs to run a script, so that it doesn't let a hung script block it from providing service to other sockets. The patch is against dhcpcd 1.3.16; or, if you don't want to compile it (and trust me to compile a safe root-run binary for you), I put an i386 binary on my ftp site at ftp://ftp.circlemud.org/pub/jelson/dhcpcd. Regards, Jeremy diff -u dhcpcd-1.3.16/dhcpcd.c dhcpcd-1.3.16-patched/dhcpcd.c --- dhcpcd-1.3.16/dhcpcd.c Sat Nov 7 18:07:43 1998 +++ dhcpcd-1.3.16-patched/dhcpcd.c Sun Mar 14 21:41:24 1999 @@ -178,6 +178,13 @@ #ifndef DEBUG if ( fork() ) exit(0); /* got into bound state. */ #endif + /* patched by Jeremy Elson 14 Mar 1999 - + * close stdin, stdout, and stderr so that programs such as the PCMCIA + * cardmgr who are running us with a pipe don't read from the daemon + */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); chdir("/"); writePidFile(); do currState=(int (*)())currState(); while ( currState );