forked from illiliti/tinyramfs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinit
executable file
·131 lines (108 loc) · 3.16 KB
/
init
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/sh
#
# tiny init
#
# false positive
# shellcheck disable=2154
print()
{
printf "%b %s\n" "${2:-"\033[1;37m>>\033[m"}" "$1"
}
panic()
{
print "${1:-unexpected error occurred}" \
"\033[1;31m!!\033[m" >&2; sh
}
resolve_device()
{
count=0; device="$1"
case "${device%%=*}" in
UUID) device="/dev/disk/by-uuid/${device#*=}" ;;
LABEL) device="/dev/disk/by-label/${device#*=}" ;;
PARTUUID) device="/dev/disk/by-partuuid/${device#*=}" ;;
/dev/*) ;;
*) return 0 ;;
esac
# prevent race condition
while [ ! -b "$device" ]; do sleep 1
[ "$((count += 1))" = "${rootdelay:=30}" ] && {
panic "failed to lookup partition"
break
}
done || :
}
run_hook()
{
type="$1"
# run hooks if any
# false positive
# shellcheck disable=1090
for hook in $hooks; do
[ -f "/usr/share/tinyramfs/hooks/${hook}/${hook}.${type}" ] || continue
. "/usr/share/tinyramfs/hooks/${hook}/${hook}.${type}"
done
}
prepare_environment()
{
# false positive
# shellcheck disable=1091
. /etc/tinyramfs/config
export \
PATH=/bin TERM=linux SHELL=/bin/sh \
LANG=C LC_ALL=C PS1="# " HOME=/root
mount -t proc -o nosuid,noexec,nodev proc /proc
mount -t sysfs -o nosuid,noexec,nodev sys /sys
mount -t tmpfs -o nosuid,nodev,mode=0755 run /run
mount -t devtmpfs -o nosuid,noexec,mode=0755 dev /dev
ln -s /proc/self/fd /dev/fd
ln -s fd/0 /dev/stdin
ln -s fd/1 /dev/stdout
ln -s fd/2 /dev/stderr
}
parse_cmdline()
{
read -r cmdline < /proc/cmdline
for line in $cmdline; do case "$line" in
rootfstype=*) root_type="${line#*=}" ;;
rootflags=*) root_opts="${line#*=}" ;;
debug=1) set -x ;;
ro | rw) rorw="-o $line" ;;
--*) init_args="${cmdline#*-- }"; break ;;
*=*) command export "$line" ;;
*) command export "${line}=1" ;;
esac 2> /dev/null || :; done
}
mount_root()
{
[ "$break" = root ] && { print "break before mount_root()"; sh; }
resolve_device "$root"
set -- \
"${rorw:--o ro}${root_opts:+,$root_opts}" \
"${root_type:+-t $root_type}" "$device" "/mnt/root"
# word splitting is safe by design
# shellcheck disable=2068
mount $@ || panic "failed to mount root"
}
boot_system()
{
[ "$break" = boot ] && { print "break before boot_system()"; sh; }
for dir in run dev sys proc; do
mount -o move "$dir" "/mnt/root/${dir}"
done
set -- "/mnt/root" "${init:-/sbin/init}" "$init_args"
# POSIX exec has no -c flag to execute command with empty environment
# use 'env -i' to prevent leaking exported variables
# word splitting is safe by design
# shellcheck disable=2068
exec env -i TERM=linux PATH=/bin:/sbin:/usr/bin:/usr/sbin \
switch_root $@ || panic "failed to boot system"
}
# enable exit on error and disable globbing
# trap EXIT signal
set -ef; trap panic EXIT
prepare_environment
parse_cmdline
run_hook init
mount_root
run_hook init.late
boot_system