summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolás Reynolds <fauno@kiwwwi.com.ar>2011-09-08 01:02:06 -0300
committerNicolás Reynolds <fauno@kiwwwi.com.ar>2011-09-08 01:02:06 -0300
commitede246d73091a7b733ae56819fc7296e18aa4c31 (patch)
treed9913f474acc8d023605c90ba088d1b84ef3275a
parente70da9aade583714d399adb35573aecbea84f5f7 (diff)
parent7cccf54fcb9fab459590b8b6fd5c51f2088e3b2e (diff)
Merge branch 'master' of git://projects.archlinux.org/initscripts2011.09.8
Conflicts: functions
-rw-r--r--Makefile18
-rw-r--r--PKGBUILD2
-rwxr-xr-xarch-tmpfiles250
-rw-r--r--bash-completion22
-rw-r--r--functions341
-rw-r--r--locale.sh3
-rwxr-xr-xnetfs31
-rwxr-xr-xnetwork34
-rw-r--r--rc.conf8
-rwxr-xr-xrc.d19
-rwxr-xr-xrc.multi14
-rwxr-xr-xrc.shutdown151
-rwxr-xr-xrc.single56
-rwxr-xr-xrc.sysinit305
-rw-r--r--tmpfiles.conf20
-rw-r--r--zsh-completion5
16 files changed, 821 insertions, 458 deletions
diff --git a/Makefile b/Makefile
index c568b13..4916387 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,16 @@
VER := $(shell git describe)
-DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/logrotate.d /sbin /etc/bash_completion.d /usr/share/zsh/site-functions
+DIRS := \
+ /etc/rc.d \
+ /etc/conf.d \
+ /etc/rc.d/functions.d \
+ /etc/logrotate.d \
+ /etc/profile.d \
+ /usr/sbin \
+ /etc/tmpfiles.d \
+ /usr/lib/tmpfiles.d \
+ /usr/lib/initscripts \
+ /etc/bash_completion.d \
+ /usr/share/zsh/site-functions
minilogd: minilogd.o
@@ -12,7 +23,10 @@ install: minilogd installdirs
install -m644 -t $(DESTDIR)/etc/logrotate.d bootlog
install -m644 -t $(DESTDIR)/etc/rc.d functions
install -m755 -t $(DESTDIR)/etc/rc.d hwclock network netfs
- install -m755 -t $(DESTDIR)/sbin minilogd rc.d
+ install -m755 -t $(DESTDIR)/etc/profile.d locale.sh
+ install -m755 -t $(DESTDIR)/usr/sbin minilogd rc.d
+ install -m755 -t $(DESTDIR)/usr/lib/initscripts arch-tmpfiles
+ install -m644 tmpfiles.conf $(DESTDIR)/usr/lib/tmpfiles.d/arch.conf
install -m644 -T bash-completion $(DESTDIR)/etc/bash_completion.d/rc.d
install -m644 -T zsh-completion $(DESTDIR)/usr/share/zsh/site-functions/_rc.d
diff --git a/PKGBUILD b/PKGBUILD
index dcf007b..1029b32 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,6 +1,6 @@
pkgname=initscripts-git
pkgver=$(date +%s)
-pkgrel=$(git log --pretty=format:%h |head -n 1)
+pkgrel=$(git log -1 --pretty=format:%h)
pkgdesc="System initialization/bootup scripts"
arch=('i686' 'x86_64')
url="http://parabolagnulinux.org"
diff --git a/arch-tmpfiles b/arch-tmpfiles
new file mode 100755
index 0000000..f133a40
--- /dev/null
+++ b/arch-tmpfiles
@@ -0,0 +1,250 @@
+#!/bin/bash
+#
+# /usr/lib/initscripts/arch-tmpfiles
+#
+# Control creation, deletion, and cleaning of volatile and temporary files
+#
+
+warninvalid() {
+ printf "arch-tmpfiles: ignoring invalid entry on line %d of \`%s'\n" "$LINENUM" "$FILE"
+ (( ++error ))
+} >&2
+
+checkparams() {
+ local parmreq=$1; shift
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ # parmcount must be >= parmreq
+ if (( $# < parmreq )); then
+ return 1
+ fi
+
+ # mode must be valid octal and 3 or 4 digits
+ if [[ $mode && ! $mode =~ ^[0-7]{3,4}$ ]]; then
+ return 1
+ fi
+
+ # uid must be numeric or a valid user name
+ if [[ $uid && $uid != +([[:digit:]]) ]] && ! getent passwd "$uid" >/dev/null; then
+ return 1
+ fi
+
+ # gid must be numeric or a valid group name
+ if [[ $gid && $gid != +([[:digit:]]) ]] && ! getent group "$gid" >/dev/null; then
+ return 1
+ fi
+
+ return 0
+}
+
+_f() {
+ # Create a file if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ (( CREATE )) || return 0
+
+ if ! checkparams 4 "$@"; then
+ warninvalid
+ return
+ fi
+
+ if [[ ! -e $path ]]; then
+ install -m"$mode" -o"$uid" -g"$gid" /dev/null "$path"
+ fi
+}
+
+_F() {
+ # Create or truncate a file
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ (( CREATE )) || return 0
+
+ if ! checkparams 4 "$@"; then
+ warninvalid
+ return
+ fi
+
+ install -m"$mode" -o"$uid" -g"$gid" /dev/null "$path"
+}
+
+_d() {
+ # Create a directory if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ (( CREATE )) || return 0
+
+ if ! checkparams 4 "$@"; then
+ warninvalid
+ return
+ fi
+
+ if [[ ! -d "$path" ]]; then
+ install -d -m"$mode" -o"$uid" -g"$gid" "$path"
+ fi
+}
+
+_D() {
+ # Create or empty a directory
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ (( CREATE )) || return 0
+
+ if ! checkparams 4 "$@"; then
+ warninvalid
+ return
+ fi
+
+ if [[ -d $path ]]; then
+ find "$path" -mindepth 1 -maxdepth 1 -xdev -print0 | xargs -r0 rm -rf
+ fi
+ install -d -m"$mode" -o"$uid" -g"$gid" "$path"
+}
+
+_p() {
+ # Create a named pipe (FIFO) if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ (( CREATE )) || return 0
+
+ if ! checkparams 4 "$@"; then
+ warninvalid
+ return
+ fi
+
+ if [[ ! -p "$path" ]]; then
+ mkfifo -m$mode "$path"
+ chown "$uid:$gid" "$path"
+ fi
+}
+
+_x() {
+ # Ignore a path during cleaning. Use this type to exclude paths from clean-up as
+ # controlled with the Age parameter. Note that lines of this type do not
+ # influence the effect of r or R lines. Lines of this type accept shell-style
+ # globs in place of of normal path names.
+ :
+ # XXX: we don't implement this
+}
+
+_r() {
+ # Remove a file or directory if it exists. This may not be used to remove
+ # non-empty directories, use R for that. Lines of this type accept shell-style
+ # globs in place of normal path names.
+ local path
+ local -a paths=($1)
+
+ (( REMOVE )) || return 0
+
+ if ! checkparams 1 "$@"; then
+ warninvalid
+ return
+ fi
+
+ for path in "${paths[@]}"; do
+ if [[ -f $path ]]; then
+ rm -f "$path"
+ elif [[ -d $path ]]; then
+ rmdir "$path"
+ fi
+ done
+}
+
+_R() {
+ # Recursively remove a path and all its subdirectories (if it is a directory).
+ # Lines of this type accept shell-style globs in place of normal path names.
+ local path
+ local -a paths=($1)
+
+ (( REMOVE )) || return 0
+
+ if ! checkparams 1 "$@"; then
+ warninvalid
+ return
+ fi
+
+ for path in "${paths[@]}"; do
+ [[ -d $path ]] && rm -rf --one-file-system "$path"
+ done
+}
+
+shopt -s nullglob
+
+declare -i CREATE=0 REMOVE=0 CLEAN=0 error=0 LINENO=0
+declare FILE=
+declare -A fragments
+declare -a tmpfiles_d=(
+ /usr/lib/tmpfiles.d/*.conf
+ /etc/tmpfiles.d/*.conf
+ /run/tmpfiles.d/*.conf
+)
+
+while (( $# )); do
+ case $1 in
+ --create) CREATE=1 ;;
+ --remove) REMOVE=1 ;;
+ esac
+ shift
+done
+
+if (( !(CREATE + REMOVE) )); then
+ printf 'usage: %s [--create] [--remove]\n' "${0##*/}"
+ exit 1
+fi
+
+# directories declared later in the tmpfiles_d array will override earlier
+# directories, on a per file basis.
+# Example: `/etc/tmpfiles.d/foo.conf' supersedes `/usr/lib/tmpfiles.d/foo.conf'.
+for path in "${tmpfiles_d[@]}"; do
+ [[ -f $path ]] && fragments[${path##*/}]=${path%/*}
+done
+
+# catch errors in functions so we can exit with something meaningful
+set -E
+trap '(( ++error ))' ERR
+
+# loop through the gathered fragments, sorted globally by filename.
+# `/run/tmpfiles/foo.conf' will always be read after `/etc/tmpfiles.d/bar.conf'
+while read -d '' fragment; do
+ LINENUM=0
+
+ printf -v FILE '%s/%s' "${fragments[$fragment]}" "$fragment"
+
+ ### FILE FORMAT ###
+ # XXX: We ignore the final 'Age' parameter
+ # 0 1 2 3 4 5
+ # Type Path Mode UID GID Age
+ # d /run/user 0755 root root 10d
+
+ # omit read's -r flag to honor escapes here, so that whitespace can be
+ # escaped for paths. We will _not_ honor quoted paths.
+ while read -a line; do
+ (( ++LINENUM ))
+
+ # skip over comments and empty lines
+ if (( ! ${#line[*]} )) || [[ ${line[0]:0:1} = '#' ]]; then
+ continue
+ fi
+
+ # whine about invalid entries
+ if ! type -t _${line[0]} >/dev/null; then
+ warninvalid
+ continue
+ fi
+
+ # fall back on defaults when parameters are passed as '-'
+ if [[ ${line[2]} = '-' ]]; then
+ case ${line[0]} in
+ p|f|F) line[2]=0644 ;;
+ d|D) line[2]=0755 ;;
+ esac
+ fi
+ [[ ${line[3]} = '-' ]] && line[3]=0
+ [[ ${line[4]} = '-' ]] && line[4]=0
+
+ _${line[0]} "${line[@]:1}"
+ done <"$FILE"
+done < <(printf '%s\0' "${!fragments[@]}" | sort -z)
+
+exit $error
+
+# vim: set ts=2 sw=2 noet:
diff --git a/bash-completion b/bash-completion
index 5151972..d78484e 100644
--- a/bash-completion
+++ b/bash-completion
@@ -1,22 +1,24 @@
# rc.d bash completion by Seblu <seblu@seblu.net>
-_rc.d ()
+_rc_d()
{
- local action="help list start stop reload restart"
- local cur="${COMP_WORDS[COMP_CWORD]}"
- local caction="${COMP_WORDS[1]}"
- if ((${COMP_CWORD} == 1)); then
+ local action cur prev
+ action="help list start stop reload restart"
+ _get_comp_words_by_ref cur prev
+ if ((COMP_CWORD == 1)); then
COMPREPLY=($(compgen -W "${action}" -- "$cur"))
- elif [[ "$caction" =~ help|list ]]; then
+ elif [[ "$prev" == help ]]; then
COMPREPLY=()
- elif [[ "$caction" == start ]]; then
+ elif [[ "$prev" == list ]]; then
+ ((COMP_CWORD == 2)) && COMPREPLY=($(compgen -W "started stopped" -- "$cur")) || COMPREPLY=()
+ elif [[ "$prev" == start ]]; then
COMPREPLY=($(comm -23 <(cd /etc/rc.d && compgen -f -X 'functions*' "$cur"|sort) <(cd /run/daemons/ && compgen -f "$cur"|sort)))
- elif [[ "$caction" =~ stop|restart|reload ]]; then
+ elif [[ "$prev" =~ stop|restart|reload ]]; then
COMPREPLY=($(cd /run/daemons/ && compgen -f "$cur"|sort))
- elif ((${COMP_CWORD} > 1)); then
+ elif ((COMP_CWORD > 1)); then
COMPREPLY=($(cd /etc/rc.d && compgen -f -X 'functions*' "$cur"|sort))
fi
}
-complete -F _rc.d rc.d
+complete -F _rc_d rc.d
# vim: set ts=2 sw=2 ft=sh noet:
diff --git a/functions b/functions
index d9e6f89..2cbf01e 100644
--- a/functions
+++ b/functions
@@ -2,32 +2,56 @@
# initscripts functions
#
-# width:
+# sanitize PATH (will be overridden later when /etc/profile is sourced, but is useful for UDev)
+export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-STAT_COL=80
-if [[ ! -t 1 ]]; then
- USECOLOR=""
-elif [[ -t 0 ]]; then
- # stty will fail when stdin isn't a terminal
- STAT_COL="$(/bin/stty size)"
- # stty gives "rows cols"; strip the rows number, we just want columns
- STAT_COL="${STAT_COL##* }"
-elif /bin/tput cols &>/dev/null; then
- # is /usr/share/terminfo already mounted, and TERM recognized?
- STAT_COL=$(/bin/tput cols)
+if [[ $1 == "start" ]]; then
+ if [[ $STARTING ]]; then
+ echo "A daemon is starting another daemon, this is unlikely to work as intended."
+ else
+ export STARTING=1
+ fi
fi
-if ((STAT_COL==0)); then
- # if output was 0 (serial console), set default width to 80
+
+# width:
+calc_columns () {
STAT_COL=80
- USECOLOR=""
-fi
+ if [[ ! -t 1 ]]; then
+ USECOLOR=""
+ elif [[ -t 0 ]]; then
+ # stty will fail when stdin isn't a terminal
+ STAT_COL=$(stty size)
+ # stty gives "rows cols"; strip the rows number, we just want columns
+ STAT_COL=${STAT_COL##* }
+ elif tput cols &>/dev/null; then
+ # is /usr/share/terminfo already mounted, and TERM recognized?
+ STAT_COL=$(tput cols)
+ fi
+ if (( STAT_COL == 0 )); then
+ # if output was 0 (serial console), set default width to 80
+ STAT_COL=80
+ USECOLOR=""
+ fi
-# we use 13 characters for our own stuff
-STAT_COL=$(($STAT_COL - 13))
+ # we use 13 characters for our own stuff
+ STAT_COL=$(( STAT_COL - 13 ))
+
+ if [[ -t 1 ]]; then
+ SAVE_POSITION="\e[s"
+ RESTORE_POSITION="\e[u"
+ DEL_TEXT="\e[$(( STAT_COL + 4 ))G"
+ else
+ SAVE_POSITION=""
+ RESTORE_POSITION=""
+ DEL_TEXT=""
+ fi
+}
+
+calc_columns
# disable colors on broken terminals
-TERM_COLORS="$(/bin/tput colors 2>/dev/null)"
-if (($? != 3)); then
+TERM_COLORS=$(tput colors 2>/dev/null)
+if (( $? != 3 )); then
case $TERM_COLORS in
*[!0-9]*) USECOLOR="";;
[0-7]) USECOLOR="";;
@@ -43,25 +67,25 @@ unset TZ
unset LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY \
LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE \
LC_MEASUREMENT LC_IDENTIFICATION LC_ALL
-if [[ $DAEMON_LOCALE =~ yes|YES && -n $LOCALE ]]; then
+if [[ $DAEMON_LOCALE = [yY][eE][sS] && $LOCALE ]]; then
export LANG="${LOCALE}"
else
export LANG=C
fi
# set colors
-if [[ $USECOLOR =~ yes|YES ]]; then
- if /bin/tput setaf 0 &>/dev/null; then
- C_CLEAR="$(tput sgr0)" # clear text
- C_MAIN="${C_CLEAR}$(/bin/tput bold)" # main text
- C_OTHER="${C_MAIN}$(/bin/tput setaf 5)" # prefix & brackets
- C_SEPARATOR="${C_MAIN}$(/bin/tput setaf 0)" # separator
- C_BUSY="${C_CLEAR}$(/bin/tput setaf 6)" # busy
- C_FAIL="${C_MAIN}$(/bin/tput setaf 1)" # failed
- C_DONE="${C_MAIN}" # completed
- C_BKGD="${C_MAIN}$(/bin/tput setaf 5)" # backgrounded
- C_H1="${C_MAIN}" # highlight text 1
- C_H2="${C_MAIN}$(/bin/tput setaf 6)" # highlight text 2
+if [[ $USECOLOR = [yY][eE][sS] ]]; then
+ if tput setaf 0 &>/dev/null; then
+ C_CLEAR=$(tput sgr0) # clear text
+ C_MAIN=${C_CLEAR}$(tput bold) # main text
+ C_OTHER=${C_MAIN}$(tput setaf 5) # prefix & brackets
+ C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator
+ C_BUSY=${C_CLEAR}$(tput setaf 6) # busy
+ C_FAIL=${C_MAIN}$(tput setaf 1) # failed
+ C_DONE=${C_MAIN} # completed
+ C_BKGD=${C_MAIN}$(tput setaf 5) # backgrounded
+ C_H1=${C_MAIN} # highlight text 1
+ C_H2=${C_MAIN}$(tput setaf 6) # highlight text 2
else
C_CLEAR="\e[m" # clear text
C_MAIN="\e[;1m" # main text
@@ -69,23 +93,13 @@ if [[ $USECOLOR =~ yes|YES ]]; then
C_SEPARATOR="\e[1;30m" # separator
C_BUSY="\e[;36m" # busy
C_FAIL="\e[1;31m" # failed
- C_DONE="${C_MAIN}" # completed
+ C_DONE=${C_MAIN} # completed
C_BKGD="\e[1;35m" # backgrounded
- C_H1="${C_MAIN}" # highlight text 1
+ C_H1=${C_MAIN} # highlight text 1
C_H2="\e[1;36m" # highlight text 2
fi
fi
-if [[ -t 1 ]]; then
- SAVE_POSITION="\e[s"
- RESTORE_POSITION="\e[u"
- DEL_TEXT="\e[$(($STAT_COL+4))G"
-else
- SAVE_POSITION=""
- RESTORE_POSITION=""
- DEL_TEXT=""
-fi
-
# prefixes:
PREFIX_REG="::"
@@ -142,24 +156,20 @@ stat_die() {
status() {
stat_busy "$1"
shift
- if "$@" >/dev/null 2>&1; then
- stat_done
- return 0
- fi
- stat_fail
- return 1
+ "$@" &>/dev/null
+ local ret=$?
+ (( ret == 0 )) && stat_done || stat_fail
+ return $ret
}
# usage : in_array( $needle, $haystack )
# return : 0 - found
# 1 - not found
-# Copied from makepkg
in_array() {
- [[ $2 ]] || return 1
local needle=$1; shift
local item
- for item in "$@"; do
- [[ ${item#@} = $needle ]] && return 0
+ for item; do
+ [[ $item = "${needle}" ]] && return 0
done
return 1 # Not Found
}
@@ -167,12 +177,12 @@ in_array() {
# daemons:
add_daemon() {
- [[ -d /run/daemons ]] || /bin/mkdir -p /run/daemons
- > /run/daemons/"$1"
+ [[ -d /run/daemons ]] || mkdir -p /run/daemons
+ >| /run/daemons/"$1"
}
rm_daemon() {
- /bin/rm -f /run/daemons/"$1"
+ rm -f /run/daemons/"$1"
}
ck_daemon() {
@@ -186,9 +196,9 @@ have_daemon() {
# Check if $1 is started at boot
ck_autostart() {
- local d
- for d in "${DAEMONS[@]}"; do
- [[ "$1" = ${d#@} ]] && return 1
+ local daemon
+ for daemon in "${DAEMONS[@]}"; do
+ [[ $1 = "${daemon#@}" ]] && return 1
done
return 0
}
@@ -197,8 +207,11 @@ start_daemon() {
have_daemon "$1" && /etc/rc.d/"$1" start
}
+# Never use this function, it causes daemons to be stoped in the wrong order.
+# The only way to start a daemon at boot is to add it to the DAEMONS array.
ck_depends() {
- for daemon in "$@"; do
+ local daemon
+ for daemon; do
ck_daemon "$daemon" && start_daemon "$daemon"
done
}
@@ -224,11 +237,23 @@ status_stopped() {
}
ck_status() {
- if ! ck_daemon "$1"; then
- status_started
- else
- status_stopped
+ ! ck_daemon "$1" && status_started || status_stopped
+}
+
+# Return PID of $1
+get_pid() {
+ pidof -o %PPID $1 || return 1
+}
+
+# Check if PID-file $1 is still the active PID-file for command $2
+ck_pidfile() {
+ if [[ -f $1 ]]; then
+ local fpid ppid
+ read -r fpid <"$1"
+ ppid=$(get_pid "$2")
+ [[ $fpid = "${ppid}" ]] && return 0
fi
+ return 1
}
# PIDs to be omitted by killall5
@@ -238,52 +263,84 @@ add_omit_pids() {
omit_pids+=( $@ )
}
-
-kill_everything() {
- # $1 = where we are being called from.
- # This is used to determine which hooks to run.
+# Stop all daemons
+# This function should *never* ever perform any other actions beside calling stop_daemon()!
+# It might be used by a splash system etc. to get a list of daemons to be stopped.
+stop_all_daemons() {
# Find daemons NOT in the DAEMONS array. Shut these down first
+ local daemon
for daemon in /run/daemons/*; do
[[ -f $daemon ]] || continue
daemon=${daemon##*/}
- in_array "$daemon" "${DAEMONS[@]}" || stop_daemon "$daemon"
+ ck_autostart "$daemon" && stop_daemon "$daemon"
done
# Shutdown daemons in reverse order
- for ((i=${#DAEMONS[@]}-1; i>=0; i--)); do
- [[ ${DAEMONS[$i]:0:1} = '!' ]] && continue
- ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@}
+ local i daemon
+ for (( i=${#DAEMONS[@]}-1; i>=0; i-- )); do
+ [[ ${DAEMONS[i]} = '!'* ]] && continue
+ daemon=${DAEMONS[i]#@}
+ ck_daemon "$daemon" || stop_daemon "$daemon"
done
+}
+kill_all() {
# Terminate all processes
+ # and wait until killall5 reports all done or timeout
+ # Unfortunately killall5 does not support the 0 signal, so just
+ # use SIGCONT for checking (which should be ignored).
stat_busy "Sending SIGTERM To Processes"
- run_hook "$1_prekillall"
- local pid k5args=""
- for pid in ${omit_pids[@]}; do
- k5args+=" -o $pid"
- done
- /sbin/killall5 -15 $k5args &> /dev/null
- /bin/sleep 5
+ local i
+ killall5 -15 ${omit_pids[@]/#/-o } &>/dev/null
+ for (( i=0; i<20 && $?!=2; i++ )); do
+ sleep .25 # 1/4 second
+ killall5 -18 ${omit_pids[@]/#/-o } &>/dev/null
+ done
stat_done
stat_busy "Sending SIGKILL To Processes"
- /sbin/killall5 -9 $k5args &> /dev/null
- /bin/sleep 1
+ local i
+ killall5 -9 ${omit_pids[@]/#/-o } &>/dev/null
+ for (( i=0; i<4 && $?!=2; i++ )); do
+ sleep .25 # 1/4 second
+ killall5 -18 ${omit_pids[@]/#/-o } &>/dev/null
+ done
stat_done
+}
+
+# Start/trigger UDev, load MODULES and settle UDev
+udevd_modprobe() {
+ # $1 = where we are being called from.
+ # This is used to determine which hooks to run.
+ status "Starting UDev Daemon" udevd --daemon
+
+ run_hook "$1_udevlaunched"
+
+ stat_busy "Triggering UDev uevents"
+ udevadm trigger --action=add --type=subsystems
+ udevadm trigger --action=add --type=devices
+ stat_done
+
+ # Load modules from the MODULES array defined in rc.conf
+ [[ -f /proc/modules ]] && (( ${#MODULES[*]} )) &&
+ status "Loading Modules" modprobe -ab "${MODULES[@]}"
+
+ status "Waiting for UDev uevents to be processed" \
+ udevadm settle --timeout=${UDEV_TIMEOUT:-30}
- run_hook "$1_postkillall"
+ run_hook "$1_udevsettled"
+
+ # in case loading a module changed the display mode
+ calc_columns
}
activate_vgs() {
- [[ $USELVM =~ yes|YES && -x /sbin/lvm && -d /sys/block ]] || return
+ [[ $USELVM = [yY][eE][sS] && -x $(type -P lvm) && -d /sys/block ]] || return 0
# Kernel 2.6.x, LVM2 groups
- /sbin/modprobe -q dm-mod 2>/dev/null
stat_busy "Activating LVM2 groups"
- if /sbin/vgchange --sysinit -a y >/dev/null; then
- stat_done
- else
- stat_fail
- fi
+ modprobe -q dm-mod 2>/dev/null
+ vgchange --sysinit -a y >/dev/null
+ (( $? == 0 )) && stat_done || stat_fail
}
# Arch cryptsetup packages traditionally contained the binaries
@@ -301,7 +358,7 @@ read_crypttab() {
# $1 = function to call with the split out line from the crypttab
local line nspo failed=0
while read line; do
- [[ $line && ${line:0:1} != '#' ]] || continue
+ [[ $line && $line != '#'* ]] || continue
eval nspo=("${line%#*}")
if $1 "${nspo[0]}" "${nspo[1]}" "${nspo[2]}" "${nspo[*]:3}"; then
crypto_unlocked=1
@@ -312,6 +369,75 @@ read_crypttab() {
return $failed
}
+# Filesystem functions
+# These can be overridden/reused for customizations like shutdown/loop-fsck.
+NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.glusterfs"
+
+# Check local filesystems
+fsck_all() {
+ fsck -A -T -C"$FSCK_FD" -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK
+ return $?
+}
+
+# Single-user login and/or automatic reboot after fsck (if needed)
+fsck_reboot() {
+ # $1 = exit code returned by fsck
+ # Ignore conditions 'FS errors corrected' and 'Cancelled by the user'
+ (( ($1 | 33) == 33 )) && return 0
+ if (( $1 & 2 )); then
+ echo
+ echo "********************** REBOOT REQUIRED *********************"
+ echo "* *"
+ echo "* The system will be rebooted automatically in 15 seconds. *"
+ echo "* *"
+ echo "************************************************************"
+ echo
+ sleep 15
+ else
+ echo
+ echo "***************** FILESYSTEM CHECK FAILED ****************"
+ echo "* *"
+ echo "* Please repair manually and reboot. Note that the root *"
+ echo "* file system is currently mounted read-only. To remount *"
+ echo "* it read-write type: mount -n -o remount,rw / *"
+ echo "* When you exit the maintenance shell the system will *"
+ echo "* reboot automatically. *"
+ echo "* *"
+ echo "************************************************************"
+ echo
+ sulogin -p
+ fi
+ echo "Automatic reboot in progress..."
+ umount -a
+ mount -n -o remount,ro /
+ reboot -f
+ exit 0
+}
+
+mount_all() {
+ mount -a -t "nosysfs,no${NETFS//,/,no}" -O no_netdev
+}
+
+remove_leftover() {
+ stat_busy "Removing Leftover Files"
+ # handle this separately until we declare the non-symlinks obsoleted
+ [[ ! -L /var/lock ]] && rm -rf /var/lock/*
+ if [[ ! -L /var/run && -d /var/run ]]; then
+ find /var/run/ \! -type d -delete
+ ln -s /run/daemons /var/run/daemons
+ fi
+ /usr/lib/initscripts/arch-tmpfiles --create --remove && stat_done || stat_fail
+}
+
+bootlogd_stop() {
+ [[ -f /run/bootlogd.pid ]] || return 0
+ touch /var/log/boot
+ kill $(< /run/bootlogd.pid)
+ rm -f /run/bootlogd.pid
+ sed -i -r -e 's/\^\[\[[0-9]?;?[0-9]?[0-9]?;?[0-9]?[0-9]?[ms]//g' \
+ -e 's/\^\[(\[1[0-9]1|%)G//g' -e 's/\^\[\[0;1//g' /var/log/boot
+}
+
###############################
# Custom hooks in initscripts #
###############################
@@ -338,21 +464,23 @@ read_crypttab() {
# sysinit_udevsettled: after uevents have settled in rc.sysinit
# single_udevsettled: after uevents have settled in rc.single
# sysinit_premount: before local filesystems are mounted, but after root is mounted read-write in rc.sysinit
+# sysinit_postmount: after local filesystems are mounted
# shutdown_prekillall: before all processes are being killed in rc.shutdown
# single_prekillall: before all processes are being killed in rc.single
# shutdown_postkillall: after all processes have been killed in rc.shutdown
# single_postkillall: after all processes have been killed in rc.single
+# shutdown_postumount: after filesystems are unmounted
# shutdown_poweroff: directly before powering off in rc.shutdown
#
# Declare add_hook and run_hook as read-only to prevent overwriting them.
# Too bad we cannot do the same thing with hook_funcs
-if [[ $RC_FUNCTIONS_HOOK_FUNCS_DEFINED -ne 1 ]]; then
+if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then
declare -A hook_funcs
add_hook() {
[[ $1 && $2 ]] || return 1
- hook_funcs["$1"]+=" $2"
+ hook_funcs[$1]+=" $2"
}
run_hook() {
@@ -371,13 +499,14 @@ fi
set_consolefont() {
[[ $CONSOLEFONT ]] || return 0
stat_busy "Loading Console Font: $CONSOLEFONT"
- #CONSOLEMAP in UTF-8 shouldn't be used
- [[ $CONSOLEMAP && ${LOCALE,,} =~ utf ]] && CONSOLEMAP=""
- for i in /dev/tty[0-9]*; do
- /usr/bin/setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \
- $CONSOLEFONT -C ${i} >/dev/null 2>&1
- done
- if (($? != 0)); then
+ #CONSOLEMAP in UTF-8 shouldn't be used
+ [[ $CONSOLEMAP && ${LOCALE,,} =~ utf ]] && CONSOLEMAP=""
+ local i
+ for i in /dev/tty[0-9]*; do
+ setfont ${CONSOLEMAP:+-m "${CONSOLEMAP}"} \
+ "$CONSOLEFONT" -C ${i} &>/dev/null
+ done
+ if (( $? )); then
stat_fail
elif [[ $CONSOLEMAP ]]; then
cat <<"EOF" >>/etc/profile.d/locale.sh
@@ -394,5 +523,15 @@ for f in /etc/rc.d/functions.d/*; do
[[ -e $f ]] && . "$f"
done
+# Exit current shell if user is not root
+need_root() {
+ (( EUID )) && printf 'You need to be root.\n' && exit 1
+}
+
+# Quit script if it's not running by root
+# This can be disabled in scripts sourcing functions by setting NEED_ROOT=0
+# A local call to need_root can be done to ensure part of script need root privilege
+(( ${NEED_ROOT:-0} == 1 )) && need_root
+
# End of file
# vim: set ts=2 sw=2 noet:
diff --git a/locale.sh b/locale.sh
new file mode 100644
index 0000000..611a797
--- /dev/null
+++ b/locale.sh
@@ -0,0 +1,3 @@
+. /etc/rc.conf
+
+export LANG=${LOCALE:=en_US}
diff --git a/netfs b/netfs
index 2bcec6c..ea7e4eb 100755
--- a/netfs
+++ b/netfs
@@ -4,32 +4,24 @@
. /etc/rc.conf
. /etc/rc.d/functions
-rc=0
-
case "$1" in
start)
stat_busy "Mounting Network Filesystems"
- /bin/mount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs
+ mount -a -t "$NETFS"
rc=$?
- /bin/mount -a -O _netdev
- if ((rc + $? > 0)); then
- stat_fail
- else
- add_daemon netfs
- stat_done
- fi
+ mount -a -O _netdev
+ (( rc || $? )) && stat_die
+ add_daemon netfs
+ stat_done
;;
stop)
stat_busy "Unmounting Network Filesystems"
- /bin/umount -a -O _netdev
+ umount -a -O _netdev
rc=$?
- /bin/umount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs
- if ((rc + $? > 0)); then
- stat_fail
- else
- rm_daemon netfs
- stat_done
- fi
+ umount -a -t "$NETFS"
+ (( rc || $? )) && stat_die
+ rm_daemon netfs
+ stat_done
;;
restart)
$0 stop
@@ -37,7 +29,8 @@ case "$1" in
$0 start
;;
*)
- echo "usage: $0 {start|stop|restart}"
+ echo "usage: $0 {start|stop|restart}"
+ exit 1
esac
# vim: set ts=2 noet:
diff --git a/network b/network
index c2ad9ba..b94d170 100755
--- a/network
+++ b/network
@@ -9,7 +9,8 @@ done
# helper function to determine if legacy network support is needed
need_legacy() {
- if [[ -z $interface ]]; then
+ # complain when `interface' is unset and `INTERFACES' has profiles enabled
+ if [[ -z $interface && ${INTERFACES[@]##!*} ]]; then
return 0 # need legacy
fi
@@ -17,33 +18,42 @@ need_legacy() {
}
deprecated() {
- printf "${C_FAIL}Warning:${C_CLEAR} This functionality is deprecated.\n"
+ printf "${C_FAIL}Warning:${C_CLEAR} Your network settings are deprecated.\n"
printf " Please refer to /etc/rc.conf on how to define a single wired\n"
printf " connection, or use a utility such as netcfg.\n"
}
+have_interface() {
+ if [[ -z $1 ]]; then
+ printf "\n${C_FAIL}Error:${C_CLEAR} \`interface' is undefined in /etc/rc.conf\n"
+ return 1
+ fi
+
+ if [[ ! -d /sys/class/net/$1 ]]; then
+ printf "\n${C_FAIL}Error:${C_CLEAR} unknown interface in /etc/rc.conf: \`%s'\n" "$1"
+ return 1
+ fi
+}
+
network_up() {
+ have_interface "$interface" || return 1
+
ip link set dev $interface up || return 1
if [[ $address ]]; then
- for var in netmask gateway; do
- if [[ -z ${!var} ]]; then
- printf "${C_FAIL}Error: static address defined without $var!\n"
- return 1
- fi
- done
- ip addr add $address/$netmask broadcast ${broadcast:-+} dev $interface || return 1
- ip route add default via $gateway || return 1
+ ip addr add $address/${netmask:-24} broadcast ${broadcast:-+} dev $interface || return 1
+ [[ $gateway ]] && { ip route add default via $gateway || return 1; }
else
dhcpcd $DHCPCD_ARGS $interface || return 1
fi
}
network_down() {
+ have_interface "$interface" || return 1
+
if [[ -f /var/run/dhcpcd-$interface.pid ]]; then
dhcpcd -k $interface || return 1
else
- ip route del default || return 1
ip addr flush dev $interface || return 1
fi
@@ -299,7 +309,7 @@ case "$1" in
;;
ifup|ifdown|iflist|rtup|rtdown|rtlist)
# deprecation check
- need_legacy && deprecated
+ deprecated
$1 $2
;;
*)
diff --git a/rc.conf b/rc.conf
index cd95d9c..418f607 100644
--- a/rc.conf
+++ b/rc.conf
@@ -9,10 +9,12 @@
# LOCALE: available languages can be listed with the 'locale -a' command
# DAEMON_LOCALE: If set to 'yes', use $LOCALE as the locale during daemon
# startup and during the boot process. If set to 'no', the C locale is used.
-# HARDWARECLOCK: set to "UTC" or "localtime", any other value will result
+# HARDWARECLOCK: set to "", "UTC" or "localtime", any other value will result
# in the hardware clock being left untouched (useful for virtualization)
-# Note: Using "localtime" is discouraged.
+# Note: Using "localtime" is discouraged, using "" makes hwclock fall back
+# to the value in /var/lib/hwclock/adjfile
# TIMEZONE: timezones are found in /usr/share/zoneinfo
+# Note: if unset, the value in /etc/localtime is used unchanged
# KEYMAP: keymaps are found in /usr/share/kbd/keymaps
# CONSOLEFONT: found in /usr/share/kbd/consolefonts (only needed for non-US)
# CONSOLEMAP: found in /usr/share/kbd/consoletrans
@@ -64,7 +66,7 @@ HOSTNAME="myhost"
# Wired network setup
# - interface: name of device (required)
# - address: IP address (leave blank for DHCP)
-# - netmask: subnet mask (ignored for DHCP)
+# - netmask: subnet mask (ignored for DHCP) (optional, defaults to 255.255.255.0)
# - broadcast: broadcast address (ignored for DHCP) (optional)
# - gateway: default route (ignored for DHCP)
#
diff --git a/rc.d b/rc.d
index ad0a1e9..5cb03f8 100755
--- a/rc.d
+++ b/rc.d
@@ -1,14 +1,22 @@
#!/bin/bash
+NEED_ROOT=0 # this script can be run without be root
. /etc/rc.conf
. /etc/rc.d/functions
usage() {
local name=${0##*/}
cat >&2 << EOF
-usage: $name action daemon ...
+usage: $name <action> <daemon> [daemon] ...
+ $name list [started|stopped]
+ $name help
+
+<daemon> is the name of a script in /etc/rc.d
+<action> can be a start, stop, restart, reload, status, ...
+WARNING: initscripts are free to implement or not the above actions.
e.g: $name list
+ $name list started
$name help
$name start sshd gpm
EOF
@@ -23,13 +31,16 @@ case $1 in
usage
;;
list)
+ shift
cd /etc/rc.d/
for d in *; do
have_daemon "$d" || continue
# print running / stopped satus
if ! ck_daemon "$d"; then
+ [[ "$1" == stopped ]] && continue
printf "${C_OTHER}[${C_DONE}STARTED${C_OTHER}]"
else
+ [[ "$1" == started ]] && continue
printf "${C_OTHER}[${C_FAIL}STOPPED${C_OTHER}]"
fi
# print auto / manual status
@@ -40,7 +51,7 @@ case $1 in
fi
printf " ${C_CLEAR}$d\n"
done
- ;;
+ ;;
*)
# check min args count
(( $# < 2 )) && usage
@@ -58,10 +69,12 @@ case $1 in
if [[ -x "/etc/rc.d/$i" ]]; then
env -i "${ENV[@]}" "/etc/rc.d/$i" "$action"
else
- printf "${C_OTHER}:: ${C_FAIL}Error: ${C_DONE}Daemon script $i does not exist.\n"
+ printf "${C_OTHER}:: ${C_FAIL}Error: ${C_DONE}Daemon script \`%s' does not exist or is not executable.${C_CLEAR}\n" \
+ "$i"
fi
(( ret += !! $? )) # clamp exit value to 0/1
done
+ ;;
esac
exit $ret
diff --git a/rc.multi b/rc.multi
index 1160ab4..16fa83a 100755
--- a/rc.multi
+++ b/rc.multi
@@ -9,7 +9,7 @@
run_hook multi_start
# Load sysctl variables if sysctl.conf is present
-[[ -r /etc/sysctl.conf ]] && /sbin/sysctl -q -p &>/dev/null
+[[ -r /etc/sysctl.conf ]] && sysctl -q -p &>/dev/null
# Start daemons
for daemon in "${DAEMONS[@]}"; do
@@ -20,18 +20,10 @@ for daemon in "${DAEMONS[@]}"; do
esac
done
-if [[ -x /etc/rc.local ]]; then
- /etc/rc.local
-fi
+[[ -x /etc/rc.local ]] && /etc/rc.local
run_hook multi_end
-if [[ -f /run/bootlogd.pid ]]; then
- touch /var/log/boot
- kill $(< /run/bootlogd.pid)
- rm -f /run/bootlogd.pid
- sed -i -r -e 's/\^\[\[[0-9]?;?[0-9]?[0-9]?;?[0-9]?[0-9]?[ms]//g' \
- -e 's/\^\[(\[151|%)G//g' /var/log/boot
-fi
+bootlogd_stop
# vim: set ts=2 sw=2 noet:
diff --git a/rc.shutdown b/rc.shutdown
index a040bbe..db8f50b 100755
--- a/rc.shutdown
+++ b/rc.shutdown
@@ -6,10 +6,6 @@
. /etc/rc.conf
. /etc/rc.d/functions
-export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-
-run_hook shutdown_start
-
# avoid staircase effect
stty onlcr
@@ -17,29 +13,33 @@ echo " "
printhl "Initiating Shutdown..."
echo " "
+run_hook shutdown_start
+
[[ -x /etc/rc.local.shutdown ]] && /etc/rc.local.shutdown
-kill_everything shutdown
+stop_all_daemons
+
+run_hook shutdown_prekillall
+
+kill_all
+
+run_hook shutdown_postkillall
stat_busy "Saving Random Seed"
-RANDOM_SEED=/var/lib/misc/random-seed
-[[ -d ${RANDOM_SEED%/*} ]] || mkdir -p ${RANDOM_SEED%/*}
-: > $RANDOM_SEED
-chmod 0600 $RANDOM_SEED
-POOL_FILE=/proc/sys/kernel/random/poolsize
-if [[ -r $POOL_FILE ]]; then
- read POOL_SIZE <$POOL_FILE
-else
- POOL_SIZE=512
-fi
-dd if=/dev/urandom of=$RANDOM_SEED count=1 bs=$POOL_SIZE &> /dev/null
+ RANDOM_SEED=/var/lib/misc/random-seed
+ install -TDm 0600 /dev/null $RANDOM_SEED
+ POOL_FILE=/proc/sys/kernel/random/poolsize
+ if [[ -r $POOL_FILE ]]; then
+ read POOL_SIZE < $POOL_FILE
+ else
+ POOL_SIZE=512
+ fi
+ dd if=/dev/urandom of=$RANDOM_SEED count=1 bs=$POOL_SIZE &>/dev/null
stat_done
-if [[ $TIMEZONE && -e /usr/share/zoneinfo/$TIMEZONE ]]; then
- rm -f /etc/localtime
+[[ $TIMEZONE ]] &&
status "Saving Time Zone" \
- cp "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
-fi
+ cp --remove-destination "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
# Write to wtmp file before unmounting
halt -w
@@ -47,58 +47,89 @@ halt -w
status "Deactivating Swap" swapoff -a
# stop monitoring of lvm2 groups before unmounting filesystems
-if [[ $USELVM =~ yes|YES && -x $(type -P lvm) && -d /sys/block ]]; then
+[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] &&
status "Deactivating monitoring of LVM2 groups" \
- vgchange --monitor n >/dev/null 2>&1
-fi
+ vgchange --monitor n &>/dev/null
-stat_busy "Unmounting Filesystems"
-if grep -q devtmpfs /proc/filesystems &>/dev/null; then
- umount -a -r -t nosysfs,noproc,nodevtmpfs,nodevpts -O no_netdev
-else
- # if we don't have devtmpfs support, /dev is mounted as tmpfs, so don't unmount it
- umount -a -r -t notmpfs,nosysfs,noproc,nodevpts -O no_netdev
-fi
-stat_done
+# if we don't have devtmpfs support, /dev is mounted as tmpfs, so don't unmount it
+status "Unmounting Filesystems" \
+ umount -a -r -t nodevtmpfs,notmpfs,nosysfs,noproc,nodevpts -O no_netdev
+
+run_hook shutdown_postumount
# Kill non-root encrypted partition mappings
-if [[ -f /etc/crypttab && -n $CS ]] && grep -q ^[^#] /etc/crypttab; then
+if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then
stat_busy "Deactivating encrypted volumes:"
- # Maybe someone has LVM on an encrypted block device
- # executing an extra vgchange is errorless
- if [[ $USELVM =~ yes|YES ]]; then
- vgchange --sysinit -a n >/dev/null 2>&1
- fi
- do_lock() {
- stat_append "${1}.."
- if $CS remove "$1" >/dev/null 2>&1; then
- stat_append "ok "
- else
- stat_append "failed "
- fi
- }
- read_crypttab do_lock
+ # Maybe someone has LVM on an encrypted block device
+ # executing an extra vgchange is errorless
+ [[ $USELVM = [Yy][Ee][Ss] ]] && vgchange --sysinit -a n &>/dev/null
+ do_lock() {
+ stat_append "${1}.."
+ if $CS remove "$1" &>/dev/null; then
+ stat_append "ok "
+ else
+ stat_append "failed "
+ fi
+ }
+ read_crypttab do_lock
stat_done
fi
-if [[ $USELVM =~ yes|YES && -x $(type -P lvm) && -d /sys/block ]]; then
- status "Deactivating LVM2 groups" vgchange --sysinit -a n >/dev/null 2>&1
-fi
+[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] &&
+ status "Deactivating LVM2 groups" vgchange --sysinit -a n &>/dev/null
+
+if [[ -x /run/initramfs/shutdown ]]; then
+
+ # decide what we want to do
+ if [[ $RUNLEVEL = 0 ]]; then
+ action="poweroff"
+ else
+ action="reboot"
+ fi
-status "Remounting Root Filesystem Read-only" mount -n -o remount,ro /
+ # make /run/initrafs a mount
+ mount --bind /run/initramfs /run/initramfs
-run_hook shutdown_poweroff
+ # in case someone has shared our mountpoints, unshare them
+ mount --make-private /run/initramfs
+ mount --make-private /
+
+ # bind all api mounts
+ mkdir -p /run/initramfs/{sys,proc,dev,run,oldroot}
+ mount --bind /sys /run/initramfs/sys
+ mount --bind /proc /run/initramfs/proc
+ mount --bind /dev /run/initramfs/dev
+ mount --bind /run /run/initramfs/run
+
+ # enter shutdownramfs
+ cd /run/initramfs
+ pivot_root . oldroot
+
+ #reexec init
+ /oldroot/sbin/init u
+
+ # run /shutdown in the new root
+ exec chroot . /shutdown $action </dev/console >/dev/console 2>&1
-# Power off or reboot
-printsep
-if [[ $RUNLEVEL = 0 ]]; then
- printhl "${C_H2}POWER OFF"
- poweroff -d -f -h -i
else
- printhl "${C_H2}REBOOTING"
- # if kexec is installed and a kernel is loaded, use it
- [[ -x $(type -P kexec) ]] && kexec -e > /dev/null 2>&1
- reboot -d -f -i
+
+ status "Remounting Root Filesystem Read-only" \
+ mount -n -o remount,ro /
+
+ run_hook shutdown_poweroff
+
+ # Power off or reboot
+ printsep
+ if [[ $RUNLEVEL = 0 ]]; then
+ printhl "${C_H2}POWER OFF"
+ poweroff -d -f -h -i
+ else
+ printhl "${C_H2}REBOOTING"
+ # if kexec is installed and a kernel is loaded, use it
+ [[ -x $(type -P kexec) ]] && kexec -e &>/dev/null
+ reboot -d -f -i
+ fi
+
fi
# End of file
diff --git a/rc.single b/rc.single
index bb27ddf..3527a99 100755
--- a/rc.single
+++ b/rc.single
@@ -6,42 +6,32 @@
. /etc/rc.conf
. /etc/rc.d/functions
-export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-
run_hook single_start
if [[ $PREVLEVEL != N ]]; then
- kill_everything single
- status "Starting UDev Daemon" udevd --daemon
- run_hook single_udevlaunched
-
- # Trigger udev uevents
- if pidof -o %PPID /udevd >/dev/null; then
- stat_busy "Triggering UDev uevents"
- udevadm trigger --action=add --type=subsystems
- udevadm trigger --action=add --type=devices
- stat_done
- fi
-
- # Wait for udev uevents
- if pidof -o %PPID udevd >/dev/null; then
- status "Waiting for UDev uevents to be processed" \
- udevadm settle --quiet --timeout=${UDEV_TIMEOUT:-30}
- fi
-
- run_hook single_udevsettled
-
- # try syslog-NG first, then fall back to good ol' syslogd
- if [[ -x /etc/rc.d/syslog-ng ]]; then
- /etc/rc.d/syslog-ng start
- elif [[ -x /etc/rc.d/syslogd ]]; then
- /etc/rc.d/syslogd start
- [[ -x /etc/rc.d/klogd ]] && /etc/rc.d/klogd start
- fi
+
+ stop_all_daemons
+
+ run_hook single_prekillall
+
+ kill_all
+
+ run_hook single_postkillall
+
+ # start up our mini logger until syslog takes over
+ minilogd
+
+ # Start/trigger UDev, load MODULES and settle UDev
+ udevd_modprobe single
+
+ # Removing leftover files
+ remove_leftover
fi
run_hook single_end
+bootlogd_stop
+
if [[ $RUNLEVEL = 1 ]]; then
printsep
printhl "Entering single-user mode..."
@@ -50,13 +40,5 @@ if [[ $RUNLEVEL = 1 ]]; then
exec init -t1 S
fi
-if [[ -f /run/bootlogd.pid ]]; then
- touch /var/log/boot
- kill $(< /run/bootlogd.pid)
- rm -f /run/bootlogd.pid
- sed -i -r -e 's/\^\[\[[0-9]?;?[0-9]?[0-9]?;?[0-9]?[0-9]?[ms]//g' \
- -e 's/\^\[(\[151|%)G//g' /var/log/boot
-fi
-
# End of file
# vim: set ts=2 sw=2 noet:
diff --git a/rc.sysinit b/rc.sysinit
index 011c649..236d663 100755
--- a/rc.sysinit
+++ b/rc.sysinit
@@ -12,27 +12,17 @@ printhl "${C_H2}http://parabolagnulinux.org"
printhl "You're booting into a /libre/ version of Archlinux"
printsep
-run_hook sysinit_start
-
-# export standard PATH (will be overridden later when /etc/profile is sourced, but is useful for UDev)
-export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-
# mount /proc, /sys, /run, /dev, /run/lock, /dev/pts, /dev/shm (the api filesystems)
mountpoint -q /proc || mount -n -t proc proc /proc -o nosuid,noexec,nodev
mountpoint -q /sys || mount -n -t sysfs sys /sys -o nosuid,noexec,nodev
-mountpoint -q /run || mount -n -t tmpfs run /run -o mode=755,size=10M,nosuid,nodev
-if ! mountpoint -q /dev; then
- if grep -q devtmpfs /proc/filesystems &>/dev/null; then
- mount -n -t devtmpfs udev /dev -o mode=0755,size=10M,nosuid
- else
- mount -n -t tmpfs udev /dev -o mode=0755,size=10M,nosuid
- fi
-fi
-mkdir -p /run/lock /dev/{pts,shm}
-chmod 1777 /run/lock
-mountpoint -q /dev/pts || mount -n /dev/pts &> /dev/null \
- || mount -n -t devpts devpts /dev/pts -o mode=620,gid=5,nosuid,noexec
-mountpoint -q /dev/shm || mount -n /dev/shm &> /dev/null \
+mountpoint -q /run || mount -n -t tmpfs run /run -o mode=0755,size=10M,nosuid,nodev
+mountpoint -q /dev || mount -n -t devtmpfs udev /dev -o mode=0755,size=10M,nosuid &>/dev/null \
+ || mount -n -t tmpfs udev /dev -o mode=0755,size=10M,nosuid
+mkdir -p -m 1777 /run/lock
+mkdir -p /dev/{pts,shm}
+mountpoint -q /dev/pts || mount -n /dev/pts &>/dev/null \
+ || mount -n -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec
+mountpoint -q /dev/shm || mount -n /dev/shm &>/dev/null \
|| mount -n -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev
# remount root ro to allow for fsck later on, we remount now to
@@ -40,10 +30,16 @@ mountpoint -q /dev/shm || mount -n /dev/shm &> /dev/null \
findmnt / --options ro &>/dev/null ||
status "Mounting Root Read-Only" mount -n -o remount,ro /
+run_hook sysinit_start
+
# start up our mini logger until syslog takes over
minilogd
bootlogd -p /run/bootlogd.pid
+if [[ ! -a /usr/lib ]] ; then
+ printf "${C_FAIL}/usr is not mounted. This is not supported.${C_OTHER}\n"
+fi
+
HWCLOCK_PARAMS="--systz"
case $HARDWARECLOCK in
"") ;;
@@ -53,86 +49,66 @@ case $HARDWARECLOCK in
esac
if [[ $HWCLOCK_PARAMS ]]; then
- # enable rtc access
- modprobe -q -a rtc-cmos rtc genrtc
- # If devtmpfs is used, the required RTC device already exists now
- # Otherwise, create whatever device is available
- if ! [[ -c /dev/rtc || -c /dev/rtc0 ]]; then
- for dev in /sys/class/rtc/rtc0/dev /sys/class/misc/rtc/dev; do
- [[ -e $dev ]] || continue
- IFS=: read -r major minor < "$dev"
- mknod /dev/rtc c $major $minor
- done
- fi
-
- # Adjust the system time for timezone offset if rtc is not in UTC
- # 1. Make creation time on udev nodes sane (FS#8665)
- # 2. Filesystem checks can depend on system time
- # 3. This will set the clock, if using non-UTC, off the last known
- # configured timezone. Any new timezone put in rc.conf is copied over at
- # a later time.
- # This does *NOT* take into account a time adjustment file as /var may not be
- # mounted yet. A second set may occur in rc.d/hwclock to match rc.conf.
- if [[ -f /etc/localtime ]]; then
- hwclock $HWCLOCK_PARAMS
- fi
+ stat_busy "Adjusting system time and setting kernel timezone"
+ # enable rtc access
+ modprobe -q -a rtc-cmos rtc genrtc
+ # If devtmpfs is used, the required RTC device already exists now
+ # Otherwise, create whatever device is available
+ if ! [[ -c /dev/rtc || -c /dev/rtc0 ]]; then
+ for dev in /sys/class/rtc/rtc0/dev /sys/class/misc/rtc/dev; do
+ [[ -e $dev ]] || continue
+ IFS=: read -r major minor < "$dev"
+ mknod /dev/rtc c $major $minor
+ done
+ fi
+
+ # Adjust the system time for timezone offset if rtc is not in UTC
+ # 1. Make creation time on udev nodes sane (FS#8665)
+ # 2. Filesystem checks can depend on system time
+ # 3. This also sets the kernel time zone, used by e.g. vfat
+ # If TIMEZONE is not set in rc.conf, the timezone stored in /etc/localtime
+ # is used. If HARDWARECLOCK is not set in rc.conf, the value in
+ # /var/lib/hwclock/adjfile is used (in this case /var can not be a separate
+ # partition).
+ TZ=$TIMEZONE hwclock $HWCLOCK_PARAMS && stat_done || stat_fail
fi
-status "Starting UDev Daemon" udevd --daemon
-
-run_hook sysinit_udevlaunched
-
-stat_busy "Triggering UDev uevents"
- udevadm trigger --action=add --type=subsystems
- udevadm trigger --action=add --type=devices
-stat_done
-
-# Load modules from the MODULES array defined in rc.conf
-mods=${MODULES[@]/!*/}
-if [[ $load_modules != off && -f /proc/modules && $mods ]]; then
- status "Loading Modules" modprobe --all $mods
-fi
-unset mods
-
-status "Waiting for UDev uevents to be processed" \
- udevadm settle --timeout=${UDEV_TIMEOUT:-30}
-
-run_hook sysinit_udevsettled
+# Start/trigger UDev, load MODULES and settle UDev
+udevd_modprobe sysinit
# bring up the loopback interface
[[ -d /sys/class/net/lo ]] &&
status "Bringing up loopback interface" ip link set up dev lo
# FakeRAID devices detection
-if [[ $USEDMRAID =~ yes|YES && -x $(type -P dmraid) ]]; then
+[[ $USEDMRAID = [Yy][Ee][Ss] && -x $(type -P dmraid) ]] &&
status "Activating FakeRAID arrays" dmraid -i -ay
-fi
# BTRFS devices detection
-if [[ $USEBTRFS =~ yes|YES && -x $(type -P btrfs) ]]; then
+[[ $USEBTRFS = [Yy][Ee][Ss] && -x $(type -P btrfs) ]] &&
status "Activating BTRFS volumes" btrfs device scan
-fi
+# Activate LVM2 groups if any
activate_vgs
# Set up non-root encrypted partition mappings
-if [[ -f /etc/crypttab && -n $CS ]] && grep -q ^[^#] /etc/crypttab; then
- modprobe -q dm-crypt 2>/dev/null
+if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then
stat_busy "Unlocking encrypted volumes:"
+ modprobe -q dm-crypt 2>/dev/null
do_unlock() {
# $1 = requested name
# $2 = source device
# $3 = password
# $4 = options
stat_append "${1}.."
- local open=create a="$1" b="$2" failed=0
+ local open=create a=$1 b=$2 failed=0
# Ordering of options is different if you are using LUKS vs. not.
# Use ugly swizzling to deal with it.
# isLuks only gives an exit code but no output to stdout or stderr.
if $CS isLuks "$2" 2>/dev/null; then
open=luksOpen
- a="$2"
- b="$1"
+ a=$2
+ b=$1
fi
case $3 in
SWAP)
@@ -148,11 +124,9 @@ if [[ -f /etc/crypttab && -n $CS ]] && grep -q ^[^#] /etc/crypttab; then
# This sanity check _should_ be sufficient, but it might not.
# This may cause dataloss if it is not used carefully.
blkid -p "$2" &>/dev/null
- if [[ $? -eq 2 ]]; then
- _overwriteokay=1
- fi
+ (( $? == 2 )) && _overwriteokay=1
fi
- if [[ $_overwriteokay -eq 0 ]]; then
+ if (( _overwriteokay == 0 )); then
false
elif $CS -d /dev/urandom $4 $open "$a" "$b" >/dev/null; then
stat_append "creating swapspace.."
@@ -162,12 +136,12 @@ if [[ -f /etc/crypttab && -n $CS ]] && grep -q ^[^#] /etc/crypttab; then
printf "\nOpening '$1' volume:\n"
$CS $4 $open "$a" "$b" < /dev/console;;
/dev*)
- ckdev=${3%%:*}
- cka=${3#*:}
- ckb=${cka#*:}
- cka=${cka%:*}
- ckfile=/dev/ckfile
- ckdir=/dev/ckdir
+ local ckdev=${3%%:*}
+ local cka=${3#*:}
+ local ckb=${cka#*:}
+ local cka=${cka%:*}
+ local ckfile=/dev/ckfile
+ local ckdir=/dev/ckdir
case ${cka} in
*[!0-9]*)
# Use a file on the device
@@ -190,7 +164,7 @@ if [[ -f /etc/crypttab && -n $CS ]] && grep -q ^[^#] /etc/crypttab; then
*)
echo "$3" | $CS $4 $open "$a" "$b" >/dev/null;;
esac
- if (($? != 0)); then
+ if (( $? )); then
failed=1
stat_append "failed "
else
@@ -199,137 +173,72 @@ if [[ -f /etc/crypttab && -n $CS ]] && grep -q ^[^#] /etc/crypttab; then
return $failed
}
crypto_unlocked=0
- if read_crypttab do_unlock; then
- stat_done
- else
- stat_fail
- fi
- if [[ ${crypto_unlocked} -eq 1 ]]; then
- # Maybe someone has LVM on an encrypted block device
- activate_vgs
- fi
+ read_crypttab do_unlock && stat_done || stat_fail
+ # Maybe someone has LVM on an encrypted block device
+ (( crypto_unlocked == 1 )) && activate_vgs
fi
-NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk,noglusterfs,nodavfs"
-
+# Check filesystems
+[[ -f /forcefsck ]] || in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f"
+declare -r FORCEFSCK
+run_hook sysinit_prefsck
if [[ -x $(type -P fsck) ]]; then
stat_busy "Checking Filesystems"
- fsck_reboot() {
- echo "Automatic reboot in progress..."
- umount -a
- mount -n -o remount,ro /
- reboot -f
- exit 0
- }
- FSCK_OUT=/dev/stdout
- FSCK_ERR=/dev/stdout
- FSCK_FD=
- FORCEFSCK=
- [[ -f /forcefsck ]] && FORCEFSCK="-- -f"
- for cmdarg in $(< /proc/cmdline); do
- [[ "$cmdarg" == forcefsck ]] && FORCEFSCK="-- -f" && break
- done
- run_hook sysinit_prefsck
- fsck -A -T -C$FSCK_FD -a -t "$NETFS,noopts=_netdev" $FORCEFSCK >$FSCK_OUT 2>$FSCK_ERR
- fsckret=$?
- if ((fsckret > 1)); then
- stat_fail
- fi
- run_hook sysinit_postfsck
- if (( ( fsckret & 2) == 2)); then
- echo
- echo "********************** REBOOT REQUIRED *********************"
- echo "* *"
- echo "* The system will be rebooted automatically in 15 seconds. *"
- echo "* *"
- echo "************************************************************"
- echo
- sleep 15
- fsck_reboot
- elif ((fsckret > 1 && fsckret != 32)); then
- echo
- echo "***************** FILESYSTEM CHECK FAILED ****************"
- echo "* *"
- echo "* Please repair manually and reboot. Note that the root *"
- echo "* file system is currently mounted read-only. To remount *"
- echo "* it read-write type: mount -n -o remount,rw / *"
- echo "* When you exit the maintenance shell the system will *"
- echo "* reboot automatically. *"
- echo "* *"
- echo "************************************************************"
- echo
- sulogin -p
- fsck_reboot
- fi
- stat_done
+ fsck_all >|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}"
+ declare -r fsckret=$?
+ (( fsckret <= 1 )) && stat_done || stat_fail
+else
+ declare -r fsckret=0
fi
+run_hook sysinit_postfsck
+
+# Single-user login and/or automatic reboot if needed
+fsck_reboot $fsckret
-stat_busy "Mounting Local Filesystems"
+status "Remounting Root Read/Write" \
mount -n -o remount,rw /
- # don't touch /etc/mtab if it is a symlink to /proc/self/mounts
- if [[ -L /etc/mtab ]]; then
- :
- elif [[ -x $(type -P findmnt) && -e /proc/self/mountinfo ]]; then
- findmnt -rnu -o SOURCE,TARGET,FSTYPE,OPTIONS >| /etc/mtab
- else
- cat /proc/mounts >| /etc/mtab
- fi
+# don't touch /etc/mtab if it is a symlink to /proc/self/mounts
+if [[ ! -L /etc/mtab ]]; then
+ stat_busy "Creating mtab"
+ if [[ -x $(type -P findmnt) && -e /proc/self/mountinfo ]]; then
+ findmnt -rnu -o SOURCE,TARGET,FSTYPE,OPTIONS >| /etc/mtab
+ else
+ cat /proc/mounts >| /etc/mtab
+ fi
+ (( $? == 0 )) && stat_done || stat_fail
+fi
- run_hook sysinit_premount
- # now mount all the local filesystems
- mount -a -t $NETFS -O no_netdev
-stat_done
+# now mount all the local filesystems
+run_hook sysinit_premount
+status "Mounting Local Filesystems" \
+ mount_all
+run_hook sysinit_postmount
# enable monitoring of lvm2 groups, now that the filesystems are mounted rw
-if [[ $USELVM =~ yes|YES && -x $(type -P lvm) && -d /sys/block ]]; then
+[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] &&
status "Activating monitoring of LVM2 groups" \
vgchange --monitor y >/dev/null
-fi
status "Activating Swap" swapon -a
-if [[ $TIMEZONE && -e /usr/share/zoneinfo/$TIMEZONE ]]; then
- rm -f /etc/localtime
+[[ $TIMEZONE ]] &&
status "Configuring Time Zone" \
- cp "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
-fi
+ cp --remove-destination "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
RANDOM_SEED=/var/lib/misc/random-seed
-if [[ -f $RANDOM_SEED ]]; then
+[[ -f $RANDOM_SEED ]] &&
status "Initializing Random Seed" \
- cat $RANDOM_SEED > /dev/urandom
-fi
+ cp $RANDOM_SEED /dev/urandom
-stat_busy "Removing Leftover Files"
- rm -rf /etc/{nologin,shutdownpid} /forcefsck &>/dev/null
- rm -rf /tmp/* /tmp/.* &>/dev/null
- [[ ! -L /var/lock ]] && rm -rf /var/lock/*
- [[ ! -L /var/run && -d /var/run ]] && find /var/run/ \! -type d -delete
- [[ ! -L /var/run && ! -L /var/run/daemons ]] &&
- rm -rf /var/run/daemons &&
- ln -s /run/daemons /var/run/daemons
- : >| /var/run/utmp
- chmod 0664 /var/run/utmp
- chown root:utmp /var/run/utmp
- # Keep {x,k,g}dm happy with xorg
- mkdir -m1777 /tmp/.{X11,ICE}-unix
-stat_done
+# Remove leftover files
+remove_leftover
if [[ $HOSTNAME ]]; then
stat_busy "Setting Hostname: $HOSTNAME"
- echo $HOSTNAME > /proc/sys/kernel/hostname
- stat_done
+ echo "$HOSTNAME" >| /proc/sys/kernel/hostname && stat_done || stat_fail
fi
-stat_busy "Setting Locale: ${LOCALE:=en_US}"
- # Flush old locale settings
- : >| /etc/profile.d/locale.sh
- chmod 755 /etc/profile.d/locale.sh
- # Set user defined locale
- echo "export LANG=$LOCALE" >>/etc/profile.d/locale.sh
-stat_done
-
if [[ ${LOCALE,,} =~ utf ]]; then
stat_busy "Setting Consoles to UTF-8 mode"
# UTF-8 consoles are default since 2.6.24 kernel
@@ -339,9 +248,8 @@ if [[ ${LOCALE,,} =~ utf ]]; then
kbd_mode -u < ${i}
printf "\e%%G" > ${i}
done
- echo 1 > /sys/module/vt/parameters/default_utf8
+ echo 1 >| /sys/module/vt/parameters/default_utf8
stat_done
- [[ $KEYMAP ]] && status "Loading Keyboard Map: $KEYMAP" loadkeys -q -u $KEYMAP
else
stat_busy "Setting Consoles to legacy mode"
# make non-UTF-8 consoles work on 2.6.24 and newer kernels
@@ -349,22 +257,23 @@ else
kbd_mode -a < ${i}
printf "\e%%@" > ${i}
done
- echo 0 > /sys/module/vt/parameters/default_utf8
+ echo 0 >| /sys/module/vt/parameters/default_utf8
stat_done
- [[ $KEYMAP ]] && status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP
fi
+[[ $KEYMAP ]] &&
+ status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP
# Set console font if required
set_consolefont
-if [[ -e /proc/sys/kernel/dmesg_restrict && $(< /proc/sys/kernel/dmesg_restrict) -eq 1 ]]; then
- : >| /var/log/dmesg.log
- chmod 600 /var/log/dmesg.log
-else
- : >| /var/log/dmesg.log
- chmod 644 /var/log/dmesg.log
-fi
-dmesg >| /var/log/dmesg.log
+stat_busy "Saving dmesg Log"
+ if [[ -e /proc/sys/kernel/dmesg_restrict ]] &&
+ (( $(< /proc/sys/kernel/dmesg_restrict) == 1 )); then
+ install -Tm 0600 <( dmesg ) /var/log/dmesg.log
+ else
+ install -Tm 0644 <( dmesg ) /var/log/dmesg.log
+ fi
+(( $? == 0 )) && stat_done || stat_fail
run_hook sysinit_end
diff --git a/tmpfiles.conf b/tmpfiles.conf
new file mode 100644
index 0000000..7dd1358
--- /dev/null
+++ b/tmpfiles.conf
@@ -0,0 +1,20 @@
+#
+# /usr/lib/tmpfiles.d/arch.conf
+#
+
+D /tmp 1777 root root
+D /run/daemons 0755 root root
+
+d /tmp/.X11-unix 1777 root root
+d /tmp/.ICE-unix 1777 root root
+d /tmp/.XIM-unix 1777 root root
+d /tmp/.font-unix 1777 root root
+d /tmp/.Test-unix 1777 root root
+
+F /var/run/utmp 0664 root utmp
+
+r /tmp/.X[0-9]-lock
+r /etc/nologin
+r /etc/shutdownpid
+r /forcefsck
+
diff --git a/zsh-completion b/zsh-completion
index f1b7165..e5c2850 100644
--- a/zsh-completion
+++ b/zsh-completion
@@ -15,9 +15,12 @@ _rc.d () {
curcontext="${curcontext%:*:*}:rc.d-${action}:"
case $action in
- list|help)
+ help)
_arguments "*: :"
;;
+ list)
+ _arguments "2: :(started stopped)"
+ ;;
start)
_arguments "*: :($(comm -23 <(echo /etc/rc.d/*(N-*:t)|tr ' ' '\n') <(echo /run/daemons/*(N:t)|tr ' ' '\n')))"
;;