summary refs log tree commit diff
diff options
context:
space:
mode:
authorGerrit Pape <pape@smarden.org>2001-11-22 17:42:01 +0000
committerGerrit Pape <pape@smarden.org>2001-11-22 17:42:01 +0000
commitf7ccdd14a5c954c1c5f0aab084776c2a49586dc1 (patch)
tree14124814db7129cb8afc2b33641a23694d7ac710
parent54b64b3f09fde903a80fafb0244165e7623998e4 (diff)
downloadrunit-f7ccdd14a5c954c1c5f0aab084776c2a49586dc1.tar.gz
runit-f7ccdd14a5c954c1c5f0aab084776c2a49586dc1.tar.xz
runit-f7ccdd14a5c954c1c5f0aab084776c2a49586dc1.zip
* 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
-rw-r--r--Makefile2
-rw-r--r--debian/postinst2
-rwxr-xr-xdebian/rules44
-rw-r--r--doc/install.html10
-rw-r--r--doc/replaceinit.html2
-rwxr-xr-xetc/debian/ctrlaltdel9
-rw-r--r--man/runit.826
-rw-r--r--package/CHANGES10
-rwxr-xr-xpackage/upgrade4
-rw-r--r--src/runit.c127
10 files changed, 146 insertions, 90 deletions
diff --git a/Makefile b/Makefile
index df5f7fb..ad32e5f 100644
--- 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
index c2aecce..acf9d1f 100644
--- 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
index dec040f..de6ca33 100755
--- 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
index 6af7926..f63326d 100644
--- 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
index e07bbf1..a1e55a7 100644
--- 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
index de3a440..2bfe4e0 100755
--- 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
index e14786d..2fd6672 100644
--- 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
index b3bfbb2..cb46641 100644
--- 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
index bef6a88..581da29 100755
--- 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
index adfab62..0772856 100644
--- 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);
 }