initlog does a dup of fd 0 (usually getting 10) before fork(). the parent closes it, but the child does not. Most daemon programs close 0,1,2 but do not know to close 10. E.g. consider this extract of strace output.... 870 execve("/sbin/initlog", ["initlog", "-c", "/usr/sbin/snmpd"], [/* 10 vars */]) = 0 870 brk(0) = 0x804e2ac 870 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) 870 open("/etc/ld.so.cache", O_RDONLY) = 4 870 fstat(4, {st_mode=0, st_size=0, ...}) = 0 870 mmap(0, 21944, PROT_READ, MAP_PRIVATE, 4, 0) = 0x40014000 870 close(4) = 0 870 open("/lib/libc.so.6", O_RDONLY) = 4 870 fstat(4, {st_mode=0, st_size=0, ...}) = 0 870 read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096) = 4096 870 mmap(0, 974392, PROT_READ|PROT_EXEC, MAP_PRIVATE, 4, 0) = 0x4001a000 870 mprotect(0x40100000, 32312, PROT_NONE) = 0 870 mmap(0x40100000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 4, 0xe5000) = 0x40100000 870 mmap(0x40105000, 11832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40105000 870 close(4) = 0 870 munmap(0x40014000, 21944) = 0 870 personality(PER_LINUX) = 0 870 getpid() = 870 870 brk(0) = 0x804e2ac 870 brk(0x804e2e4) = 0x804e2e4 870 brk(0x804f000) = 0x804f000 870 pipe([4, 5]) = 0 870 pipe([6, 7]) = 0 870 pipe([8, 9]) = 0 870 dup(0) = 10 870 fork() = 871 870 close(10) = 0 870 close(5) = 0 870 close(7) = 0 870 close(9) = 0 870 pipe([5, 7]) = 0 870 SYS_168(0x804ed20, 0x2, 0x1f4, 0x1f4, 0x804ed20 <unfinished ...> 871 dup2(5, 1) = 1 871 dup2(7, 2) = 2 871 dup2(9, 21) = 21 871 close(5) = 0 871 close(7) = 0 871 close(9) = 0 871 close(4) = 0 871 close(6) = 0 871 execve("/usr/sbin/snmpd", ["/usr/sbin/snmpd"], [/* 10 vars */]) = 0 This leads to many daemons having a reference to the stdin of the starting session. (you can see this with lsof) If the stdin was a real terminal then there is no problem because the /dev/tty.. entry continues to exist after the user logs out. But, if the stdin is a socket (due to use of rsh) then the rsh does not terminate (the init.d/xxx appears to never terminate). If the user drops the connection then the daemon gets killed! initlog should not do this dup(). This problem can be worked around by editing init.d/functions andputting a </dev/null on line 78 before the &&.
fixed in initscripts-4.44-1.
This behavior is different but not fixed in 4.48-1. The daemon still ends up with a reference to the socket, and the rsh is still blocked. E.g.: bash# rsh revs lsof -p20451 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME nfsd 20451 root cwd DIR 3,3 4096 2 / nfsd 20451 root rtd DIR 3,3 4096 2 / nfsd 20451 root 0u sock 0,0 166838 can't identify protocol nfsd 20451 root 1w FIFO 0,0 166867 pipe nfsd 20451 root 2w FIFO 0,0 166868 pipe nfsd 20451 root 3w REG 3,3 255731 59079 /tmp/wibble nfsd 20451 root 4r REG 3,3 557 15175 /etc/initlog.conf nfsd 20451 root 9r FIFO 0,0 166869 pipe nfsd 20451 root 21w FIFO 0,0 166869 pipe [1]+ Stopped (tty input) rsh revs strace -f -o /tmp/wibble /etc/rc.d/init.d/nfs start bash# Indeed, the strace shows that initlog now does a close(1073817264) getting EBADF arounf about the point where it would be expected to close(0) Please can this be reopened and fixed.
A slightly related bug is that the child daemon inherits a descriptor to /etc/initlog.conf. This diff fixes that: --- initscripts-4.48/src/initlog.c.close Thu Jan 20 16:58:01 2000 +++ initscripts-4.48/src/initlog.c Thu Jan 20 16:59:43 2000 @@ -42,9 +42,9 @@ int lfac=-1,lpri=-1; if ((fd=open(fname,O_RDONLY))==-1) return; - if (fstat(fd,&sbuf)) return; + if (fstat(fd,&sbuf)) goto clout; data=malloc(sbuf.st_size+1); - if (read(fd,data,sbuf.st_size)!=sbuf.st_size) return; + if (read(fd,data,sbuf.st_size)!=sbuf.st_size) goto clout; data[sbuf.st_size] = '\0'; while ((line=getLine(&data))) { if (line[0]=='#') continue; @@ -88,6 +88,9 @@ } if (lfac!=-1) logfacility=lfac; if (lpri!=-1) logpriority=lpri; + +clout: + close(fd); } char *getLine(char **data) {
Second one is fixed since 4.65 or so. First one is being worked on.
The first bug also seems to be fixed as of initscripts-4.5x or so, and I can't reproduce it in initscripts-latest.