summaryrefslogtreecommitdiff
path: root/init
blob: 204d1750413871303d3c36ecfe1126d6afb1c58a (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
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/ash
# SPDX-License-Identifier: GPL-2.0-only

export PATH='/usr/local/sbin:/usr/local/bin:/usr/bin'

udevd_running=0
mount_handler=default_mount_handler
init=/sbin/init
rd_logmask=0

. /init_functions

mount_setup

# parse the kernel command line
parse_cmdline </proc/cmdline

# setup logging as early as possible
rdlogger_start

# busybox ash supports string replacements
# shellcheck disable=SC3060
# assigned by parse_cmdline
# shellcheck disable=SC2154
for d in ${disablehooks//,/ }; do
    [ -e "/hooks/$d" ] && chmod 644 "/hooks/$d"
done

# shellcheck disable=SC1091
. /config

# We rely on word splitting
# shellcheck disable=SC2086
run_hookfunctions 'run_earlyhook' 'early hook' $EARLYHOOKS

if [ -n "$earlymodules$MODULES" ]; then
    # busybox ash supports string replacements
    # shellcheck disable=SC3060,SC2086
    modprobe -qab ${earlymodules//,/ } $MODULES
fi

# We rely on word splitting
# shellcheck disable=SC2086
run_hookfunctions 'run_hook' 'hook' $HOOKS

# honor the old behavior of break=y as a synonym for break=premount
# assigned by parse_cmdline
# shellcheck disable=SC2154
if [ "${break}" = "y" ] || [ "${break}" = "premount" ]; then
    # shellcheck disable=SC2086
    run_hookfunctions 'run_emergencyhook' 'emergency hook' $EMERGENCYHOOKS
    echo ":: Pre-mount break requested, type 'exit' to resume operation"
    launch_interactive_shell
fi

if rootdev="$(resolve_device "$root")"; then
    # If the tag is supported by util-linux mount, pass it as is.
    # Otherwise, use the resolved device path.
    case "$root" in
        'UUID='* | 'LABEL='* | 'PARTUUID='* | 'PARTLABEL='*) : ;;
        *) root="$rootdev" ;;
    esac
fi
unset rootdev

fsck_root

# Mount root at /new_root
"$mount_handler" /new_root

# We rely on word splitting
# shellcheck disable=SC2086
run_hookfunctions 'run_latehook' 'late hook' $LATEHOOKS

# We rely on word splitting
# shellcheck disable=SC2086
run_hookfunctions 'run_cleanuphook' 'cleanup hook' $CLEANUPHOOKS

if [ "$(stat -c %D /)" = "$(stat -c %D /new_root)" ]; then
    # Nothing got mounted on /new_root. This is the end, we don't know what to do anymore
    # We fall back into a shell, but the shell has now PID 1
    # This way, manual recovery is still possible.
    # shellcheck disable=SC2086
    run_hookfunctions 'run_emergencyhook' 'emergency hook' $EMERGENCYHOOKS
    err "Failed to mount the real root device."
    echo "Bailing out, you are on your own. Good luck."
    echo
    launch_interactive_shell --exec
elif [ ! -x "/new_root${init}" ]; then
    # Successfully mounted /new_root, but ${init} is missing
    # The same logic as above applies
    # shellcheck disable=SC2086
    run_hookfunctions 'run_emergencyhook' 'emergency hook' $EMERGENCYHOOKS
    err "Root device mounted successfully, but ${init} does not exist."
    echo "Bailing out, you are on your own. Good luck."
    echo
    launch_interactive_shell --exec
fi

if [ "${break}" = "postmount" ]; then
    # shellcheck disable=SC2086
    run_hookfunctions 'run_emergencyhook' 'emergency hook' $EMERGENCYHOOKS
    echo ":: Post-mount break requested, type 'exit' to resume operation"
    launch_interactive_shell
fi

# this should always be the last thing we do before the switch_root.
rdlogger_stop

exec env -i \
    "TERM=$TERM" \
    /usr/bin/switch_root /new_root "$init" "$@"

# vim: set ft=sh ts=4 sw=4 et: