From 1b659c8ebebd86be51095ab905293889a306ff01 Mon Sep 17 00:00:00 2001 From: Jesse Smith Date: Sat, 27 Oct 2018 20:26:15 -0300 Subject: [PATCH] Applied patch from Daniel Povey which should allow killall5/pidof to avoid locking up if it encounters stopped or zombie processes due to broken NFS mount points. This should allow Debian bug #719273 to be closed. --- doc/Changelog | 4 ++++ man/init.8 | 4 ++-- src/init.c | 2 +- src/killall5.c | 22 ++++++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 1f52161..98a6772 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -17,6 +17,10 @@ sysvinit (2.92) unreleased; urgency=low flag may not properly shut down network interfaces if the interface does not have an IP address. Addresses Debian bug #361935. + * Applied patch from Daniel Povey which should allow killall5/pidof to + avoid locking up if it encounters stopped or zombie processes + due to broken NFS mount points. + This should allow Debian bug #719273 to be closed. sysvinit (2.91) world; urgency=low diff --git a/man/init.8 b/man/init.8 index 5514e82..1f7c426 100644 --- a/man/init.8 +++ b/man/init.8 @@ -153,7 +153,7 @@ about this. .PP When \fBinit\fP is requested to change the runlevel, it sends the warning signal \s-1\fBSIGTERM\fP\s0 to all processes that are undefined -in the new runlevel. It then waits 5 seconds before forcibly +in the new runlevel. It then waits 3 seconds before forcibly terminating these processes via the \s-1\fBSIGKILL\fP\s0 signal. Note that \fBinit\fP assumes that all these processes (and their descendants) remain in the same process group which \fBinit\fP @@ -178,7 +178,7 @@ tell \fBinit\fP to re-examine the \fB/etc/inittab\fP file. tell \fBinit\fP to switch to single user mode. .IP "\fBU\fP or \fBu\fP" tell \fBinit\fP to re-execute itself (preserving the state). No re-examining of -\fB/etc/inittab\fP file happens. Run level should be one of +\fB/etc/inittab\fP file happens. Runlevel should be one of \fBSs0123456\fP otherwise request would be silently ignored. .PP diff --git a/src/init.c b/src/init.c index 1db45b7..3834ac5 100644 --- a/src/init.c +++ b/src/init.c @@ -2224,7 +2224,7 @@ void re_exec(void) /* * We shouldn't be here, something failed. - * Bitch, close the state pipe, unblock signals and return. + * Close the state pipe, unblock signals and return. */ init_freeenv(env); close(fd); diff --git a/src/killall5.c b/src/killall5.c index 5d81c09..e8a0ccb 100644 --- a/src/killall5.c +++ b/src/killall5.c @@ -484,6 +484,7 @@ int readproc(int do_stat) unsigned long startcode, endcode; int pid, f; ssize_t len; + char process_status[11]; /* Open the /proc directory. */ if (chdir("/proc") == -1) { @@ -567,11 +568,20 @@ int readproc(int do_stat) /* Get session, startcode, endcode. */ startcode = endcode = 0; + /* if (sscanf(q, "%*c %*d %*d %d %*d %*d %*u %*u " "%*u %*u %*u %*u %*u %*d %*d " "%*d %*d %*d %*d %*u %*u %*d " "%*u %lu %lu", &p->sid, &startcode, &endcode) != 3) { + */ + if (sscanf(q, "%10s %*d %*d %d %*d %*d %*u %*u " + "%*u %*u %*u %*u %*u %*d %*d " + "%*d %*d %*d %*d %*u %*u %*d " + "%*u %lu %lu", + process_status, + &p->sid, &startcode, &endcode) != 4) { + p->sid = 0; nsyslog(LOG_ERR, "can't read sid from %s\n", path); @@ -586,6 +596,18 @@ int readproc(int do_stat) if (startcode == 0 && endcode == 0) p->kernel = 1; fclose(fp); + if ( (strchr(process_status, 'D') != NULL) || + (strchr(process_status, 'Z') != NULL) ){ + /* Ignore zombie processes or processes in + disk sleep, as attempts + to access the stats of these will + sometimes fail. */ + if (p->argv0) free(p->argv0); + if (p->argv1) free(p->argv1); + if (p->statname) free(p->statname); + free(p); + continue; + } } else { /* Process disappeared.. */ if (p->argv0) free(p->argv0);