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:
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);
}