Due to do_sleep one second granularity, children killing logic always causes one second delay at shutdown, even if all processes successfully terminate long before that.
Fixed thus by replacing do_sleep with do_msleep and waiting for children to terminate every 10 ms. --- src/init.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/init.c b/src/init.c index 4369beb..3b4b4af 100644 --- a/src/init.c +++ b/src/init.c @@ -229,18 +229,18 @@ char *extra_env[NR_EXTRA_ENV]; /* - * Sleep a number of seconds. + * Sleep a number of milliseconds. * * This only works correctly because the linux select updates * the elapsed time in the struct timeval passed to select! */ static -void do_sleep(int sec) +void do_msleep(int msec) { struct timeval tv; - tv.tv_sec = sec; - tv.tv_usec = 0; + tv.tv_sec = msec / 1000; + tv.tv_usec = (msec % 1000) * 1000; while(select(0, NULL, NULL, NULL, &tv) < 0 && errno == EINTR) ; @@ -257,7 +257,7 @@ void *imalloc(size_t size) while ((m = malloc(size)) == NULL) { initlog(L_VB, "out of memory"); - do_sleep(5); + do_msleep(5000); } memset(m, 0, size); return m; @@ -723,7 +723,7 @@ void coredump(void) sigdelset(&mask, SIGSEGV); sigprocmask(SIG_SETMASK, &mask, NULL); - do_sleep(5); + do_msleep(5000); exit(0); } @@ -749,7 +749,7 @@ void segv_handler(int sig, struct sigcontext ctx) initlog(L_VB, "PANIC: segmentation violation at %p%s! " "sleeping for 30 seconds.", (void *)ctx.eip, p); coredump(); - do_sleep(30); + do_msleep(30000); errno = saved_errno; } #else @@ -764,7 +764,7 @@ void segv_handler(int sig) initlog(L_VB, "PANIC: segmentation violation! sleeping for 30 seconds."); coredump(); - do_sleep(30); + do_msleep(30000); errno = saved_errno; } #endif @@ -978,7 +978,7 @@ char **init_buildenv(int child) while ((e = (char**)calloc(n, sizeof(char *))) == NULL) { initlog(L_VB, "out of memory"); - do_sleep(5); + do_msleep(5000); } for (n = 0; environ[n]; n++) @@ -1304,7 +1304,7 @@ pid_t spawn(CHILD *ch, int *res) if (pid == -1) { initlog(L_VB, "cannot fork, retry.."); - do_sleep(5); + do_msleep(5000); continue; } return(pid); @@ -1712,13 +1712,13 @@ void read_inittab(void) } /* - * See if we have to wait 5 seconds + * See if we have to wait sleep_time seconds */ if (foundOne && round == 0) { /* - * Yup, but check every second if we still have children. + * Yup, but check every 10 milliseconds if we still have children. */ - for(f = 0; f < sleep_time; f++) { + for(f = 0; f < 100 * sleep_time; f++) { for(ch = family; ch; ch = ch->next) { if (!(ch->flags & KILLME)) continue; if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE)) @@ -1732,7 +1732,7 @@ void read_inittab(void) foundOne = 0; /* Skip the sleep below. */ break; } - do_sleep(1); + do_msleep(10); } } } @@ -1740,7 +1740,7 @@ void read_inittab(void) /* * Now give all processes the chance to die and collect exit statuses. */ - if (foundOne) do_sleep(1); + if (foundOne) do_msleep(10); for(ch = family; ch; ch = ch->next) if (ch->flags & KILLME) { if (!(ch->flags & ZOMBIE)) -- 2.20.1