diff options
Diffstat (limited to 'beagle/debian-rfs/lib/init')
| -rw-r--r-- | beagle/debian-rfs/lib/init/bootclean.sh | 190 | ||||
| -rw-r--r-- | beagle/debian-rfs/lib/init/mount-functions.sh | 165 | ||||
| -rw-r--r-- | beagle/debian-rfs/lib/init/splash-functions-base | 93 | ||||
| -rw-r--r-- | beagle/debian-rfs/lib/init/swap-functions.sh | 28 | ||||
| -rw-r--r-- | beagle/debian-rfs/lib/init/usplash-fsck-functions.sh | 178 | ||||
| -rw-r--r-- | beagle/debian-rfs/lib/init/vars.sh | 39 |
6 files changed, 693 insertions, 0 deletions
diff --git a/beagle/debian-rfs/lib/init/bootclean.sh b/beagle/debian-rfs/lib/init/bootclean.sh new file mode 100644 index 0000000..02e6cef --- /dev/null +++ b/beagle/debian-rfs/lib/init/bootclean.sh @@ -0,0 +1,190 @@ +#!/bin/sh +# +# bootclean +# +# Clean /tmp. Clean /var/run and /var/lock if not mounted as tmpfs +# +# DO NOT RUN AFTER S:55bootmisc.sh and do not run this script directly +# in runlevel S. Instead write an initscript to call it. +# + +. /lib/init/vars.sh + +. /lib/lsb/init-functions + +# Should be called outside verbose message block +mkflagfile() +{ + # Prevent symlink attack (See #264234.) + [ -L "$1" ] && log_warning_msg "bootclean: Deleting symbolic link '$1'." + rm -f "$1" || { log_failure_msg "bootclean: Failure deleting '$1'." ; return 1 ; } + # No user processes should be running, so no one should be able to introduce + # a symlink here. As an extra precaution, set noclobber. + set -o noclobber + :> "$1" || { log_failure_msg "bootclean: Failure creating '$1'." ; return 1 ; } + return 0 +} + +clean_tmp() { + cd /tmp || { log_failure_msg "bootclean: Could not cd to /tmp." ; return 1 ; } + + # + # Only clean out /tmp if it is world-writable. This ensures + # it really is a/the temp directory we're cleaning. + # + [ "$(find . -maxdepth 0 -perm -002)" = "." ] || return 0 + + if [ ! "$TMPTIME" ] + then + log_warning_msg "Using default TMPTIME 0." + TMPTIME=0 + fi + + [ "$VERBOSE" = no ] || log_action_begin_msg "Cleaning /tmp" + + # + # Remove regardless of TMPTIME setting + # + rm -f .X*-lock + + # + # Don't clean remaining files if TMPTIME is negative or 'infinite' + # + case "$TMPTIME" in + -*|infinite|infinity) + [ "$VERBOSE" = no ] || log_action_end_msg 0 "skipped" + return 0 + ;; + esac + + # + # Wipe /tmp, excluding system files, but including lost+found + # + # If TMPTIME is set to 0, we do not use any ctime expression + # at all, so we can also delete files with timestamps + # in the future! + # + if [ "$TMPTIME" = 0 ] + then + TEXPR="" + DEXPR="" + else + TEXPR="-mtime +$TMPTIME -ctime +$TMPTIME -atime +$TMPTIME" + DEXPR="-mtime +$TMPTIME -ctime +$TMPTIME" + fi + + EXCEPT='! -name . + ! ( -path ./lost+found -uid 0 ) + ! ( -path ./quota.user -uid 0 ) + ! ( -path ./aquota.user -uid 0 ) + ! ( -path ./quota.group -uid 0 ) + ! ( -path ./aquota.group -uid 0 ) + ! ( -path ./.journal -uid 0 ) + ! ( -path ./.clean -uid 0 ) + ! ( -path './...security*' -uid 0 )' + + mkflagfile /tmp/.clean || return 1 + + report_err() + { + if [ "$VERBOSE" = no ] + then + log_failure_msg "bootclean: Failure cleaning /tmp." + else + log_action_end_msg 1 "bootclean: Failure cleaning /tmp" + fi + } + + # + # First remove all old files... + # + find . -depth -xdev $TEXPR $EXCEPT ! -type d -delete \ + || { report_err ; return 1 ; } + + # + # ...and then all empty directories + # + find . -depth -xdev $DEXPR $EXCEPT -type d -empty -delete \ + || { report_err ; return 1 ; } + + [ "$VERBOSE" = no ] || log_action_end_msg 0 + return 0 +} + +clean_lock() { + if [ yes = "$RAMLOCK" ] ; then + return 0 + fi + + cd /var/lock || { log_failure_msg "bootclean: Could not cd to /var/lock." ; return 1 ; } + + [ "$VERBOSE" = no ] || log_action_begin_msg "Cleaning /var/lock" + report_err() + { + if [ "$VERBOSE" = no ] + then + log_failure_msg "bootclean: Failure cleaning /var/lock." + else + log_action_end_msg 1 "bootclean: Failure cleaning /var/lock" + fi + } + find . ! -type d -delete \ + || { report_err ; return 1 ; } + [ "$VERBOSE" = no ] || log_action_end_msg 0 + mkflagfile /var/lock/.clean || return 1 + return 0 +} + +clean_run() { + if [ yes = "$RAMRUN" ] ; then + return 0 + fi + + cd /var/run || { log_action_end_msg 1 "bootclean: Could not cd to /var/run." ; return 1 ; } + + [ "$VERBOSE" = no ] || log_action_begin_msg "Cleaning /var/run" + report_err() + { + if [ "$VERBOSE" = no ] + then + log_failure_msg "bootclean: Failure cleaning /var/run." + else + log_action_end_msg 1 "bootclean: Failure cleaning /var/run" + fi + } + find . ! -xtype d ! -name utmp ! -name innd.pid -delete \ + || { report_err ; return 1 ; } + [ "$VERBOSE" = no ] || log_action_end_msg 0 + mkflagfile /var/run/.clean || return 1 + return 0 +} + +which find >/dev/null 2>&1 || exit 1 +log_begin_msg "Cleaning up temporary files..." + +# If there are flag files that have not been created by root +# then remove them +for D in /tmp /var/run /var/lock +do + if [ -f $D/.clean ] + then + which stat >/dev/null 2>&1 && cleanuid="$(stat -c %u $D/.clean)" + # Poor's man stat %u, since stat (and /usr) might not be + # available in some bootup stages + [ "$cleanuid" ] || cleanuid="$(find $D/.clean -printf %U)" + [ "$cleanuid" ] || { log_failure_msg "bootclean: Could not stat '$D/.clean'." ; exit 1 ; } + if [ "$cleanuid" -ne 0 ] + then + rm -f $D/.clean || { log_failure_msg "bootclean: Could not delete '$D/.clean'." ; exit 1 ; } + fi + fi +done + +[ -f /tmp/.clean ] && [ -f /var/run/.clean ] && [ -f /var/lock/.clean ] && { log_end_msg 0 ; exit 0 ; } + +ES=0 +[ -d /tmp ] && ! [ -f /tmp/.clean ] && { clean_tmp || ES=1 ; } +[ -d /var/run ] && ! [ -f /var/run/.clean ] && { clean_run || ES=1 ; } +[ -d /var/lock ] && ! [ -f /var/lock/.clean ] && { clean_lock || ES=1 ; } +log_end_msg $ES +exit $ES diff --git a/beagle/debian-rfs/lib/init/mount-functions.sh b/beagle/debian-rfs/lib/init/mount-functions.sh new file mode 100644 index 0000000..007d127 --- /dev/null +++ b/beagle/debian-rfs/lib/init/mount-functions.sh @@ -0,0 +1,165 @@ +# +# Functions used by several mount* scripts in initscripts package +# +# Sourcer must source /lib/lsb/init-functions.sh + +# $1: directory +is_empty_dir() { + for FILE in $1/* $1/.* + do + case "$FILE" in + "$1/.*") return 0 ;; + "$1/*"|"$1/."|"$1/..") continue ;; + *) return 1 ;; + esac + done + return 0 +} + + +selinux_enabled () { + which selinuxenabled >/dev/null 2>&1 && selinuxenabled +} + + +# Called before mtab is writable to mount kernel and device file systems. +# $1: file system type +# $2: alternative file system type (or empty string if none) +# $3: mount point +# $4: mount device name +# $5... : extra mount program options +domount () { + MTPT="$3" + KERNEL="$(uname -s)" + # Figure out filesystem type + FSTYPE= + if [ "$1" = proc ] + then + case "$KERNEL" in + Linux|GNU) FSTYPE=proc ;; + *FreeBSD) FSTYPE=linprocfs ;; + *) FSTYPE=procfs ;; + esac + elif [ "$1" = tmpfs ] + then # always accept tmpfs, to mount /lib/init/rw before /proc + FSTYPE=$1 + elif grep -E -qs "$1\$" /proc/filesystems + then + FSTYPE=$1 + elif grep -E -qs "$2\$" /proc/filesystems + then + FSTYPE=$2 + fi + + if [ ! "$FSTYPE" ] + then + if [ "$2" ] + then + log_warning_msg "Filesystem types '$1' and '$2' are not supported. Skipping mount." + else + log_warning_msg "Filesystem type '$1' is not supported. Skipping mount." + fi + return + fi + + # We give file system type as device name if not specified as + # an argument + if [ "$4" ] ; then + DEVNAME=$4 + else + DEVNAME=$FSTYPE + fi + + # Get the options from /etc/fstab. + OPTS= + if [ -f /etc/fstab ] + then + exec 9<&0 </etc/fstab + + while read TAB_DEV TAB_MTPT TAB_FSTYPE TAB_OPTS TAB_REST + do + case "$TAB_DEV" in (""|\#*) continue ;; esac + [ "$MTPT" = "$TAB_MTPT" ] || continue + [ "$FSTYPE" = "$TAB_FSTYPE" ] || continue + case "$TAB_OPTS" in + noauto|*,noauto|noauto,*|*,noauto,*) + exec 0<&9 9<&- + return + ;; + ?*) + OPTS="-o$TAB_OPTS" + ;; + esac + break + done + + exec 0<&9 9<&- + fi + + if [ ! -d "$MTPT" ] + then + log_warning_msg "Mount point '$MTPT' does not exist. Skipping mount." + return + fi + + if mountpoint -q "$MTPT" + then + return # Already mounted + fi + + if [ "$VERBOSE" != "no" ]; then + is_empty_dir "$MTPT" >/dev/null 2>&1 || log_warning_msg "Files under mount point '$MTPT' will be hidden." + fi + mount -n -t $FSTYPE $5 $OPTS $DEVNAME $MTPT + if [ "$FSTYPE" = "tmpfs" -a -x /sbin/restorecon ]; then + /sbin/restorecon $MTPT + fi +} + +# +# Preserve /var/run and /var/lock mountpoints +# +pre_mountall () +{ + # We may end up mounting something over top of /var, either directly + # or because /var is a symlink to something that's mounted. So keep + # copies of the /var/run and /var/lock mounts elsewhere on the root + # filesystem so they can be moved back. + if [ yes = "$RAMRUN" ] ; then + mkdir /lib/init/rw/var.run + mount -n --bind /var/run /lib/init/rw/var.run + fi + if [ yes = "$RAMLOCK" ] ; then + mkdir /lib/init/rw/var.lock + mount -n --bind /var/lock /lib/init/rw/var.lock + fi +} + +# +# Restore /var/run and /var/lock mountpoints if something was mounted +# as /var/. Avoid mounting them back over themselves if nothing was +# mounted as /var/ by checking if /var/run/ and /var/lock/ are still +# mount points. Enabling RAMRUN and RAMLOCK while listing /var/run or +# /var/lock in /etc/fstab is not supported. +# +post_mountall () +{ + if [ yes = "$RAMRUN" ] ; then + [ -d /var/run ] || mkdir /var/run + if mountpoint -q /var/run ; then + umount /lib/init/rw/var.run + else + mount -n --move /lib/init/rw/var.run /var/run + fi + rmdir /lib/init/rw/var.run + fi + if [ yes = "$RAMLOCK" ] ; then + [ -d /var/lock ] || mkdir /var/lock + if mountpoint -q /var/lock ; then + umount /lib/init/rw/var.lock + else + mount -n --move /lib/init/rw/var.lock /var/lock + fi + rmdir /lib/init/rw/var.lock + fi +} diff --git a/beagle/debian-rfs/lib/init/splash-functions-base b/beagle/debian-rfs/lib/init/splash-functions-base new file mode 100644 index 0000000..8319dab --- /dev/null +++ b/beagle/debian-rfs/lib/init/splash-functions-base @@ -0,0 +1,93 @@ +# This script contains hooks to allow init scripts to control +# a splash program during boot and shutdown. +# +# To override these, provide a /lib/init/splash-functions scripts +# with new functions (it is sourced at the end of this file) +# +# Note that scripts have a number of constraints: +# 1) Should avoid using any binaries not found in the initramfs so that +# the same hooks can be used there. +# 2) This also means that bashisms can't be used. +# 3) Scripts must work when running under "set -e". +# 4) "local" should be used to avoid overwriting global variables. + + +# Detects whether a splash is running +splash_running() { return 1; } + +# Tells the splash to quit +splash_stop() { return 0; } + +# Tells the splash to start if not already running +splash_start() { return 1; } + +# Tells the splash the current boot/shutdown progress +# $1 contains the progress as a percentage value between -100 and 100 +# Positive values indicate boot progress +# Negative values indicate shutdown progress +splash_progress() +{ + local progress tmp + progress="$1" + + splash_running || return 0 + + # Sanity check step 1 - must match ^-[0-9]*$ + tmp="$progress" + + # Strip trailing numbers + while [ "${tmp%[0-9]}" != "$tmp" ]; do + tmp="${tmp%[0-9]}" + done + + # Now "-" or no characters should remain + if [ -n "$tmp" ] && [ "$tmp" != "-" ]; then + return 1 + fi + + # Sanity check step 2 - check for values >= -100 and <= 100 + if [ "$progress" != "${progress#-}" ]; then + # Negative value + if [ "$progress" -lt -100 ]; then + return 1 + fi + else + # Positive value + if [ "$progress" -gt 100 ]; then + return 1 + fi + fi + + # Sanity checks passed + custom_splash_progress "$progress" || return 1 + return 0 +} + +# Customizations should replace this function instead of splash_progress above +custom_splash_progress() { return 0; } + + +# Tells the splash that a task which may take an unknown amount of +# time has started (such as a fsck). This is useful to make sure the +# splash doesn't time out and to give visual feedback to the user. +splash_start_indefinite() { return 0; } + +# Tells the splash that an indefinite task is done +splash_stop_indefinite() { return 0; } + +# Gets user input from a splash +# $1 contains the text for the user prompt +# $2 describes the type of input: +# regular = regular input, e.g. a user name +# password = input which should not be echoed to screen, e.g. a password +# enter = A "press enter to continue" type of prompt +# +# Returns 1 if no user input is possible +# Should be called with an alternative non-splash input fallback: +# INPUT="$(splash_user_input "Enter password:" password)" || \ +# INPUT="$(manual_method)" +splash_user_input() { return 1; } + +# Allow these functions to be overridden with custom scripts. This is +# the official API hook. +if [ -e /lib/init/splash-functions ] ; then . /lib/init/splash-functions ; fi diff --git a/beagle/debian-rfs/lib/init/swap-functions.sh b/beagle/debian-rfs/lib/init/swap-functions.sh new file mode 100644 index 0000000..48a2326 --- /dev/null +++ b/beagle/debian-rfs/lib/init/swap-functions.sh @@ -0,0 +1,28 @@ +# +# Functions that assist in turning on swap. +# + +# $1 is a string used to log the type of swap expected to be activated +swaponagain() { + # + # Execute swapon command again to pick up any swap partitions + # that have shown up since the last swapon. + # + # Ignore 255 status due to swap already being enabled + # + if [ "$NOSWAP" = yes ] + then + [ "$VERBOSE" = no ] || log_warning_msg "Not activating swap as requested via bootoption noswap." + else + if [ "$VERBOSE" = no ] + then + log_action_begin_msg "Activating $1 swap" + swapon -a -e 2>/dev/null || : # Stifle "Device or resource busy" + log_action_end_msg 0 + else + log_daemon_msg "Will now activate $1 swap" + swapon -a -e -v + log_action_end_msg $? + fi + fi +} diff --git a/beagle/debian-rfs/lib/init/usplash-fsck-functions.sh b/beagle/debian-rfs/lib/init/usplash-fsck-functions.sh new file mode 100644 index 0000000..7235e20 --- /dev/null +++ b/beagle/debian-rfs/lib/init/usplash-fsck-functions.sh @@ -0,0 +1,178 @@ +# +# Functions for reporting fsck progress in usplash +# +# (C) 2008 Canonical Ltd. +# Author: Martin Pitt <martin.pitt@ubuntu.com> +# + +# convert a "pass cur max" progress triple from fsck to a progress percentage +# based on calc_percent() from e2fsck +fsck_progress_to_percent() { + if [ $1 = 1 ]; then + PERCENT=$(($2 * 70 / $3)) + elif [ $1 = 2 ]; then + PERCENT=$(($2 * 20 / $3 + 70)) + elif [ $1 = 3 ]; then + PERCENT=$(($2 * 2 / $3 + 90)) + elif [ $1 = 4 ]; then + PERCENT=$(($2 * 3 / $3 + 92)) + elif [ $1 = 5 ]; then + PERCENT=$(($2 * 5 / $3 + 95)) + else + PERCENT=100 + fi +} + +# read current fsck status ($PASS, $CUR, $MAX) from file descriptor 4 +# this assumes that fsck was started in the background ($!) +get_fsck_status() +{ + local a b c S + + unset a + # only consider the last line + while true; do + PASS=$a + CUR=$b + MAX=$c + read a b c rest <&4 + if [ -n "$PASS" ] && [ -z "$a" ]; then + break; + fi + + # if we did not read anything, check if the process is still + # actually running, or just waiting to be reaped + if [ -z "$PASS" ] && [ -z "$a" ]; then + S=`ps -o state --no-headers -p $!` || break + [ "$S" != "Z" ] || break + # do not spin while waiting for fsck to start up + sleep 0.1 + fi + done +} + +# Set $NAME to a human readable description of which partitions are currently +# being checked. Set $CLEAN if this is only a routine check on clean +# partitions which can be skipped. +get_checked_names () +{ + local DEVS DUMP LABEL + + FSCKPROCS=$(ps --no-headers -C 'fsck.ext2 fsck.ext3 fsck.ext4 fsck.ext4dev' -o pid,args | grep /dev) + DEVS=$(echo "$FSCKPROCS" | sed 's_^.*\(/dev/[^[:space:]]*\).*$_\1_') + FSCKPIDS=$(echo "$FSCKPROCS" | sed 's_^[[:space:]]*\([[:digit:]]\+\).*$_\1_') + + if [ -z "$DEVS" ]; then + unset NAME + return 0 + fi + + CLEAN=1 + unset NAME + for DEV in $DEVS; do + DUMP=$(dumpe2fs -h $DEV) + if ! echo "$DUMP" | grep -q 'state:[[:space:]]*clean$'; then + unset CLEAN + fi + + LABEL=$(blkid $DEV | sed -rn '/LABEL="([^"]+)"/ { s/^.*LABEL="//; s/".*$//; p }') + [ -z "$NAME" ] || NAME="$NAME, " + if [ -n "$LABEL" ]; then + NAME="$NAME$LABEL ($DEV)" + else + NAME="$NAME$DEV" + fi + done +} + +# Return true if usplash is active +usplash_running() { + if pidof usplash ; then + return 0 + else + return 1 + fi +} + +# Read fsck progress from file $1 and display progress in usplash. +usplash_progress() { + exec 4<$1 + unset CANCEL + ESCAPE=`/bin/echo -ne "\x1B"` + FIRST=1 + PREVPERCENT=0 + + while true; do + sleep 0.5 + get_fsck_status + [ -n "$PASS" ] || break + + fsck_progress_to_percent "$PASS" "$CUR" "$MAX" + + # check if fsck advanced to the next drive + if [ "$PREVPERCENT" -gt "$PERCENT" ]; then + if [ -n "$CANCEL" ]; then + usplash_write "STATUS skip " + else + usplash_write "STATUS " + fi + FIRST=1 + fi + PREVPERCENT=$PERCENT + + # lazy initialization of output and progress report on the first + # progress line that we receive; this avoids starting the output + # for clean or non-ext[234] partitions + if [ -n "$FIRST" ]; then + usplash_write "TIMEOUT 0" + + # show which device is being checked + get_checked_names + [ -n "$NAME" ] || break + + usplash_write "VERBOSE on" + if [ "$CLEAN" ]; then + usplash_write "TEXT Routine check of drives: $NAME..." + usplash_write "TEXT Press ESC to skip" + else + usplash_write "TEXT Unclean shutdown, checking drives:" + usplash_write "TEXT $NAME..." + fi + + unset FIRST + fi + + usplash_write "STATUS $PERCENT% (stage $PASS/5, $CUR/$MAX) " + echo "Checking drive $NAME: $PERCENT% (stage $PASS/5, $CUR/$MAX)" >/dev/console + + # ESC interrupts check for clean drives + if [ -n "$CLEAN" ]; then + if FAIL_NO_USPLASH=1 usplash_write "INPUTCHAR"; then + read ch < /dev/.initramfs/usplash_outfifo + if [ "$ch" = "$ESCAPE" ]; then + kill $FSCKPIDS + CANCEL=1 + continue # there might be more drives, so do not break + fi + fi + fi + done + + if [ -n "$CANCEL" ]; then + usplash_write "STATUS skip " + else + usplash_write "STATUS " + fi + usplash_write "VERBOSE default" + usplash_write "TEXT Drive checks finished." + usplash_write "TIMEOUT 15" + wait %1 # to collect fsck's exit code + EXITCODE=$? + [ -n "$CANCEL" ] && FSCKCODE=0 || FSCKCODE=$EXITCODE + if [ "$FSCKCODE" -gt 1 ]; then + # non-correctable failure which requires sulogin: quit usplash and + # restore stdin/out/err + usplash_write "QUIT" + exec </dev/console >/dev/console 2>/dev/console + fi +} diff --git a/beagle/debian-rfs/lib/init/vars.sh b/beagle/debian-rfs/lib/init/vars.sh new file mode 100644 index 0000000..1b4769b --- /dev/null +++ b/beagle/debian-rfs/lib/init/vars.sh @@ -0,0 +1,39 @@ +# +# Set rcS vars +# + +# Source conffile +if [ -f /etc/default/rcS ]; then + . /etc/default/rcS +fi + +# Parse kernel command line +if [ -r /proc/cmdline ]; then + for ARG in $(cat /proc/cmdline); do + case $ARG in + + # check for bootoption 'noswap' and do not activate swap + # partitions/files when it is set. + noswap) + NOSWAP=yes + break + ;; + + # Accept the same 'quiet' option as the kernel, but only + # during boot and shutdown. Only use this rule when the + # variables set by init.d/rc is present. + quiet) + if [ "$RUNLEVEL" ] && [ "$PREVLEVEL" ] ; then + VERBOSE="no" + fi + break + ;; + esac + done +fi + +# But allow both rcS and the kernel options 'quiet' to be overrided +# when INIT_VERBOSE=yes is used as well. +if [ "$INIT_VERBOSE" ] ; then + VERBOSE="$INIT_VERBOSE" +fi |
