# -*- mode: sh -*- # rc.lib -- common functions for rc.boot and rc.shutdown # shellcheck disable=1090,2034 export PATH=$PATH:/usr/local/bin:/usr/bin # logger is provided by 3 packages on the core repository (sbase, # busybox, util-linux). However, it is optional. Since logger # outputs to stderr, we cannot silence stderr to not display error # messages in the rare case where it isn't available on the system. logger=$(command -v logger) || logger=: log() { # A function to log all output to syslog (if it is available) # and to kernel messages. This way the logs are readable after # reboot. # # The usability of this also depends on how early you start # syslogd and how late you stop it. I will be modifying this # to enable a way (or multiple ways) of storing boot/shutdown # logs in a persistent manner. # # Right now, you could possibly start a syslogd from the early # boot hooks which will be run right after filesystems are # mounted. # # If no arguments for the logger are specified, it will read # standard input for the log. This means you can pipe the output # of a command to this function. Those will be logged as well. [ "$1" ] && printf 'init: %s\n' "$@" >/dev/kmsg 2>/dev/null "$logger" -t init "${@:--s}" } out() { log "$1" [ "$quiet" = 1 ] && return printf '%b%s \033[39m%s\033[m\n' "${3:-"\033[1;36m"}" "${2:-->}" "$1" } err() { out "$1" "!>" "\033[1;31m" ;} device_helper() { # We devices based on user preference, and what's available # on the system. # # Get the device daemon to be used, if we don't have a daemon # available on the system, do not continue any further. [ "$devd" ] || { devd=$(command -v udevd) || devd=$(command -v mdev) || return 0 } case "$1" in settle) case "${devd##*/}" in udevd) udevd -d udevadm trigger -c add -t subsystems udevadm trigger -c add -t devices udevadm settle ;; mdev) mdev -s mdev -df & mdev_pid=$! ;; esac ;; exit) case "${devd##*/}" in udevd) udevadm control --exit ;; mdev) [ "$mdev_pid" ] && kill "$mdev_pid" command -v mdev > /proc/sys/kernel/hotplug ;; esac esac } mounted() { [ -e "$1" ] && [ -f /proc/mounts ] && while read -r _ mnt _; do case "$mnt" in "$1") return 0; esac done < /proc/mounts return 1 } mnt() { mounted "$4" && set -- "remount,$1" "$2" "$3" "$4" mount -o "$1" -t "$2" "$3" "$4" } parse_cmdline() { # This is a primitive way of parsing kernel command line # options. Before now, carbs-init ignored these options # set by the user. More will be added as needed. Init scripts # don't need to handle most of the command line options # as the kernel deals with most of them, but not things # such as mount options. [ -r /proc/cmdline ] || { err "Kernel command line options cannot be parsed" shell } # We want to read words instead of lines here. # shellcheck disable=2013 while read -r cmdline; do for arg in $cmdline; do case "$arg" in *=*) export "$arg" ;; *) export "$arg=1" ;; esac done done < /proc/cmdline } random() { seed=/var/random.seed case "$1" in load) out "Seeding random..." [ -f "$seed" ] || { out "Generating entropy, this might take a while..." dd count=1 bs=512 if=/dev/random of="$seed" 2>/dev/null } cat "$seed" > /dev/urandom ;; save) mkdir -p "${seed%/*}" out "Saving random seed..." dd count=1 bs=512 if=/dev/urandom of="$seed" 2>/dev/null ;; esac } run_hook() { out "Running '$1' hooks..." for hook in "/etc/init/"*".$1" "/usr/lib/init/hooks/"*".$1"; do [ -f "$hook" ] || continue out "Running '$hook'..." . "$hook" done } shell() { err "Dropping to shell, type 'exit' to continue the boot process." sh -l }