aboutsummaryrefslogtreecommitdiff
path: root/rc.lib
blob: 8fa85bfc92ea0786d689d5383ee20c7062a11abf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# 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() { printf '\033[1;36m-> \033[39m%s\033[m\n' "$@" | log ;}
err() { printf '\033[1;31m!> \033[39m%s\033[m\n' "$@" | log ;}

shell() {
    err "Dropping to shell, type 'exit' to continue the boot process."
    sh -l
}

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
}

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
}

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
    for arg in $(cat /proc/cmdline); do
        case "$arg" in
            ro) RO=1 ;;
            forcefsck) FORCEFSCK="-f" ;;
            fastboot)  FASTBOOT=1 ;;
            loglevel=?) dmesg_level=${arg##*=} ;;
        esac
    done
}

mnt() {
    [ -f /proc/mounts ] && while read -r _ mnt _; do
        case "$mnt" in "$1") return 0; esac
    done < /proc/mounts

    mnt="$1"; shift
    mount "$@" "$mnt" 2>&1 | log
}