From 710d9bf74e012ee0c7db4d721dfe43d8d0cc5031 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Tue, 20 Oct 2009 03:01:36 +0000 Subject: [PATCH] --- README | 28 ++++--- init.mk | 118 ++++++++++++++-------------- mkfile | 2 +- src/mkinit | 204 +++++++++++++++++++------------------------------ src/mkinit.rc | 207 ++++++++++++++++++++++---------------------------- src/respawn | 6 +- src/service | 21 +++-- 7 files changed, 260 insertions(+), 326 deletions(-) diff --git a/README b/README index e64b844..a9d99e6 100644 --- a/README +++ b/README @@ -8,16 +8,16 @@ a few times as root before actually trying using init=/sbin/mkinit. Init scripts ------------ Init scripts take the form of mk rules contained in /etc/init.mk. Services are -started by calling the `start-' rule and stopped by calling -`stop-service'. Services should use `:Pservice -[ud]:' to determine whether the -script needs to be invoked. +started by calling the `-start' rule and stopped by calling +`-stop'. Services should use `:Pservice -[ud]:' to determine if the +script needs to be run and call `service -[UD]' afterwards. -For simple services consisting of a single start and stop command which no -dependencies other than boot, the default start-stop rules can be used by -setting `_start_cmd' and `_stop_cmd'. +For simple services consisting of a single start and stop command with no +dependencies other than `boot', the default start-stop rules can be used by +setting `-start_cmd' and `-stop_cmd'. -Dependencies are handled by adding `start-' to the rules list of -dependencies. When stopping a service, `stop-' should be added to the +Dependencies are handled by adding `-start' to the rules list of +dependencies. When stopping a service, `-stop' should be added to the list of dependencies for the dependency. @@ -28,10 +28,14 @@ README - This file mkfile - For [un]installing mkinit init.mk - Example database of init scripts -bin/mkinit - The actual init program it runs main loop and calls mk on - init.mk whenever services need to be started and stopped. -bin/respawn - Used to respawn gettys and such -bin/service - Set or query the state of a service +src: +mkinit - The actual init program it runs main loop and calls mk on init.mk + whenever services need to be started and stopped. +mkinit.rc - Rc variant of mkinit, unforuntly I can't get the IO redirects + working, it also leave zombies laying around.. +initctld.c - Reads /dev/initctl (Sysvinit compatability for halt,reboot,etc) +service - Set or query the state of a service +respawn - Used to respawn gettys and such # tw=80 diff --git a/init.mk b/init.mk index 8af525b..8ab2784 100644 --- a/init.mk +++ b/init.mk @@ -16,8 +16,8 @@ NPROC=10 # Runlevels user = alsa keymap polipo spam dbus -system = at cron hddtemp hostname hwclock i8k sshd swap syslog -bare = cpufreq fsclean getty qingy localhost modules mounts uevents utmp +system = at cron hddtemp hostname hwclock sshd swap syslog +bare = cpufreq fsclean getty qingy initctl localhost modules mounts uevents utmp default:V: user @@ -34,94 +34,99 @@ kexec:V: halt $P reboot -ndfk # Initial setup/shutdown for mkinit -boot:QVEPservice -u: / +boot:VEPservice -u: / echo Starting init $P mount -o remount,rw / # mount proc here to make bootchart happier $P mount -t proc proc /proc - rm -f /lib/mkinit/state/* + service -F service -U $target # Kill all process, then remount and sync halt:QVE: utmp-stop hwclock-stop alsa-stop - echo Stopping init - rm -f /lib/mkinit/state/* - echo TERMinating all processes - $P pkill -15 -vg0 + $P pkill -15 -vg0 >/dev/null >[2=1] for (i in 1 2 3 4 5) - $P pgrep -vg0 >/dev/null && $P sleep 1 - + $P pgrep -vg0 >/dev/null >[2=1] && $P sleep 1 echo KILLing all processes - $P pkill -9 -vg0 + $P pkill -9 -vg0 >/dev/null >[2=1] for (i in 1 2 3) - $P pgrep -vg0 >/dev/null && $P sleep 1 - + $P pgrep -vg0 >/dev/null >[2=1] && $P sleep 1 + service -F + echo Remounting read-only $P mount -o remount,ro / $P sync # Bare # ---- +# Listener for /dev/initctl, for shutdown(8) +initctl-start:VPservice -u: boot + fifo=/dev/initctl + if (! test -e $fifo) + $P mkfifo $fifo + { exec $P initctld $fifo | + while(line=`{line}) + $P mkinit $line >/dev/console >[2=1] + } & + service -U $target +initctl-stop_cmd=fuser -k /dev/initctl + # Proc, mtab, udev, fstab -mounts-start:QVPservice -u: boot - echo Starting mounts - $P cat /proc/mounts > /etc/mtab +mounts-start:VPservice -u: boot + $P cp /proc/mounts /etc/mtab $P udevd --daemon - $P mount -a + $P mount -a service -U $target # Load kernel modules -modules-start:QVEPservice -u: boot - echo Starting modules +modules-start:VEPservice -u: boot $P modprobe uvesafb service -U $target # Trigger udev uevents -uevents-start:QVEPservice -u: mounts-start - echo Starting uevents +uevents-start:VEPservice -u: mounts-start $P udevadm trigger $P udevadm settle '--timeout=10' service -U $target # Clean out /tmp and /var/run directories -fsclean-start:QVPservice -u: boot - echo Starting fsclean - $P rm -rf /tmp/* - $P rm -rf /var/run/* +fsclean-start:VPservice -u: boot + dirs=(/var/run /tmp) + $P mkdir -p /.old + $P mv $dirs /.old + $P mkdir -p $dirs + $P chmod 1777 /tmp + $P exec rm -rf /.old & service -U $target # Spawn gettys for tty[456] -getty-start:QVPservice -u: hostname-start utmp-start - echo Starting getty - $P respawn /sbin/agetty 38400 tty4 linux & - $P respawn /sbin/agetty 38400 tty5 linux & - $P respawn /sbin/agetty 38400 tty6 linux & +getty-start:VEPservice -u: hostname-start utmp-start + $P respawn /sbin/agetty 38400 tty4 linux + $P respawn /sbin/agetty 38400 tty5 linux + $P respawn /sbin/agetty 38400 tty6 linux service -U $target -getty-stop_cmd=pkill agetty +getty-stop_cmd=fuser -k /dev/tty4 /dev/tty5 /dev/tty6 # Spawn qingys for tty[23] -qingy-start:QVPservice -u: hostname-start utmp-start modules-start uevents-start - echo Starting qingy - $P respawn /sbin/qingy tty2 & - $P respawn /sbin/qingy tty3 & +qingy-start:VEPservice -u: hostname-start utmp-start modules-start uevents-start + $P respawn /sbin/qingy tty2 + $P respawn /sbin/qingy tty3 service -U $target -getty-stop_cmd=pkill qingy +qingy-stop_cmd=fuser -k /dev/tty2 /dev/tty3 # Login records -utmp-start:QVPservice -u: fsclean-start - echo Starting utmp +utmp-start:VPservice -u: fsclean-start for (i in /var/run/utmp /var/log/wtmp) { - echo -n > $i - chgrp utmp $i - chmod 0664 $i + $P eval 'echo -n > $i' + $P chgrp utmp $i + $P chmod 0664 $i } service -U $target utmp-stop_cmd=halt -w # CPU freq -cpufreq-start:QVPservice -u: uevents-start - echo Starting cpufreq - cpufreq-set -g ondemand +cpufreq-start:VPservice -u: uevents-start + $P cpufreq-set -g ondemand service -U $target # Keymap (us-cc = us with ctrl-capslock switched) @@ -152,14 +157,12 @@ hwclock-stop_cmd=hwclock --systohc --utc swap-start_cmd=swapon -a swap-stop_cmd=swapoff -a -syslog-start:QVPservice -u: mounts-start - echo Starting syslog; +syslog-start:VPservice -u: mounts-start $P syslog-ng service -U $target syslog-stop_cmd=pkill syslog -hddtemp-start:QVPservice -u: localhost-start - echo Starting hddtemp +hddtemp-start:VPservice -u: localhost-start $P hddtemp -d -l 127.0.0.1 /dev/sda service -U $target hddtemp-stop_cmd=pkill hddtemp @@ -173,21 +176,18 @@ alsa-stop_cmd=alsactl store sshd-start_cmd=/usr/sbin/sshd sshd-stop_cmd=pkill sshd -dbus-start:QVPservice -u: fsclean-start localhost-start - echo Starting dbus +dbus-start:VPservice -u: fsclean-start localhost-start $P mkdir -p /var/run/dbus $P /usr/bin/dbus-daemon --system service -U $target dbus-stop_cmd=pkill dbus-daemon -spam-start:QVPservice -u: localhost-start - echo Starting spam +spam-start:VPservice -u: localhost-start $P spamd -d service -U $target spam-stop_cmd=pkill spamd -polipo-start:QVPservice -u: localhost-start - echo Starting poliop +polipo-start:VPservice -u: localhost-start $P polipo service -U $target polipo-stop_cmd=pkill polipo @@ -195,22 +195,20 @@ polipo-stop_cmd=pkill polipo # Library # ------- -%-start:QVPservice -u: boot +%-start:VPservice -u: boot if (~ $#($stem^-start_cmd) 0) exit 0 - echo Starting $stem $P $($stem^-start_cmd) service -U $target -%-stop:QVPservice -d: / +%-stop:VPservice -d: / if (~ $#($stem^-stop_cmd) 0) exit 0 - echo Stopping $stem $P $($stem^-stop_cmd) service -D $target -%-zap:QVPservice -d: / +%-zap:VPservice -d: / service -D $target -%-status:QV: +%-status:V: service -q $target diff --git a/mkfile b/mkfile index 8a60b60..30fa12b 100644 --- a/mkfile +++ b/mkfile @@ -24,6 +24,6 @@ uninstall:VE: rmdir /lib/mkinit/state/ rmdir /lib/mkinit/ -<../mkcommon + Execute mk rule' + echo ' boot Execute boot-up procedures' + echo ' halt Execute shutdown procedures' + echo ' reload Re-execute init process' + echo ' mk Execute mk rule' echo ' start|stop|restart|zap|status ' - echo ' Start,stop,restart,zap or query status of service' - echo ' eval Execute command in mkinit process' + echo ' Start,stop,restart,zap or query status of service' + echo ' eval Execute command in mkinit process' exit } +# Handle arguments +function doopts { + TMP=`getopt -n "$0" -o htd -l help,test,daemon -- "$@"` + [ $? != 0 ] && + usage + eval set -- "$TMP" + + # Parse options + while [ ! "$1" == "--" ]; do + case "$1" in + -h|--help ) usage ;; + -t|--test ) TESTING=true ;; + -d|--daemon ) DAEMON=true ;; + esac + shift + done + shift + if [ "$*" ]; then + COMMAND=($@) + fi + + # Debugging output + if $TESTING; then + echo 'Options' 1>&2 + echo ' TESTING:' $TESTING 1>&2 + echo ' DAEMON:' $DAEMON 1>&2 + echo ' COMMAND:' $COMMAND 1>&2 + fi +} + # Run mk on the init scripts function runamk { - $TEST && - export P=true + if $TESTING; then + export P=echo + export MKINIT_STATE=/tmp/mkinit_state + mkdir -p $MKINIT_STATE + fi /usr/lib/plan9/bin/mk \ -f /etc/init.mk \ -i -k "$@" @@ -44,135 +81,54 @@ function runamk { function process { cmd=$1 shift - arg=$* - exec 1>/dev/console + echo mkinit -- running "$cmd" "$@" case "$cmd" in boot ) - echo - echo mkinit -- booting - runamk -a "$arg" + runamk -a "$@" ;; restart ) - if [ "$arg" ]; then - echo mkinit -- restarting $arg - runamk "$arg"-stop - runamk "$arg"-start + if [ "$*" ]; then + runamk "$@"-stop || + runamk "$@"-zap + runamk "$@"-start fi ;; start|stop|zap|status ) - if [ "$arg" ]; then - echo mkinit -- ${cmd}ing $arg - runamk "$arg-$cmd" - fi - ;; - mk|runlevel ) - if [ "$arg" ]; then - [ "$cmd" = mk ] && - echo mkinit -- running mk cmd [$arg] - [ "$cmd" = runlevel ] && - echo mkinit -- entering runlevel $arg - runamk "$arg" + if [ "$*" ]; then + runamk "$@-$cmd" fi ;; reload ) - echo mkinit -- ${cmd}ing - $TEST && + $TESTING && opt=-t exec $0 -r $opt ;; + poweroff|reboot|kexec|halt) + ( runamk "$cmd" "$@" & ) + ;; eval ) - eval $arg + eval "$@" ;; ?* ) - echo mkinit -- unknown command [$cmd] [$arg] + runamk "$cmd" "$@" ;; esac } -# Telinit -if [ $$ != 1 -a $1 != "-t" ]; then - echo "$@" > $FIFO - exit -fi - -# Handle arguments -TMP=`getopt -n "$0" \ - --options hrt \ - --longoptions help,reload,test \ - -- "$@"` -[ $? != 0 ] && - usage -eval set -- "$TMP" -while [ ! "$1" == "--" ]; do - $TEST && - echo '$1=' $1 - case "$1" in - -h|--help ) - usage - ;; - -r|--reload ) - RELOAD=true - ;; - -t|--test ) - TEST=true - FIFO=/tmp/pipe - INITCTL=/tmp/initctl - trap "pkill -HUP -P $$" EXIT - ;; - esac - shift -done -shift; cmd=$1 -shift; arg=$* +# Process arguments +doopts "$@" -# Debugging output -if $TEST; then - echo 'Options' - echo ' test:' $TEST - echo ' reload:' $RELOAD - echo ' cmd:' $cmd - echo ' arg:' $arg -fi - -# Create fifos if they don't exist -test ! -e $FIFO && - mkfifo $FIFO -test ! -e $INITCTL && - mkfifo $INITCTL - -# Initial boot-up -process $cmd $arg - -# Fork listeners -if ! $RELOAD; then - # Fork /dev/initctl listener - ( exec 0<&- 1<&- 2<&- - initctld $INITCTL | - while read line; do - echo $line > $FIFO - done ) & - - # Fork console listener - # Readline uses stdin,stderr - ( exec 1<&-; - while true; do - while read -e -p "mkinit> " line; do - echo $line > $FIFO - history -s $line - done - $TEST && break - exec 0/dev/console - echo "Respawning on /dev/console.." >&2 - sleep 1 - done) <&0 & - - # Close stdin, stderr - exec 0<&- 2<&- -fi +# Run whatever was requested +process "${COMMAND[@]}" -# Main loop -while true; do - while read line; do +# Fork console listener +while $DAEMON; do + while read -ep "mkinit> " line; do process $line - done < $FIFO + history -s $line + done + $TESTING && exit + exec 0/dev/console 2>&1 + echo "Respawning on /dev/console.." + sleep 1 done diff --git a/src/mkinit.rc b/src/mkinit.rc index 4a6116e..2a43fd0 100755 --- a/src/mkinit.rc +++ b/src/mkinit.rc @@ -4,42 +4,80 @@ # See ../COPYING for terms # GLobals -TEST=false -RELOAD=false -FIFO=/lib/mkinit/cmd -INITCTL=/dev/initctl -PATH=/lib/mkinit/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/lib/plan9/bin +COMMAND=boot +TESTING=false +if(~ $pid 1) + DAEMON=true +if not + DAEMON=false + +PATH=/lib/mkinit/bin:/bin:/sbin:/usr/bin:/usr/sbin # Functions fn usage { echo 'usage: '$0' [options] [command]' echo echo 'Options:' - echo ' -h,--help Print usage information' - echo ' -r,--relaod Prevent spawning listeners when reloading' - echo ' -t,--test Fake all commands' - echo + echo ' -h,--help Print usage information' + echo ' -t,--test Fake all commands' + echo ' -d,--daemon For spawning stdin listener' + echo '' echo 'Command:' - echo ' boot Execute boot-up procedures' - echo ' halt Execute shutdown procedures' - echo ' reload Re-execute init process' - echo ' mk Execute mk rule' + echo ' boot Execute boot-up procedures' + echo ' halt Execute shutdown procedures' + echo ' reload Re-execute init process' + echo ' mk Execute mk rule' echo ' start|stop|restart|zap|status ' - echo ' Start,stop,restart,zap or query status of service' - echo ' eval Execute command in mkinit process' + echo ' Start,stop,restart,zap or query status of service' + echo ' eval Execute command in mkinit process' exit } +# Handle arguments +fn doopts { + tmp=`{getopt -n $0 -o htd -l help,test,daemon -- $*} + if(~ $status 0) + usage + eval '*=('$"tmp')' + + # Parse options + while(! ~ $1 --){ + switch($1){ + case -h --help + usage + case -t --test + TESTING=true + case -d --daemon + DAEMON=true + } + shift + } + shift + if(! ~ $#* 0) + COMMAND=$* + + # Debugging output + if($TESTING){ + echo 'Options' >[2=1] + echo ' TESTING:' $TESTING >[2=1] + echo ' DAEMON:' $DAEMON >[2=1] + echo ' COMMAND:' $COMMAND >[2=1] + } +} + # Fake readline fn prompt { echo -n $1 >[1=2] - read + line } # Run mk on the init scripts fn runamk { - if ($TEST) - P=true + if($TESTING){ + P=echo + MKINIT_STATE=/tmp/mkinit_state + mkdir -p $MKINIT_STATE + } /usr/lib/plan9/bin/mk \ -f /etc/init.mk \ -i -k $* @@ -49,126 +87,59 @@ fn runamk { fn process { cmd=$1 shift - arg=$* + echo mkinit -- running "$"cmd" "$"*" switch($cmd){ case boot - echo - echo mkinit -- booting - runamk -a $arg + runamk -a $* case restart if(~ $arg ?*){ - echo mkinit -- restarting $arg - runamk $arg-stop - runamk $arg-start + if (! runamk $"*-stop) + runamk $"*-zap + runamk $"*-start } case start stop zap status - if(~ $arg ?*){ - echo mkinit -- $cmd^ing $arg - runamk $arg-$cmd - } - - case mk runlevel - if(~ $arg ?*){ - if (~ $cmd mk) - echo mkinit -- running mk cmd [$arg] - if (~ $cmd runlevel) - echo mkinit -- entering runlevel $arg - runamk $arg - } + if(~ $arg ?*) + runamk $"*-$cmd case reload - echo mkinit -- $cmd^ing - if($TEST) + if($TESTING) opt=-t exec $0 -r $opt - case eval - eval $arg + case poweroff reboot kexec halt + { runamk $cmd $* & } + case eval + eval $* + case ?* - echo mkinit -- unknown command [$cmd] [$arg] + runamk $cmd $* + } } -# Handle arguments -tmp=`{getopt -n $0 \ - --options hrt \ - --longoptions help,reload,test \ - -- $*} -if(~ $status ?*) - usage -eval '*=('$"tmp')' -while(! ~ $1 --){ - if ($TEST) - echo '$1=' $1 - switch($1){ - case -h --help - usage - - case -r --reload - RELOAD=true +# Process arguments +doopts $* - case -t --test - TEST=true - FIFO=/tmp/pipe - INITCTL=/tmp/initctl - fn sigint { pkill -HUP -P $pid } +# Run whatever was requested +process $COMMAND - } - shift -} -shift; cmd=$1 -shift; arg=$* - -# Debugging output -if($TEST){ - echo 'Options' - echo ' test:' $TEST - echo ' reload:' $RELOAD - echo ' cmd:' $cmd - echo ' arg:' $arg +# Fork console listener +fn listen1 { + while(line=`{prompt 'mkinit> '}) + process $line } - -# Create fifos if they don't exist -if(test ! -e $FIFO) - mkfifo $FIFO -if(test ! -e $INITCTL) - mkfifo $INITCTL - -# Initial boot-up -process $cmd $arg - -# Fork listeners -if(!$RELOAD){ - # Fork /dev/initctl listener - { initctld $INITCTL | - while(line=`{read}) - echo $line > $FIFO - } <[0=] >[1=] >[2=] & - - # Fork console listener - # Readline uses stdin,stderr - if($TEST) { - tty=`{tty} - { while(line=`{prompt 'mkinit> '}) { - echo line: $line - echo $line > $FIFO - } } <$"tty >[1=2] & - } - if not { - { while(true){ - while(line=`{prompt 'mkinit> '}) - echo $line > $FIFO - echo Respawning on /dev/console.. - sleep 1 - } } /dev/console >[1=2] +if($DAEMON){ + listen1 + if ($TESTING) + exit + while($DAEMON) { + echo Respawning on /dev/console.. + sleep 1 + listen1 <[0]/dev/console \ + >[1]/dev/console \ + >[2=1] } } - -# Main loop -while(true) - { while(line=`{read}) - process $line - } < $FIFO >[2=1] diff --git a/src/respawn b/src/respawn index 11a677a..d41ff63 100755 --- a/src/respawn +++ b/src/respawn @@ -3,8 +3,6 @@ # Copyright (C) 2009 Andy Spencer # See ../COPYING for terms -while(true){ - $* - echo Process $! died, waiting 1 second to respawn +{ while($*){ sleep 1 -} +} } <[0=] >[1=] >[2=] & diff --git a/src/service b/src/service index b5ca605..97280b3 100755 --- a/src/service +++ b/src/service @@ -10,31 +10,38 @@ fn usage { echo ' -d,--is-down Test is service is stopped' echo ' -U,--set-up Set service to running' echo ' -D,--set-down Set service to stopped' + echo ' -F,--flush Resest all services to stopped' echo ' -q,--query Print the state of a service' exit } # Main -STATE=/lib/mkinit/state +state=/lib/mkinit/state +if (~ $MKINIT_STATE ?*) + state=$MKINIT_STATE action=$1 service=`{echo $2 | sed s/-.*//} -if(~ $action '' || ~ $service '') +if(~ $action '') + usage +if(! ~ $action -F && ~ $service '') usage switch($1){ case -u --is-up - test -e $STATE/$service + test -e $state/$service case -d --is-down - test ! -e $STATE/$service + test ! -e $state/$service case -U --set-up - touch $STATE/$service + touch $state/$service case -D --set-down - rm $STATE/$service + rm -f $state/$service +case -F --flush + rm -f $state/* case -q --query echo -n Service "$service" is - test -e $STATE/$service \ + test -e $state/$service \ && echo ' running' \ || echo ' stopped' case * -- 2.43.2