runit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 6e753ec41e1232c17546f7e9e5eb6327f324ddd0
parent 7f81457f6d0aa561993f0f365cda0051645da4fd
Author: Gerrit Pape <pape@smarden.org>
Date:   Thu, 22 Nov 2001 17:42:01 +0000

  * collects all terminated children in all stages
  * sends sigkill to whole process group if stage2 crashes and waits
    5 seconds before restarting
  * ctraltdel not automatically shuts down, now respects /etc/runit/stopit
  * /etc/runit/ctrlaltdel touches /etc/runit/stopit
  * on shutdown request: send sigterm to stage 2, wait max 5 second, send
    sigkill if still running, leave stage 2, enter stage 3

Diffstat:
MMakefile | 2+-
Mdebian/postinst | 2+-
Mdebian/rules | 44++++++++++++++++++++++----------------------
Mdoc/install.html | 10+++++-----
Mdoc/replaceinit.html | 2+-
Metc/debian/ctrlaltdel | 9++++++---
Mman/runit.8 | 26+++++++++++++-------------
Mpackage/CHANGES | 10++++++++++
Mpackage/upgrade | 4++--
Msrc/runit.c | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
10 files changed, 146 insertions(+), 90 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ DESTDIR= -PACKAGE=runit-0.1.1 +PACKAGE=runit-0.1.2 DIRS=doc man etc package src MANPAGES=man/runit.8 man/runit-init.8 man/runit-halt.8 man/runit-reboot.8 DAEMONTOOLS_PD=daemontools-pd-0.76 diff --git a/debian/postinst b/debian/postinst @@ -25,7 +25,7 @@ set -e case "$1" in configure) ( \ - cd /package/admin/runit-0.1.1 + cd /package/admin/runit-0.1.2 package/upgrade ) ;; diff --git a/debian/rules b/debian/rules @@ -24,18 +24,18 @@ build-stamp: # $(MAKE) #/usr/bin/docbook-to-man debian/runit.sgml > runit.1 - tar xfzvp runit-0.1.1.tar.gz - mkdir -p admin/runit-0.1.1/compile + tar xfzvp runit-0.1.2.tar.gz + mkdir -p admin/runit-0.1.2/compile tar xfzvp daemontools-pd-0.76.tar.gz \ - -C admin/runit-0.1.1/compile - ( cd admin/runit-0.1.1/compile ; \ + -C admin/runit-0.1.2/compile + ( cd admin/runit-0.1.2/compile ; \ ln -s daemontools-pd-0.76 support ) ( \ - cd admin/runit-0.1.1 ; \ + cd admin/runit-0.1.2 ; \ package/compile ; \ - echo "/package/admin/runit-0.1.1" > compile/home ; \ + echo "/package/admin/runit-0.1.2" > compile/home ; \ rm -f compile/src ; \ - ln -s /package/admin/runit-0.1.1/src compile/src ; \ + ln -s /package/admin/runit-0.1.2/src compile/src ; \ ) touch build-stamp @@ -62,40 +62,40 @@ install: build chmod 1755 debian/runit/package cp -a admin debian/runit/package/ - rm -rf debian/runit/package/admin/runit-0.1.1/compile - cp -a debian/runit/package/admin/runit-0.1.1/man . - rm -rf debian/runit/package/admin/runit-0.1.1/man - cp -a debian/runit/package/admin/runit-0.1.1/doc . - rm -rf debian/runit/package/admin/runit-0.1.1/doc - cp -a debian/runit/package/admin/runit-0.1.1/etc . - rm -rf debian/runit/package/admin/runit-0.1.1/etc - cp -a debian/runit/package/admin/runit-0.1.1/package . + rm -rf debian/runit/package/admin/runit-0.1.2/compile + cp -a debian/runit/package/admin/runit-0.1.2/man . + rm -rf debian/runit/package/admin/runit-0.1.2/man + cp -a debian/runit/package/admin/runit-0.1.2/doc . + rm -rf debian/runit/package/admin/runit-0.1.2/doc + cp -a debian/runit/package/admin/runit-0.1.2/etc . + rm -rf debian/runit/package/admin/runit-0.1.2/etc + cp -a debian/runit/package/admin/runit-0.1.2/package . # /etc/runit - cp -p admin/runit-0.1.1/etc/debian/[123] \ + cp -p admin/runit-0.1.2/etc/debian/[123] \ debian/runit/etc/runit/ - cp -p admin/runit-0.1.1/etc/debian/ctrlaltdel \ + cp -p admin/runit-0.1.2/etc/debian/ctrlaltdel \ debian/runit/etc/runit/ - cp -p admin/runit-0.1.1/etc/debian/getty-tty5/run \ + cp -p admin/runit-0.1.2/etc/debian/getty-tty5/run \ debian/runit/etc/runit/getty-tty5 # runit programs - cp -p debian/runit/package/admin/runit-0.1.1/command/runit* \ + cp -p debian/runit/package/admin/runit-0.1.2/command/runit* \ debian/runit/sbin/ # cleanup - rm -rf debian/runit/package/admin/runit-0.1.1/compile + rm -rf debian/runit/package/admin/runit-0.1.2/compile # create debian/links rm -f debian/links for i in \ - `cat debian/runit/package/admin/runit-0.1.1/package/commands` ; \ + `cat debian/runit/package/admin/runit-0.1.2/package/commands` ; \ do \ echo "/package/admin/runit/command/$$i /command/$$i" \ >> debian/links ; \ done # for i in \ -# `cat debian/runit/package/admin/runit-0.1.1/package/commands` ; \ +# `cat debian/runit/package/admin/runit-0.1.2/package/commands` ; \ # do \ # echo "/command/$$i /usr/local/bin/$$i" \ # >> debian/links ; \ diff --git a/doc/install.html b/doc/install.html @@ -13,14 +13,14 @@ Check that you have the recent version of <a href="http://cr.yp.to/daemontools.html">daemontools</a> installed. <p> Download -<a href="runit-0.1.1.tar.gz">runit-0.1.1.tar.gz</a> into <tt>/package</tt> +<a href="runit-0.1.2.tar.gz">runit-0.1.2.tar.gz</a> into <tt>/package</tt> and unpack the archive <pre> # cd /package - # gunzip runit-0.1.1.tar - # tar -xpf runit-0.1.1.tar - # rm runit-0.1.1.tar - # cd admin/runit-0.1.1 + # gunzip runit-0.1.2.tar + # tar -xpf runit-0.1.2.tar + # rm runit-0.1.2.tar + # cd admin/runit-0.1.2 </pre> Compile and install the <i>runit</i> programs <pre> diff --git a/doc/replaceinit.html b/doc/replaceinit.html @@ -102,7 +102,7 @@ default Unix process no 1 <i>runit</i>. </pre> To report success: <pre> - # ( uname -a ; cat /etc/runit/[123] ) | mail pape-runit-0.1.1@smarden.org + # ( uname -a ; cat /etc/runit/[123] ) | mail pape-runit-0.1.2@smarden.org </pre> <hr> <address><a href="mailto:pape@smarden.org"> diff --git a/etc/debian/ctrlaltdel b/etc/debian/ctrlaltdel @@ -1,4 +1,7 @@ #!/bin/sh -MSG="System is going down in 10 seconds..." -/bin/echo "$MSG" | /usr/bin/wall -/bin/sleep 10 +MSG="System is going down in 14 seconds..." + +#echo 'disabled.' ; exit +/bin/touch /etc/runit/stopit && \ + /bin/echo "$MSG" | /usr/bin/wall +/bin/sleep 14 diff --git a/man/runit.8 b/man/runit.8 @@ -6,7 +6,7 @@ runit \- the UNIX process no 1 .SH DESCRIPTION .B runit must be run as Unix process no 1. It performs the system's -booting, running and shutdown in three stages: +booting, running, and shutdown in three Stages: .SH STAGE 1 .B runit runs @@ -16,19 +16,25 @@ and waits for it to terminate. The system's one time tasks are done here. .B runit runs .IR /etc/runit/2 , -which should not return until system shutdown. Normally +which should not return until system shutdown; if it crashes, it will be +restarted. Normally .I /etc/runit/2 starts .BR svscanboot (8). .B runit -is able to handle the ctrl-alt-del keyboard request in stage 2, see below. +is able to handle the ctrl-alt-del keyboard request in Stage 2, see below. .SH STAGE 3 If .B runit -is told to halt or reboot the system, or the Stage 2 -returns without errors, it terminates Stage 2 if it is running and runs +is told to shutdown the system, or the Stage 2 returns without errors, it +terminates Stage 2 if it is running, and runs .IR /etc/runit/3 . The systems tasks to shutdown and halt or reboot are done here. +Normally in Stage 3 +.I /etc/runit/3 +checks for the file +.IR /etc/runit/reboot . +If it exists, the system is rebooted, it is halted otherwise. .SH CTRL-ALT-DEL If .B runit @@ -38,10 +44,10 @@ exists, .B runit runs .IR /etc/runit/ctrlaltdel , -waits for it to terminate and then enters stage 3 for system shutdown. +waits for it to terminate and then enters Stage 3 for system shutdown. .SH SIGNALS .B runit -only accepts signals in stage 2. +only accepts signals in Stage 2. .P If .B runit @@ -50,12 +56,6 @@ receives a CONT signal and the file exists, .B runit is told to shutdown the system. -.P -Normally in stage 3 -.I /etc/runit/3 -checks for the file -.IR /etc/runit/reboot . -If it exists, the system is rebooted, it is halted otherwise. .SH SEE ALSO init(8), runit-halt(8), diff --git a/package/CHANGES b/package/CHANGES @@ -1,3 +1,13 @@ +runit 0.1.2 +Thu, 22 Nov 2001 18:29:05 +0100 + * collects all terminated children in all stages + * sends sigkill to whole process group if stage2 crashes and waits + 5 seconds before restarting + * ctraltdel not automatically shuts down, now respects /etc/runit/stopit + * /etc/runit/ctrlaltdel touches /etc/runit/stopit + * on shutdown request: send sigterm to stage 2, wait max 5 second, send + sigkill if still running, leave stage 2, enter stage 3 + runit 0.1.1 Tue, 20 Nov 2001 11:56:58 +0100 * package moved to smarden.org diff --git a/package/upgrade b/package/upgrade @@ -7,9 +7,9 @@ test -d src || ( echo 'Wrong working directory.'; exit 1 ) here=`env - PATH=$PATH pwd` parent=`dirname $here` -echo 'Creating symlink runit -> runit-0.1.1...' +echo 'Creating symlink runit -> runit-0.1.2...' rm -f runit -ln -s runit-0.1.1 runit +ln -s runit-0.1.2 runit mv -f runit .. echo 'Making command links in /command...' diff --git a/src/runit.c b/src/runit.c @@ -25,24 +25,24 @@ #define STOPIT "/etc/runit/stopit" #define CTRLALTDEL "/etc/runit/ctrlaltdel" -const char * const take[3] ={ +const char * const stage[3] ={ "/etc/runit/1", "/etc/runit/2", "/etc/runit/3" }; -const char *progname; + int selfpipe[2]; int sigc =0; int sigi =0; -void sig_cont_handler(void) { +void sig_cont_handler (void) { sigc++; write(selfpipe[1], "", 1); } -void sig_int_handler(void) { +void sig_int_handler (void) { sigi++; write(selfpipe[1], "", 1); } -void sig_child_handler(void) { +void sig_child_handler (void) { write(selfpipe[1], "", 1); } @@ -50,8 +50,7 @@ int main (int argc, const char * const *argv, const char * const *envp) { int pid, pid2; int wstat; int fd; - int i; - int stopit =0; + int st; iopause_fd x; char ch; @@ -81,12 +80,13 @@ int main (int argc, const char * const *argv, const char * const *envp) { /* activate ctrlaltdel handling */ reboot(0); - strerr_warn3(INFO, "$Id$", ": booting.", 0); + strerr_warn3(INFO, "$Id$", + ": booting.", 0); /* runit */ - for (i =0; i < 3; i++) { + for (st =0; st < 3; st++) { while ((pid =fork()) == -1) { - strerr_warn4(FATAL, "unable to fork for \"", take[i], "\" pausing: ", + strerr_warn4(FATAL, "unable to fork for \"", stage[st], "\" pausing: ", &strerr_sys); sleep(5); } @@ -94,7 +94,7 @@ int main (int argc, const char * const *argv, const char * const *envp) { /* child */ const char * prog[2]; - prog[0] =take[i]; + prog[0] =stage[st]; prog[1] =0; setsid(); @@ -110,15 +110,17 @@ int main (int argc, const char * const *argv, const char * const *envp) { sig_unblock(sig_pipe); sig_unblock(sig_term); - strerr_warn3(INFO, "enter stage: ", take[i], 0); + strerr_warn3(INFO, "enter stage: ", stage[st], 0); pathexec_run(*prog, (const char* const *) prog, envp); - strerr_warn3(FATAL, "could not start child: ", take[i], &strerr_sys); + strerr_warn3(FATAL, "could not start child: ", stage[st], &strerr_sys); } x.fd =selfpipe[0]; x.events =IOPAUSE_READ; for (;;) { + int child; + sig_unblock(sig_child); sig_unblock(sig_cont); sig_unblock(sig_int); @@ -126,45 +128,43 @@ int main (int argc, const char * const *argv, const char * const *envp) { sig_block(sig_cont); sig_block(sig_child); sig_block(sig_int); - - while (read(selfpipe[0], &ch, 1) == 1) {} - if (wait_nohang(&wstat) == pid) { - if (wait_crashed(wstat) && !stopit) { - strerr_warn3(WARNING, "child crashed: ", take[i], 0); - if (i == 1) { - kill(-pid, SIGTERM); - sleep(1); + read(selfpipe[0], &ch, 1); + + if ((child =wait_nohang(&wstat)) == pid) { + if (wait_crashed(wstat)) { + strerr_warn3(WARNING, "child crashed: ", stage[st], 0); + if (st == 1) { + /* this is stage 2 */ + strerr_warn2(WARNING, "killing all processes in stage 2...", 0); + kill(-pid, 9); + sleep(5); strerr_warn2(WARNING, "restarting.", 0); - i--; + st--; break; } } - if (stopit) stopit =0; - strerr_warn3(INFO, "leave stage: ", take[i], 0); + strerr_warn3(INFO, "leave stage: ", stage[st], 0); break; } - + if (child > 0) { + /* collect terminated children */ + write(selfpipe[1], "", 1); + continue; + } + /* sig */ - if ((sigc == 0) && (sigi == 0)) { + if (!sigc && !sigi) { #ifdef DEBUG strerr_warn2(WARNING, "poll: ", &strerr_sys); #endif continue; } - if ((i != 1) || stopit) { + if (st != 1) { strerr_warn2(WARNING, "sigs only work in stage 2.", 0); sigc =sigi =0; continue; } - if (sigc && ((fd =open_write(STOPIT)) != -1)) { - close(fd); - unlink(STOPIT); - kill(pid, SIGTERM); - sigc =sigi =0; - stopit =1; - continue; - } if (sigi && ((fd =open_write(CTRLALTDEL)) != -1)) { close(fd); strerr_warn2(INFO, "ctrl-alt-del request...", 0); @@ -191,18 +191,61 @@ int main (int argc, const char * const *argv, const char * const *envp) { if (wait_crashed(wstat)) { strerr_warn3(WARNING, "child crashed: ", CTRLALTDEL, 0); } - kill(pid, SIGTERM); - sigc =sigi =0; - stopit =1; - continue; + sigi =0; + sigc++; } - + if (sigc && ((fd =open_write(STOPIT)) != -1)) { + int i; + close(fd); + unlink(STOPIT); + + /* kill stage 2 */ +#ifdef DEBUG + strerr_warn2(WARNING, "sending sigterm...", 0); +#endif + kill(pid, sig_term); + i =0; + while (i < 5) { + if ((child =wait_nohang(&wstat)) == pid) { +#ifdef DEBUG + strerr_warn2(WARNING, "stage 2 terminated.", 0); +#endif + pid =0; + break; + } + if (child) continue; + if (child == -1) { + strerr_warn2(WARNING, "wait_nohang: ", &strerr_sys); + } +#ifdef DEBUG + strerr_warn2(WARNING, "waiting...", 0); +#endif + sleep(1); + i++; + } + if (pid) { + /* still there */ + strerr_warn2(WARNING, + "stage 2 not terminated, sending sigkill...", 0); + kill(pid, 9); + if (wait_pid(&wstat, pid) == -1) { + strerr_warn2(WARNING, "wait_pid: ", &strerr_sys); + } + } + sigc =0; + + /* enter stage 3 */ + break; + } + sigc =sigi =0; + #ifdef DEBUG strerr_warn2(WARNING, "no request.", 0); #endif } } + /* not reached */ - strerr_warn2(INFO, "exit.", 0); - exit(0); + strerr_die2x(0, INFO, "exit."); + return(0); }