summaryrefslogtreecommitdiff
path: root/daemons
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2013-09-18 15:29:36 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-11-21 05:49:03 +0100
commit7e9c559c75901f391b4151ed6cabba74e60f80af (patch)
tree12a5189c81b4a13d203a139f698ea15be6e41f8c /daemons
parent0224d569030e6838c63cf946ae7321be923afc23 (diff)
init: add a minimalist init program
This patch adds a minimalist init program. It is somewhat lacking in features, but is able to bring up a Hurd system with the runsystem and rc scripts. In fact, it roughly does what the former /hurd/init did, modulo all the very early bootstrapping stuff and the startup protocol. It is started when all the essential servers are up and running, so it can make use of most of the POSIX goodies, making its implementation much simpler. * Makefile (prog-subdirs): Add init. * daemons/runsystem.sh: Generalize runsystem so that it can start any init as specified on the kernel command line. By default, it starts /hurd/init. * daemons/runsystem.hurd: This is a verbatim copy of runsystem.sh. It is started by /hurd/init. * daemons/rc.sh: Do not start /hurd/mach-defpager as it is already started in runsystem.sh. * daemons/Makefile (SRCS): Add runsystem.hurd. * init/Makefile: New file. * init/init.c: Likewise.
Diffstat (limited to 'daemons')
-rw-r--r--daemons/Makefile4
-rw-r--r--daemons/rc.sh3
-rw-r--r--daemons/runsystem.hurd155
-rw-r--r--daemons/runsystem.sh80
4 files changed, 184 insertions, 58 deletions
diff --git a/daemons/Makefile b/daemons/Makefile
index d16680ec..db1acc77 100644
--- a/daemons/Makefile
+++ b/daemons/Makefile
@@ -22,7 +22,9 @@ makemode := utilities
targets = rc getty mail.local console-run runttys runsystem
special-targets = rc runsystem
-SRCS = rc.sh runsystem.sh getty.c lmail.c console-run.c runttys.c
+SRCS = rc.sh runsystem.sh getty.c lmail.c console-run.c runttys.c \
+ runsystem.hurd \
+
installationdir = $(libexecdir)
HURDLIBS = fshelp ports shouldbeinlibc
diff --git a/daemons/rc.sh b/daemons/rc.sh
index 5cf44fa6..12408830 100644
--- a/daemons/rc.sh
+++ b/daemons/rc.sh
@@ -2,9 +2,6 @@
PATH=/bin:/sbin
-# Start the default pager. It will bail if there is already one running.
-/hurd/mach-defpager
-
# Set up swap space. This will complain if no default pager is functioning.
swapon -a
diff --git a/daemons/runsystem.hurd b/daemons/runsystem.hurd
new file mode 100644
index 00000000..f4f27711
--- /dev/null
+++ b/daemons/runsystem.hurd
@@ -0,0 +1,155 @@
+#!/bin/bash
+#
+# This program is run by /hurd/init at boot time after the essential
+# servers are up, and is responsible for running the "userland" parts of a
+# normal system. This includes running the single-user shell as well as a
+# multi-user system. This program is expected never to exit.
+#
+
+
+###
+### Where to find programs, etc.
+###
+
+PATH=/bin:/sbin
+export PATH
+
+umask 022
+
+# If we lose badly, try to exec each of these in turn.
+fallback_shells='/bin/sh /bin/bash /bin/csh /bin/ash /bin/shd'
+
+# Shell used for normal single-user startup.
+SHELL=/bin/sh
+
+# Programs that do multi-user startup.
+RUNCOM=/libexec/rc
+RUNTTYS=/libexec/runttys
+# Signals that we should pass down to runttys.
+runttys_sigs='TERM INT HUP TSTP'
+
+###
+
+
+# If we get a SIGLOST, attempt to reopen the console in case
+# our console ports were revoked. This lets us print messages.
+function reopen_console ()
+{
+ exec 1>/dev/console 2>&1 || exit 3
+}
+trap 'reopen_console' SIGLOST
+
+
+# Call this when we are losing badly enough that we want to punt normal
+# startup entirely. We exec a single-user shell, so we will not come back
+# here. The only way to get to multi-user from that shell will be
+# explicitly exec this script or something like that.
+function singleuser ()
+{
+ test $# -eq 0 || echo "$0: $*"
+ for try in ${fallback_shells}; do
+ SHELL=${try}
+ exec ${SHELL}
+ done
+ exit 127
+}
+
+
+# See whether pflocal is set up already, and do so if not (install case)
+#
+# Normally this should be the case, but we better make sure since
+# without the pflocal server, pipe(2) does not work.
+if ! test -e /servers/socket/1 ; then
+ # The root filesystem should be read-only at this point.
+ if fsysopts / --update --writable ; then
+ settrans -c /servers/socket/1 /hurd/pflocal
+ else
+ singleuser "Failed to create /servers/socket/1."
+ fi
+fi
+
+# We expect to be started by console-run, which gives us no arguments and
+# puts FALLBACK_CONSOLE=file-name in the environment if our console is
+# other than a normal /dev/console.
+
+if [ "${FALLBACK_CONSOLE+set}" = set ]; then
+ singleuser "Running on fallback console ${FALLBACK_CONSOLE}"
+fi
+
+
+###
+### Normal startup procedures
+###
+
+# Parse the multiboot command line. We only pay attention to -s and -f.
+# The first argument is the kernel file name; skip that.
+shift
+flags=
+while [ $# -gt 0 ]; do
+ arg="$1"
+ shift
+ case "$arg" in
+ --*) ;;
+ *=*) ;;
+ -*)
+ flags="${flags}${arg#-}"
+ ;;
+ 'single'|'emergency') # Linux compat
+ flags="${flags}s"
+ ;;
+ 'fastboot')
+ flags="${flags}f"
+ ;;
+ esac
+done
+
+# Check boot flags.
+case "$flags" in
+*s*)
+ rc=false # force single-user
+ ;;
+*f*)
+ rc="${RUNCOM}" # fastboot
+ ;;
+*)
+ rc="${RUNCOM} autoboot" # multi-user default
+ ;;
+esac
+
+# Large infinite loop. If this script ever exits, init considers that
+# a serious bogosity and punts to a fallback single-user shell.
+# We handle here the normal transitions between single-user and multi-user.
+while : ; do
+
+ # Run the rc script. As long as it exits nonzero, punt to single-user.
+ # After the single-user shell exits, we will start over attempting to
+ # run rc; but later invocations strip the `autoboot' argument.
+ until $rc; do
+ rc=${RUNCOM}
+
+ # Run single-user shell and repeat as long as it dies with a signal.
+ until ${SHELL} || test $? -lt 128; do
+ :
+ done
+ done
+
+ # Now we are officially ready for normal multi-user operation.
+
+ # Trap certain signals and send them on to runttys. For this to work, we
+ # must run it asynchronously and wait for it with the `wait' built-in.
+ runttys_pid=0
+ for sig in $runttys_sigs; do
+ trap "kill -$sig \${runttys_pid}" $sig
+ done
+
+ # This program reads /etc/ttys and starts the programs it says to.
+ ${RUNTTYS} &
+ runttys_pid=$!
+
+ # Wait for runttys to die, meanwhile handling trapped signals.
+ wait
+
+ # Go back to the top of the infinite loop, as if booting single-user.
+ rc=false
+
+done
diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh
index f4f27711..ae25a7d6 100644
--- a/daemons/runsystem.sh
+++ b/daemons/runsystem.sh
@@ -1,9 +1,9 @@
#!/bin/bash
#
# This program is run by /hurd/init at boot time after the essential
-# servers are up, and is responsible for running the "userland" parts of a
-# normal system. This includes running the single-user shell as well as a
-# multi-user system. This program is expected never to exit.
+# servers are up. It does some initialization of its own and then
+# execs /hurd/init or any other roughly SysV init-compatible program
+# to bring up the "userland" parts of a normal system.
#
@@ -22,11 +22,10 @@ fallback_shells='/bin/sh /bin/bash /bin/csh /bin/ash /bin/shd'
# Shell used for normal single-user startup.
SHELL=/bin/sh
-# Programs that do multi-user startup.
-RUNCOM=/libexec/rc
-RUNTTYS=/libexec/runttys
-# Signals that we should pass down to runttys.
-runttys_sigs='TERM INT HUP TSTP'
+# The init program to call.
+#
+# Can be overridden using init=something in the kernel command line.
+init=/hurd/init
###
@@ -44,7 +43,7 @@ trap 'reopen_console' SIGLOST
# startup entirely. We exec a single-user shell, so we will not come back
# here. The only way to get to multi-user from that shell will be
# explicitly exec this script or something like that.
-function singleuser ()
+function singleuser()
{
test $# -eq 0 || echo "$0: $*"
for try in ${fallback_shells}; do
@@ -54,6 +53,8 @@ function singleuser ()
exit 127
}
+# Print a newline.
+echo
# See whether pflocal is set up already, and do so if not (install case)
#
@@ -85,20 +86,23 @@ fi
# The first argument is the kernel file name; skip that.
shift
flags=
+single=
while [ $# -gt 0 ]; do
arg="$1"
shift
case "$arg" in
--*) ;;
+ init=*)
+ eval "${arg}"
+ ;;
*=*) ;;
-*)
flags="${flags}${arg#-}"
;;
- 'single'|'emergency') # Linux compat
- flags="${flags}s"
+ 'single')
+ single="-s"
;;
- 'fastboot')
- flags="${flags}f"
+ 'fastboot'|'emergency')
;;
esac
done
@@ -106,50 +110,18 @@ done
# Check boot flags.
case "$flags" in
*s*)
- rc=false # force single-user
- ;;
-*f*)
- rc="${RUNCOM}" # fastboot
- ;;
-*)
- rc="${RUNCOM} autoboot" # multi-user default
+ single="-s" # force single-user
;;
esac
-# Large infinite loop. If this script ever exits, init considers that
-# a serious bogosity and punts to a fallback single-user shell.
-# We handle here the normal transitions between single-user and multi-user.
-while : ; do
-
- # Run the rc script. As long as it exits nonzero, punt to single-user.
- # After the single-user shell exits, we will start over attempting to
- # run rc; but later invocations strip the `autoboot' argument.
- until $rc; do
- rc=${RUNCOM}
-
- # Run single-user shell and repeat as long as it dies with a signal.
- until ${SHELL} || test $? -lt 128; do
- :
- done
- done
-
- # Now we are officially ready for normal multi-user operation.
-
- # Trap certain signals and send them on to runttys. For this to work, we
- # must run it asynchronously and wait for it with the `wait' built-in.
- runttys_pid=0
- for sig in $runttys_sigs; do
- trap "kill -$sig \${runttys_pid}" $sig
- done
+# Start the default pager. It will bail if there is already one running.
+/hurd/mach-defpager
- # This program reads /etc/ttys and starts the programs it says to.
- ${RUNTTYS} &
- runttys_pid=$!
+# This is necessary to make stat / return the correct device ids.
+# Work around a race condition (probably in the root translator).
+for i in `seq 1 100000` ; do : ; done # XXX
- # Wait for runttys to die, meanwhile handling trapped signals.
- wait
+fsysopts / --update --readonly
- # Go back to the top of the infinite loop, as if booting single-user.
- rc=false
-
-done
+# Finally, start the actual init.
+exec ${init} ${single} -a