commit b371bd55212984b35eb4d4d4834f44e008b45e80
Author: Gerrit Pape <pape@smarden.org>
Date: Fri, 16 Nov 2001 13:54:39 +0000
Initial revision
Diffstat:
35 files changed, 1153 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,41 @@
+DESTDIR=
+
+PACKAGE=runit-0.1.0
+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
+
+all: clean .manpages $(DAEMONTOOLS_PD).tar.gz $(PACKAGE).tar.gz
+
+.manpages:
+ for i in $(MANPAGES); do \
+ rman -S -f html -r '' < $$i | \
+ sed -e 's}NAME="sect\([0-9]*\)" HREF="#toc[0-9]*">\(.*\)}NAME="sect\1">\2}g ; \
+ s}<A HREF="#toc">Table of Contents</A>}<a href="http://innominate.org/~pape/">G. Pape</a><br><A HREF="index.html">runit</A><hr>}g ; \
+ s}<!--.*-->}}g' \
+ > doc/`basename $$i`.html ; \
+ done ; \
+ touch .manpages
+
+$(PACKAGE).tar.gz:
+ rm -rf TEMP
+ mkdir -p TEMP/admin/$(PACKAGE)
+ make -C src clean
+ cp -a $(DIRS) TEMP/admin/$(PACKAGE)/
+ ln -s ../etc/debian TEMP/admin/$(PACKAGE)/doc/
+ chmod -R g-ws TEMP/admin
+ chmod +t TEMP/admin
+ find TEMP -exec touch {} \;
+ su -c 'chown -R root:root TEMP/admin ; \
+ ( cd TEMP ; tar cpfz ../$(PACKAGE).tar.gz admin --exclude CVS ) ; \
+ rm -rf TEMP'
+
+clean:
+ find . -name \*~ -exec rm -f {} \;
+ find . -name .??*~ -exec rm -f {} \;
+ find . -name \#?* -exec rm -f {} \;
+
+cleaner: clean
+ rm -f $(PACKAGE).tar.gz
+ for i in $(MANPAGES); do rm -f doc/`basename $$i`.html; done
+ rm -f .manpages
diff --git a/debian/changelog b/debian/changelog
@@ -0,0 +1,9 @@
+runit (0.1.0-1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Gerrit Pape <pape@smarden.org> Fri, 16 Nov 2001 14:01:27 +0100
+
+Local variables:
+mode: debian-changelog
+End:
diff --git a/debian/conffiles b/debian/conffiles
@@ -0,0 +1,6 @@
+/etc/runit/1
+/etc/runit/2
+/etc/runit/3
+/etc/runit/ctrlaltdel
+/sbin/runit-halt
+/sbin/runit-reboot
diff --git a/debian/control b/debian/control
@@ -0,0 +1,19 @@
+Source: runit
+Section: admin
+Priority: optional
+Maintainer: Gerrit Pape <pape@smarden.org>
+Build-Depends: debhelper (>> 3.0.0)
+Standards-Version: 3.5.2
+
+Package: runit
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: minimal replacement for sysvinit using daemontools
+ runit cooperates with djb's daemontools package to create a replacement for
+ sysvinit. runit currently runs on Debian GNU/Linux but may be easily adopted
+ to other unix operating systems using glibc. If runit runs for you on any
+ other operating system or linux distribution, please let me know.
+ .
+ Warning: Replacing sysvinit can cause the system's boot to fail. Make sure
+ you are able to recover and repair your system, for example if you run a
+ bootloader, it should be able to pass init=/bin/sh to the kernel.
diff --git a/debian/copyright b/debian/copyright
@@ -0,0 +1,24 @@
+Copyright (c) 2001, Gerrit Pape
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/debian/dirs b/debian/dirs
@@ -0,0 +1,4 @@
+command
+package
+sbin
+etc/runit
diff --git a/debian/docs b/debian/docs
@@ -0,0 +1,3 @@
+package/README
+package/CHANGES
+doc/
diff --git a/debian/postinst b/debian/postinst
@@ -0,0 +1,48 @@
+#! /bin/sh
+# postinst script for runit
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see /usr/share/doc/packaging-manual/
+#
+# quoting from the policy:
+# Any necessary prompting should almost always be confined to the
+# post-installation script, and should be protected with a conditional
+# so that unnecessary prompting doesn't happen if a package's
+# installation fails and the `postinst' is called with `abort-upgrade',
+# `abort-remove' or `abort-deconfigure'.
+
+case "$1" in
+ configure)
+ ( \
+ cd /package/admin/runit-0.1.0
+ package/upgrade
+ )
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 0
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/rules b/debian/rules
@@ -0,0 +1,123 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This is the debhelper compatability version to use.
+export DH_COMPAT=3
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+
+
+ touch configure-stamp
+
+build: configure-stamp build-stamp
+build-stamp:
+ dh_testdir
+
+ # Add here commands to compile the package.
+ # $(MAKE)
+ #/usr/bin/docbook-to-man debian/runit.sgml > runit.1
+
+ tar xfzvp runit-0.1.0.tar.gz
+ mkdir -p admin/runit-0.1.0/compile
+ tar xfzvp daemontools-pd-0.76.tar.gz \
+ -C admin/runit-0.1.0/compile
+ ( cd admin/runit-0.1.0/compile ; \
+ ln -s daemontools-pd-0.76 support )
+ ( \
+ cd admin/runit-0.1.0 ; \
+ package/compile ; \
+ echo "/package/admin/runit-0.1.0" > compile/home ; \
+ rm -f compile/src ; \
+ ln -s /package/admin/runit-0.1.0/src compile/src ; \
+ )
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ # -$(MAKE) clean
+
+ rm -rf admin
+ rm -f debian/links
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/runit.
+ # $(MAKE) install DESTDIR=$(CURDIR)/debian/runit
+
+ chmod 1755 debian/runit/package
+ cp -a admin debian/runit/package/
+ rm -rf debian/runit/package/admin/runit-0.1.0/compile
+ rm -rf debian/runit/package/admin/runit-0.1.0/man
+ rm -rf debian/runit/package/admin/runit-0.1.0/doc
+ rm -rf debian/runit/package/admin/runit-0.1.0/etc
+
+ # /etc/runit
+ cp -p admin/runit-0.1.0/etc/debian/[123] \
+ debian/runit/etc/runit/
+ cp -p admin/runit-0.1.0/etc/debian/ctrlaltdel \
+ debian/runit/etc/runit/
+ # runit programs
+ cp -p debian/runit/package/admin/runit-0.1.0/command/runit* \
+ debian/runit/sbin/
+
+ # cleanup
+ rm -rf debian/runit/package/admin/runit-0.1.0/compile
+
+ # create debian/links
+ rm -f debian/links
+ for i in \
+ `cat debian/runit/package/admin/runit-0.1.0/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.0/package/commands` ; \
+# do \
+# echo "/command/$$i /usr/local/bin/$$i" \
+# >> debian/links ; \
+# done
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+# dh_installdebconf
+ dh_installdocs
+ dh_installman man/runit*.8
+ dh_installchangelogs
+ dh_link
+ dh_strip
+ dh_compress
+# dh_fixperms
+# dh_makeshlibs
+ dh_installdeb
+# dh_perl
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/doc/index.html b/doc/index.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - minimal replacement for sysvinit</title>
+</head>
+<body>
+<a href="http://innominate.org/~pape/">G. Pape</a>
+<hr>
+<h1>runit - minimal replacement for <i>sysvinit</i></h1>
+<hr>
+<a href="install.html">How to install runit</a><br>
+<a href="replaceinit.html">How to replace init</a>
+<p>
+<a href="runit.8.html">The <tt>runit</tt> program</a><br>
+<a href="runit-init.8.html">The <tt>runit-init</tt> program</a><br>
+<a href="runit-halt.8.html">The <tt>runit-halt</tt> program</a><br>
+<a href="runit-reboot.8.html">The <tt>runit-reboot</tt> program</a>
+<hr>
+<i>runit</i> cooperates with djb's
+<a href="http://cr.yp.to/daemontools.html">daemontools</a> package to create
+a replacement for
+<a href="ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/">sysvinit</a>.
+<i>runit</i> currently runs on
+<a href="http://www.debian.org">Debian GNU/Linux</a> but may be easily
+adopted to other unix operating systems using glibc. If <i>runit</i> runs for
+you on any other operating system or linux distribution, please let me know.
+<p>
+<b>Warning:</b> Replacing <i>sysvinit</i> can cause the system's boot to fail.
+Make sure you are able to recover and repair your system, for example if you
+run a bootloader, it should be able to pass <tt>init=/bin/sh</tt> to the
+kernel.
+<hr>
+The command <a href="runit.8.html">runit</a> is intended to run as Unix
+process no 1, it is automatically started by the
+<a href="runit-init.8.html">runit-init</a> replacement if this is started
+by the kernel.
+<p>
+<a href="runit.8.html">runit</a> performs the system's <i>booting</i>,
+<i>running</i> and <i>shutting down</i> in <b>three stages</b>:
+<ul>
+ <li><b>Stage 1:</b><br>
+ <i>runit</i> starts <tt>/etc/runit/1</tt> and waits for it to
+ terminate. The system's one time tasks are done here.
+ <li><b>Stage 2:</b><br>
+ <i>runit</i> starts <tt>/etc/runit/2</tt> which should not return
+ until the system is going to halt or reboot, if it crashes, it will be
+ restarted. Normally, <tt>/etc/runit/2</tt> runs
+ <a href="http://cr.yp.to/daemontools/svscanboot.html">svscanboot</a>.
+ In Stage 2, <i>runit</i> is able to handle the ctrl-alt-del keyboard
+ request.
+ <li><b>Stage 3:</b><br>
+ If <i>runit</i> 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
+ <tt>/etc/runit/3</tt>. The systems tasks to shutdown and halt or
+ reboot are done here.
+</ul>
+These are working examples for debian woody:
+<a href="debian/1">/etc/runit/1</a>,
+<a href="debian/2">/etc/runit/2</a>,
+<a href="debian/3">/etc/runit/3</a>.
+<p>
+The command <a href="runit-init.8.html">runit-init</a> is intended to replace
+<tt>/sbin/init</tt>. sysvinit's command <tt>shutdown</tt> will keep working.
+Runlevels are not implemented in this Unix process no 1, such can easily be
+done in other programs, see
+<a href="http://innominate.org/~pape/djb/daemontools/noinit.html">
+Dependencies and runlevels</a>
+for an example, the amount of code in process no 1 should be minimal.
+<hr>
+See <a href="replaceinit.html">How to replace init</a> for smoothly migrating
+from <i>sysvinit</i>.
+<hr>
+See <a href="http://innominate.org/~pape/runit/">
+http://innominate.org/~pape/runit/</a>
+for recent informations.
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape <pape@smarden.org>
+</a></address>
+<small>$Id$</small>
+</body>
+</html>
diff --git a/doc/install.html b/doc/install.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - installation</title>
+</head>
+<body>
+<a href="http://innominate.org/~pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - installation</h1>
+<hr>
+Check that you have the recent version of
+<a href="http://cr.yp.to/daemontools.html">daemontools</a> installed.
+<p>
+Download
+<a href="ftp://ftp.innominate.org/pub/pape/runit/runit-0.1.0.tar.gz">
+runit-0.1.0.tar.gz</a> into <tt>/package</tt> and unpack the archive
+<pre>
+ # cd /package
+ # gunzip runit-0.1.0.tar
+ # tar -xpf runit-0.1.0.tar
+ # rm runit-0.1.0.tar
+ # cd admin/runit-0.1.0
+</pre>
+Compile and install the <i>runit</i> programs
+<pre>
+ # package/install
+</pre>
+gzip the man pages and copy them into a reasonable directory in your
+<tt>$MANPATH</tt>, e.g.
+<pre>
+ # mkdir -p /usr/local/man/man8/
+ # gzip man/runit.8 && cp -f man/runit.8.gz /usr/local/man/man8/
+ # gzip man/runit-init.8 && cp -f man/runit-init.8.gz /usr/local/man/man8/
+ # gzip man/runit-halt.8 && cp -f man/runit-halt.8.gz /usr/local/man/man8/
+ # gzip man/runit-reboot.8 && cp -f man/runit-reboot.8.gz /usr/local/man/man8/
+</pre>
+Refer to <a href="replaceinit.html">replacing init</a> for
+replacing <i>sysvinit</i> with <i>runit</i>.
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape <pape@smarden.org>
+</a></address>
+<small>$Id$</small>
+</body>
+</html>
diff --git a/doc/replaceinit.html b/doc/replaceinit.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - replacing init</title>
+</head>
+<body>
+<a href="http://innominate.org/~pape/">G. Pape</a><br>
+<a href="index.html">runit</a>
+<hr>
+<h1>runit - replacing init</h1>
+<hr>
+Follow these steps to migrate from <i>sysvinit</i> to <i>runit</i> on
+<a href="http://www.debian.org/releases/woody/">Debian GNU/Linux (woody)</a>.
+The <tt>/sbin/init</tt> binary is not replaced until step 6, <i>runit</i> is
+the default Unix process no 1 after step 7.
+<h3>Step 1: The three stages</h3>
+<i>runit</i> looks for the three stages implementing the system's
+<i>booting</i>, <i>running</i> and <i>shutdown</i> in <tt>/etc/runit/1</tt>,
+<tt>/etc/runit/2</tt> and <tt>/etc/runit/3</tt>, create the files now:
+<pre>
+ # mkdir -p /etc/runit
+ # cp -p /package/admin/runit/etc/debian/[123] /etc/runit/
+</pre>
+If you want <i>runit</i> to handle the ctrl-alt-del keyboard request, do:
+<pre>
+ # cp -p /package/admin/runit/etc/debian/ctrlaltdel /etc/runit/
+</pre>
+<h3>Step 2: The runit programs</h3>
+The <i>runit</i> programs must reside on the root partition, copy them to
+<tt>/sbin</tt>:
+<pre>
+ # cp -p /package/admin/runit/command/runit* /sbin/
+</pre>
+<h3>Step 3: The getties</h3>
+At least one getty must run in stage 2 so you are able to login, choose a
+free <tt>tty</tt>, say <tt>tty5</tt>, where <i>sysvinit</i> is not running
+any getty (edit <tt>/etc/inittab</tt> and <tt>kill -HUP 1</tt> if
+needed) and install a getty as <i>service</i>:
+<pre>
+ # cp -pr /package/admin/runit/etc/debian/getty-tty5 /etc/runit/
+ # ln -s /etc/runit/getty-tty5 /service/
+</pre>
+Check if the getty is running.
+<h3>Step 4: Reboot into runit for test</h3>
+Boot your system with <i>runit</i> for the first time. This does not change
+the default boot behavior of your system, <i>lilo</i> will be told to use
+<i>runit</i> just once:
+<ul>
+ <li>reboot the system
+ <li>enter the following on the lilo prompt:<br>
+ <tt>init=/sbin/runit-init</tt>
+ <li>watch the console output while runit boots up the system
+ <li>switch to <tt>tty5</tt> when stage 2 is reached, a <tt>getty</tt>
+ should run there, you are able to login.
+</ul>
+If you are not using <i>lilo</i> as boot loader, refer to the documentation
+of your boot loader on how to pass <tt>init=/sbin/runit-init</tt> to the
+kernel.
+<h3>Step 5: Service migration</h3>
+The goal is to migrate all services from <i>sysvinit</i> scheme to the
+<a href="http://cr.yp.to/daemontools.html">daemontools</a> design. This
+can be done smoothly. For those services that are not migrated to use
+<tt>run</tt> scripts yet, add the corresponding <tt>init</tt>-script
+startup to <tt>/etc/runit/1</tt>, e.g.:
+<pre>
+ #!/bin/sh
+ # one time tasks
+ rm -f /etc/runit/stopit
+ /etc/init.d/rcS
+
+ /etc/init.d/kerneld start
+ /etc/init.d/rmnologin
+
+ exit 0
+</pre>
+It is possible to just add <tt>/etc/init.d/rc 2</tt> for having all services
+from the former runlevel 2 started as one time tasks, but keep the goal above
+in mind, supervising services has great advantages.
+<p>
+Repeat step 4 and 5, using <tt>/sbin/runit-reboot</tt> to reboot the system,
+until your are satisfied with your services startup. If anything goes wrong,
+reboot the system with the default <i>sysvinit</i> <tt>/sbin/init</tt>
+and repair the <i>runit</i> stages, then start again at step 4.
+<h3>Step 6: Replace /sbin/init</h3>
+Now it is time to replace the <i>sysvinit</i> <tt>/sbin/init</tt> binary:
+<pre>
+ # mv /sbin/init /sbin/init.sysv
+ # ln -s runit-init /sbin/init
+</pre>
+<h3>Step 7: Final reboot</h3>
+The last step is to do the final reboot to boot the system with the new
+default Unix process no 1 <i>runit</i>.
+<pre>
+ # shutdown -r now
+</pre>
+To report success:
+<pre>
+ # ( uname -a ; cat /etc/runit/[123] ) | mail pape-runit-0.1.0@smarden.org
+</pre>
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape <pape@smarden.org>
+</a></address>
+<small>$Id$</small>
+</body>
+</html>
diff --git a/etc/debian/1 b/etc/debian/1
@@ -0,0 +1,8 @@
+#!/bin/sh
+# system one time tasks
+rm -f /etc/runit/stopit
+/etc/init.d/rcS
+
+/etc/init.d/rmnologin
+
+exit 0
diff --git a/etc/debian/2 b/etc/debian/2
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /command/svscanboot
diff --git a/etc/debian/3 b/etc/debian/3
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+LAST=0
+test -r /etc/runit/reboot && LAST=6
+
+echo 'Stopping services...'
+/command/svc -d /service/*
+/bin/sleep 5
+echo 'Stopping log services...'
+/command/svc -d /service/*/log
+/bin/sleep 5
+
+/etc/init.d/rc $LAST
+
+exit 0
diff --git a/etc/debian/ctrlaltdel b/etc/debian/ctrlaltdel
@@ -0,0 +1,4 @@
+#!/bin/sh
+MSG="System is going down in 10 seconds..."
+/bin/echo "$MSG" | /usr/bin/wall
+/bin/sleep 10
diff --git a/man/runit-halt.8 b/man/runit-halt.8
@@ -0,0 +1,35 @@
+.TH runit-halt 8
+.SH NAME
+runit-halt \- stop the system
+.SH SYNOPSIS
+.B init
+0
+.br
+.B runit-halt
+.SH DESCRIPTION
+.B runit-halt
+causes the Unix process no 1
+.BR runit (8)
+to halt the system. Normally
+.B runit-halt
+is run by
+.BR runit-init (8)
+if called as
+.B init 0\fR.
+.P
+To signal
+.BR runit (8)
+the system halt request,
+.B runit-halt
+removes the /etc/runit/reboot file and touches /etc/runit/stopit. Then a CONT
+signal is sent to
+.BR runit (8).
+.SH EXIT CODES
+.B runit-halt
+always returns 0.
+.SH SEE ALSO
+runit-init(8),
+runit(8),
+runit-reboot(8)
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/man/runit-init.8 b/man/runit-init.8
@@ -0,0 +1,38 @@
+.TH runit-init 8
+.SH NAME
+init \- the UNIX process no 1
+.SH SYNOPSIS
+.B init
+[ 0 | 6 ]
+.SH DESCRIPTION
+.B runit-init
+is the first process the kernel starts. If
+.B runit-init
+is started as process no 1, it runs and replaces itself with
+.BR runit (8).
+.P
+If
+.B runit-init
+is started while the system is up, it must be either called as
+.B init 0
+or
+.B init 6\fR:
+.TP
+.B init 0
+run
+.BR runit-halt (8)
+to halt the system.
+.TP
+.B init 6
+run
+.BR runit-reboot (8)
+to reboot the system.
+.SH EXIT CODES
+.B runit-init
+returns 111 on error, 0 in all other cases.
+.SH SEE ALSO
+runit(8),
+runit-halt(8),
+runit-reboot(8)
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/man/runit-reboot.8 b/man/runit-reboot.8
@@ -0,0 +1,35 @@
+.TH runit-reboot 8
+.SH NAME
+runit-reboot \- reboot the system
+.SH SYNOPSIS
+.B init
+6
+.br
+.B runit-reboot
+.SH DESCRIPTION
+.B runit-reboot
+causes the Unix process no 1
+.BR runit (8)
+to reboot the system. Normally
+.B runit-reboot
+is run by
+.BR runit-init (8)
+if called as
+.B init 6\fR.
+.P
+To signal
+.BR runit (8)
+the system reboot request,
+.B runit-reboot
+touches the /etc/runit/reboot and /etc/runit/stopit files. Then a CONT
+signal is sent to
+.BR runit (8).
+.SH EXIT CODES
+.B runit-reboot
+always returns 0.
+.SH SEE ALSO
+runit-init(8),
+runit(8),
+runit-halt(8)
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/man/runit.8 b/man/runit.8
@@ -0,0 +1,64 @@
+.TH runit 8
+.SH NAME
+runit \- the UNIX process no 1
+.SH SYNOPSIS
+.B runit
+.SH DESCRIPTION
+.B runit
+must be run as Unix process no 1. It performs the system's
+booting, running and shutdown in three stages:
+.SH STAGE 1
+.B runit
+runs
+.I /etc/runit/1
+and waits for it to terminate. The system's one time tasks are done here.
+.SH STAGE 2
+.B runit
+runs
+.IR /etc/runit/2 ,
+which should not return until system shutdown. 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.
+.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
+.IR /etc/runit/3 .
+The systems tasks to shutdown and halt or reboot are done here.
+.SH CTRL-ALT-DEL
+If
+.B runit
+receives the ctrl-alt-del keyboard request and the file
+.I /etc/runit/ctrlaltdel
+exists,
+.B runit
+runs
+.IR /etc/runit/ctrlaltdel ,
+waits for it to terminate and then enters stage 3 for system shutdown.
+.SH SIGNALS
+.B runit
+only accepts signals in stage 2.
+.P
+If
+.B runit
+receives a CONT signal and the file
+.I /etc/runit/stopit
+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),
+runit-reboot(8)
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/package/CHANGES b/package/CHANGES
@@ -0,0 +1,8 @@
+runit 0.1.0
+Fri, 16 Nov 2001 14:01:27 +0100
+ * documention
+ * debian package
+
+runit 0.0.4
+Sun, 11 Nov 2001 19:07:49 +0100
+ * initial release
diff --git a/package/COPYING b/package/COPYING
@@ -0,0 +1,24 @@
+Copyright (c) 2001, Gerrit Pape
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/package/README b/package/README
@@ -0,0 +1,3 @@
+Copyright 2001
+G. Pape
+http://innominate.org/~pape/runit/
diff --git a/package/commands b/package/commands
@@ -0,0 +1,4 @@
+runit
+runit-init
+runit-halt
+runit-reboot
diff --git a/package/compile b/package/compile
@@ -0,0 +1,31 @@
+#!/bin/sh -e
+
+umask 022
+test -d package || ( echo 'Wrong working directory.'; exit 1 )
+test -d src || ( echo 'Wrong working directory.'; exit 1 )
+
+here=`env - PATH=$PATH pwd`
+
+mkdir -p compile command
+test -r compile/home || echo $here > compile/home
+test -h compile/src || ln -s $here/src compile/src
+
+echo 'Linking ./src/* into ./compile...'
+for i in `ls src`
+do
+ test -h compile/$i || ln -s src/$i compile/$i
+done
+
+# support, default: ../daemontools/compile
+test -h compile/support || ln -s ../../daemontools/compile compile/support
+
+echo 'Compiling everything in ./compile...'
+( cd compile; exec make )
+
+echo 'Copying commands into ./command...'
+for i in `cat package/commands`
+do
+ rm -f command/$i'{new}'
+ cp -p compile/$i command/$i'{new}'
+ mv -f command/$i'{new}' command/$i
+done
diff --git a/package/install b/package/install
@@ -0,0 +1,4 @@
+#!/bin/sh -e
+
+package/compile
+package/upgrade
diff --git a/package/replaceinit b/package/replaceinit
@@ -0,0 +1,28 @@
+#!/bin/sh -e
+
+umask 022
+test -d package || ( echo 'Wrong working directory.'; exit 1 )
+test -d src || ( echo 'Wrong working directory.'; exit 1 )
+
+here=`env - PATH=$PATH pwd`
+
+echo 'Copying ./etc/runit into /etc...'
+rm -f /etc/runit'{new}'
+cp -pr ./etc/runit /etc/runit'{new}'
+mv -f /etc/runit'{new}' /etc/runit
+
+echo 'Copying commands into /sbin...'
+for i in `cat package/commands`
+do
+ rm -f /sbin/$i'{new}'
+ cp -p command/$i /sbin/$i'{new}'
+ mv -f /sbin/$i'{new}' /sbin/$i
+done
+
+echo 'Copying original /sbin/init to /sbin/init.orig...'
+cp /sbin/init /sbin/init.orig
+
+echo 'Linking /sbin/runit-init to /sbin/init...'
+rm -f /sbin/init'{new}'
+ln -s /sbin/runit-init /sbin/init'{new}'
+mv -f /sbin/init'{new}' /sbin/init
diff --git a/package/sharing b/package/sharing
@@ -0,0 +1,3 @@
+command:syst
+package:dist
+src:dist
diff --git a/package/upgrade b/package/upgrade
@@ -0,0 +1,30 @@
+#!/bin/sh -e
+
+umask 022
+test -d package || ( echo 'Wrong working directory.'; exit 1 )
+test -d src || ( echo 'Wrong working directory.'; exit 1 )
+
+here=`env - PATH=$PATH pwd`
+parent=`dirname $here`
+
+echo 'Creating symlink runit -> runit-0.1.0...'
+rm -f runit
+ln -s runit-0.1.0 runit
+mv -f runit ..
+
+echo 'Making command links in /command...'
+mkdir -p /command
+for i in `cat package/commands`
+do
+ rm -f /command/$i'{new}'
+ ln -s $parent/runit/command/$i /command/$i'{new}'
+ mv -f /command/$i'{new}' /command/$i
+done
+#echo 'Making compatibility links in /usr/local/bin...'
+#mkdir -p /usr/local/bin
+#for i in `cat package/commands`
+#do
+# rm -f /usr/local/bin/$i'{new}'
+# ln -s /command/$i /usr/local/bin/$i'{new}'
+# mv -f /usr/local/bin/$i'{new}' /usr/local/bin/$i
+#done
diff --git a/src/Makefile b/src/Makefile
@@ -0,0 +1,27 @@
+DESTDIR=
+
+CC=gcc
+
+CFLAGS=-Wall -O3 -Isupport
+LDFLAGS=-Wall -O3 -s
+
+all: runit runit-init
+
+runit: djb-publicdomain runit.o
+ $(CC) $(LDFLAGS) -o runit \
+ runit.o support/unix.a support/byte.a
+
+runit-init: djb-publicdomain init.o
+ $(CC) $(LDFLAGS) -o runit-init \
+ init.o support/unix.a support/byte.a
+
+djb-publicdomain:
+ ( cd support ; make )
+
+clean:
+ find . -name \*~ -exec rm -f {} \;
+ find . -name .??*~ -exec rm -f {} \;
+ find . -name \#?* -exec rm -f {} \;
+ if test -h support; \
+ then ( cd support ; $(MAKE) clean ); fi
+ rm -f `cat TARGETS`
diff --git a/src/TARGETS b/src/TARGETS
@@ -0,0 +1,4 @@
+runit
+runit.o
+runit-init
+init.o
diff --git a/src/init.c b/src/init.c
@@ -0,0 +1,54 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include "strerr.h"
+#include "pathexec.h"
+
+#define USAGE " 0|6"
+#define WARNING "init: warning: "
+#define FATAL "init: fatal: "
+
+#define RUNIT "/sbin/runit"
+#define HALT "/sbin/runit-halt"
+#define REBOOT "/sbin/runit-reboot"
+
+const char *progname;
+
+void usage(void) {
+ strerr_die4x(1, "usage: ", progname, USAGE, "\n");
+}
+
+int main (int argc, const char * const *argv, const char * const *envp) {
+ const char *prog[2];
+
+ progname =*argv++;
+
+ prog[1] =0;
+
+ if (getpid() == 1) {
+ prog[0] ="runit";
+
+ /* kernel is starting init, runit does the job. */
+ pathexec_run(RUNIT, (const char* const *) prog, envp);
+
+ /* serious error */
+ strerr_die4sys(111, FATAL, "unable to start ", prog[0], ": ");
+ }
+
+ if (! *argv) usage();
+
+ if (**argv == '0') {
+ prog[0] =HALT;
+ pathexec_run(*prog, (const char* const *) prog, envp);
+ strerr_die4sys(111, FATAL, "unable to start ", prog[0], ": ");
+ }
+ if (**argv == '6') {
+ prog[0] =REBOOT;
+ pathexec_run(*prog, (const char* const *) prog, envp);
+ strerr_die4sys(111, FATAL, "unable to start ", prog[0], ": ");
+ }
+
+ usage();
+
+ /* not reached */
+ exit(0);
+}
diff --git a/src/runit-halt b/src/runit-halt
@@ -0,0 +1,7 @@
+#!/bin/sh
+( cd /etc/runit
+rm -f reboot
+touch stopit
+kill -CONT 1
+)
+exit 0
diff --git a/src/runit-reboot b/src/runit-reboot
@@ -0,0 +1,6 @@
+#!/bin/sh
+( cd /etc/runit
+touch stopit reboot
+kill -CONT 1
+)
+exit 0
diff --git a/src/runit.c b/src/runit.c
@@ -0,0 +1,208 @@
+/* this requires: */
+#include <poll.h>
+
+#include <sys/types.h>
+#include <sys/reboot.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "sig.h"
+#include "strerr.h"
+#include "error.h"
+#include "pathexec.h"
+#include "iopause.h"
+#include "coe.h"
+#include "ndelay.h"
+#include "wait.h"
+#include "open.h"
+
+/* #define DEBUG */
+
+#define INFO "- runit: "
+#define WARNING "- runit: warning: "
+#define FATAL "- runit: fatal: "
+
+#define STOPIT "/etc/runit/stopit"
+#define CTRLALTDEL "/etc/runit/ctrlaltdel"
+
+const char * const take[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) {
+ sigc++;
+ write(selfpipe[1], "", 1);
+}
+void sig_int_handler(void) {
+ sigi++;
+ write(selfpipe[1], "", 1);
+}
+void sig_child_handler(void) {
+ write(selfpipe[1], "", 1);
+}
+
+int main (int argc, const char * const *argv, const char * const *envp) {
+ int pid, pid2;
+ int wstat;
+ int fd;
+ int i;
+ int stopit =0;
+ iopause_fd x;
+ char ch;
+
+ setsid();
+
+ sig_block(sig_alarm);
+ sig_block(sig_child);
+ sig_catch(sig_child, sig_child_handler);
+ sig_block(sig_cont);
+ sig_catch(sig_cont, sig_cont_handler);
+ sig_block(sig_hangup);
+ sig_block(sig_int);
+ sig_catch(sig_int, sig_int_handler);
+ sig_block(sig_pipe);
+ sig_block(sig_term);
+
+ /* create selfpipe */
+ while (pipe(selfpipe) == -1) {
+ strerr_warn2(FATAL, "unable to create selfpipe, pausing: ", &strerr_sys);
+ sleep(5);
+ }
+ coe(selfpipe[0]);
+ coe(selfpipe[1]);
+ ndelay_on(selfpipe[0]);
+ ndelay_on(selfpipe[1]);
+
+ /* activate ctrlaltdel handling */
+ reboot(0);
+
+ strerr_warn3(INFO, "$Id$", ": booting.", 0);
+
+ /* runit */
+ for (i =0; i < 3; i++) {
+ while ((pid =fork()) == -1) {
+ strerr_warn4(FATAL, "unable to fork for \"", take[i], "\" pausing: ",
+ &strerr_sys);
+ sleep(5);
+ }
+ if (!pid) {
+ /* child */
+ const char * prog[2];
+
+ prog[0] =take[i];
+ prog[1] =0;
+
+ setsid();
+
+ sig_unblock(sig_alarm);
+ sig_unblock(sig_child);
+ sig_uncatch(sig_child);
+ sig_unblock(sig_cont);
+ sig_ignore(sig_cont);
+ sig_unblock(sig_hangup);
+ sig_unblock(sig_int);
+ sig_uncatch(sig_int);
+ sig_unblock(sig_pipe);
+ sig_unblock(sig_term);
+
+ strerr_warn3(INFO, "enter stage: ", take[i], 0);
+ pathexec_run(*prog, (const char* const *) prog, envp);
+ strerr_warn3(FATAL, "could not start child: ", take[i], &strerr_sys);
+ }
+
+ x.fd =selfpipe[0];
+ x.events =IOPAUSE_READ;
+
+ for (;;) {
+ sig_unblock(sig_child);
+ sig_unblock(sig_cont);
+ sig_unblock(sig_int);
+ poll(&x, 1, -1);
+ 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);
+ strerr_warn2(WARNING, "restarting.", 0);
+ i--;
+ break;
+ }
+ }
+ if (stopit) stopit =0;
+ strerr_warn3(INFO, "leave stage: ", take[i], 0);
+ break;
+ }
+
+ /* sig */
+ if ((sigc == 0) && (sigi == 0)) {
+#ifdef DEBUG
+ strerr_warn2(WARNING, "poll: ", &strerr_sys);
+#endif
+ continue;
+ }
+ if ((i != 1) || stopit) {
+ 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);
+ while ((pid2 =fork()) == -1) {
+ strerr_warn4(FATAL,
+ "unable to fork for \"", CTRLALTDEL, "\" pausing: ",
+ &strerr_sys);
+ sleep(5);
+ }
+ if (!pid2) {
+ /* child */
+ const char * prog[2];
+
+ prog[0] =CTRLALTDEL;
+ prog[1] =0;
+
+ strerr_warn3(INFO, "enter stage: ", prog[0], 0);
+ pathexec_run(*prog, (const char* const *) prog, envp);
+ strerr_warn3(FATAL, "could not start child: ", prog[0], &strerr_sys);
+ }
+ if (wait_pid(&wstat, pid2) == -1) {
+ strerr_warn2(FATAL, "wait_pid: ", &strerr_sys);
+ }
+ if (wait_crashed(wstat)) {
+ strerr_warn3(WARNING, "child crashed: ", CTRLALTDEL, 0);
+ }
+ kill(pid, SIGTERM);
+ sigc =sigi =0;
+ stopit =1;
+ continue;
+ }
+
+#ifdef DEBUG
+ strerr_warn2(WARNING, "no request.", 0);
+#endif
+ }
+ }
+ /* not reached */
+ strerr_warn2(INFO, "exit.", 0);
+ exit(0);
+}