Use millisecond delays in init so that shutdown

can happen without a near-full-second delay after
all processes have terminated. Replaced do_sleep()
with do_msleep(), provided by Serge Belyshev.

Replaced hardwired sleep constants in init.c with
defined constants for easy updating in the future.
This commit is contained in:
Jesse Smith 2019-04-20 18:54:46 -03:00
parent 647ec365c6
commit cc464b1189
2 changed files with 27 additions and 17 deletions

View File

@ -11,6 +11,12 @@ sysvinit (2.95) unreleased; urgency=low
Patch supplied by KatolaZ. Patch supplied by KatolaZ.
* Updated manual page to describe -h and its modifiers (-H and -P) * Updated manual page to describe -h and its modifiers (-H and -P)
in more detail. Should close Debian bug #374039. in more detail. Should close Debian bug #374039.
* Use millisecond delays in init so that shutdown
can happen without a near-full-second delay after
all processes have terminated. Replaced do_sleep()
with do_msleep(), provided by Serge Belyshev.
* Replaced hardwired sleep constants in init.c with
defined constants for easy updating in the future.
sysvinit (2.94) released; urgency=low sysvinit (2.94) released; urgency=low

View File

@ -227,20 +227,23 @@ struct {
#define NR_EXTRA_ENV 16 #define NR_EXTRA_ENV 16
char *extra_env[NR_EXTRA_ENV]; char *extra_env[NR_EXTRA_ENV];
#define MINI_SLEEP 10 /* ten milliseconds */
#define SHORT_SLEEP 5000 /* five seconds */
#define LONG_SLEEP 30000 /* 30 seconds sleep to deal with memory issues*/
/* /*
* Sleep a number of seconds. * Sleep a number of milliseconds.
* *
* This only works correctly because the linux select updates * This only works correctly because Linux select updates
* the elapsed time in the struct timeval passed to select! * the elapsed time in the struct timeval passed to select!
*/ */
static static
void do_sleep(int sec) void do_msleep(int msec)
{ {
struct timeval tv; struct timeval tv;
tv.tv_sec = sec; tv.tv_sec = msec / 1000;
tv.tv_usec = 0; tv.tv_usec = (msec % 1000) * 1000;
while(select(0, NULL, NULL, NULL, &tv) < 0 && errno == EINTR) while(select(0, NULL, NULL, NULL, &tv) < 0 && errno == EINTR)
; ;
@ -257,7 +260,7 @@ void *imalloc(size_t size)
while ((m = malloc(size)) == NULL) { while ((m = malloc(size)) == NULL) {
initlog(L_VB, "out of memory"); initlog(L_VB, "out of memory");
do_sleep(5); do_msleep(SHORT_SLEEP);
} }
memset(m, 0, size); memset(m, 0, size);
return m; return m;
@ -723,7 +726,7 @@ void coredump(void)
sigdelset(&mask, SIGSEGV); sigdelset(&mask, SIGSEGV);
sigprocmask(SIG_SETMASK, &mask, NULL); sigprocmask(SIG_SETMASK, &mask, NULL);
do_sleep(5); do_msleep(SHORT_SLEEP);
exit(0); exit(0);
} }
@ -743,13 +746,13 @@ void segv_handler(int sig, struct sigcontext ctx)
char *p = ""; char *p = "";
int saved_errno = errno; int saved_errno = errno;
if ((void *)ctx.eip >= (void *)do_sleep && if ((void *)ctx.eip >= (void *)do_msleep &&
(void *)ctx.eip < (void *)main) (void *)ctx.eip < (void *)main)
p = " (code)"; p = " (code)";
initlog(L_VB, "PANIC: segmentation violation at %p%s! " initlog(L_VB, "PANIC: segmentation violation at %p%s! "
"sleeping for 30 seconds.", (void *)ctx.eip, p); "sleeping for 30 seconds.", (void *)ctx.eip, p);
coredump(); coredump();
do_sleep(30); do_msleep(LONG_SLEEP);
errno = saved_errno; errno = saved_errno;
} }
#else #else
@ -764,7 +767,7 @@ void segv_handler(int sig)
initlog(L_VB, initlog(L_VB,
"PANIC: segmentation violation! sleeping for 30 seconds."); "PANIC: segmentation violation! sleeping for 30 seconds.");
coredump(); coredump();
do_sleep(30); do_msleep(LONG_SLEEP);
errno = saved_errno; errno = saved_errno;
} }
#endif #endif
@ -978,7 +981,7 @@ char **init_buildenv(int child)
while ((e = (char**)calloc(n, sizeof(char *))) == NULL) { while ((e = (char**)calloc(n, sizeof(char *))) == NULL) {
initlog(L_VB, "out of memory"); initlog(L_VB, "out of memory");
do_sleep(5); do_msleep(SHORT_SLEEP);
} }
for (n = 0; environ[n]; n++) for (n = 0; environ[n]; n++)
@ -1304,7 +1307,7 @@ pid_t spawn(CHILD *ch, int *res)
if (pid == -1) { if (pid == -1) {
initlog(L_VB, "cannot fork, retry.."); initlog(L_VB, "cannot fork, retry..");
do_sleep(5); do_msleep(SHORT_SLEEP);
continue; continue;
} }
return(pid); return(pid);
@ -1712,13 +1715,14 @@ 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) { 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.
* The f < 100 * sleep_time refers to sleep time in 10 millisecond chunks.
*/ */
for(f = 0; f < sleep_time; f++) { for(f = 0; f < 100 * sleep_time; f++) {
for(ch = family; ch; ch = ch->next) { for(ch = family; ch; ch = ch->next) {
if (!(ch->flags & KILLME)) continue; if (!(ch->flags & KILLME)) continue;
if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE)) if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
@ -1732,7 +1736,7 @@ void read_inittab(void)
foundOne = 0; /* Skip the sleep below. */ foundOne = 0; /* Skip the sleep below. */
break; break;
} }
do_sleep(1); do_msleep(MINI_SLEEP);
} }
} }
} }
@ -1740,7 +1744,7 @@ void read_inittab(void)
/* /*
* Now give all processes the chance to die and collect exit statuses. * Now give all processes the chance to die and collect exit statuses.
*/ */
if (foundOne) do_sleep(1); if (foundOne) do_msleep(MINI_SLEEP);
for(ch = family; ch; ch = ch->next) for(ch = family; ch; ch = ch->next)
if (ch->flags & KILLME) { if (ch->flags & KILLME) {
if (!(ch->flags & ZOMBIE)) if (!(ch->flags & ZOMBIE))