]> git.ipfire.org Git - thirdparty/dracut.git/blame - modules.d/99base/init.sh
use "rm --" to guard against filenames beginning with "-"
[thirdparty/dracut.git] / modules.d / 99base / init.sh
CommitLineData
7f64a3fe 1#!/bin/sh
cc02093d
HH
2# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3# ex: ts=8 sw=4 sts=4 et filetype=sh
a5e56335
JK
4#
5# Licensed under the GPLv2
6#
cc02093d 7# Copyright 2008-2010, Red Hat, Inc.
ac36d5db 8# Harald Hoyer <harald@redhat.com>
a5e56335 9# Jeremy Katz <katzj@redhat.com>
ec9315e5 10
ed42e64c
HH
11export -p > /tmp/export.orig
12
bb040f93 13NEWROOT="/sysroot"
4826b9b0 14[ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT
bb040f93 15
182660d8
HH
16OLDPATH=$PATH
17PATH=/usr/sbin:/usr/bin:/sbin:/bin
18export PATH
a890fe29 19
ec9315e5 20# mount some important things
a6c34848 21[ ! -d /proc/self ] && \
c204501e
HH
22 mount -t proc -o nosuid,noexec,nodev proc /proc >/dev/null
23
24if [ "$?" != "0" ]; then
25 echo "Cannot mount proc on /proc! Compile the kernel with CONFIG_PROC_FS!"
26 exit 1
27fi
a6c34848
HH
28
29[ ! -d /sys/kernel ] && \
c204501e
HH
30 mount -t sysfs -o nosuid,noexec,nodev sysfs /sys >/dev/null
31
32if [ "$?" != "0" ]; then
33 echo "Cannot mount sysfs on /sys! Compile the kernel with CONFIG_SYSFS!"
34 exit 1
35fi
a6c34848 36
cd9072d3
CG
37RD_DEBUG=""
38. /lib/dracut-lib.sh
39
6c6d8057
HH
40if [ -x $systemdutildir/systemd-timestamp ]; then
41 RD_TIMESTAMP=$($systemdutildir/systemd-timestamp)
b2415f44
HH
42else
43 read RD_TIMESTAMP _tmp < /proc/uptime
44 unset _tmp
45fi
647bef8c 46
543f39cb
HH
47setdebug
48
dbad9f46 49if ! ismounted /dev; then
c204501e
HH
50 mount -t devtmpfs -o mode=0755,nosuid,strictatime devtmpfs /dev >/dev/null
51fi
52
53if ! ismounted /dev; then
54 echo "Cannot mount devtmpfs on /dev! Compile the kernel with CONFIG_DEVTMPFS!"
55 exit 1
3473f5d9 56fi
d0e2110a 57
77364fd6
WC
58# setup system time
59if [ -f /etc/adjtime ]; then
60 if strstr "$(cat /etc/adjtime)" LOCAL; then
61 hwclock --hctosys --localtime
62 else
63 hwclock --hctosys --utc
64 fi
65fi
66
4af673c3 67# prepare the /dev directory
dbad9f46
HH
68[ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd >/dev/null 2>&1
69[ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin >/dev/null 2>&1
70[ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout >/dev/null 2>&1
71[ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr >/dev/null 2>&1
72
73if ! ismounted /dev/pts; then
74 mkdir -m 0755 /dev/pts
dee929cd 75 mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts >/dev/null
dbad9f46
HH
76fi
77
78if ! ismounted /dev/shm; then
79 mkdir -m 0755 /dev/shm
7f217d77 80 mount -t tmpfs -o mode=1777,nosuid,nodev,strictatime tmpfs /dev/shm >/dev/null
dbad9f46
HH
81fi
82
83if ! ismounted /run; then
84 mkdir -m 0755 /newrun
7f217d77 85 mount -t tmpfs -o mode=0755,nosuid,nodev,strictatime tmpfs /newrun >/dev/null
56bf6156 86 cp -a /run/* /newrun >/dev/null 2>&1
dbad9f46 87 mount --move /newrun /run
32bd2fbb 88 rm -fr -- /newrun
dbad9f46 89fi
77e607a3 90
9d787df1 91trap "action_on_fail Signal caught!" 0
c204501e 92
dd483f4f 93[ -d /run/initramfs ] || mkdir -p -m 0755 /run/initramfs
a005c477 94[ -d /run/log ] || mkdir -p -m 0755 /run/log
dd483f4f 95
579238a3 96export UDEVVERSION=$(udevadm --version)
0afae1c7 97if [ $UDEVVERSION -gt 166 ]; then
19f3a804 98 # newer versions of udev use /run/udev/rules.d
19f3a804 99 export UDEVRULESD=/run/udev/rules.d
dd483f4f
HH
100 [ -d /run/udev ] || mkdir -p -m 0755 /run/udev
101 [ -d $UDEVRULESD ] || mkdir -p -m 0755 $UDEVRULESD
77e607a3 102else
3b403b32 103 mkdir -m 0755 /dev/.udev /dev/.udev/rules.d
77e607a3
HH
104 export UDEVRULESD=/dev/.udev/rules.d
105fi
106
a6c34848 107if [ "$RD_DEBUG" = "yes" ]; then
7eb40c48
HH
108 mkfifo /run/initramfs/loginit.pipe
109 loginit $DRACUT_QUIET </run/initramfs/loginit.pipe >/dev/console 2>&1 &
110 exec >/run/initramfs/loginit.pipe 2>&1
ac36d5db
HH
111else
112 exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
4592b698 113fi
ac36d5db 114
982d59af 115[ -f /etc/initrd-release ] && . /etc/initrd-release
cc6f0925 116[ -n "$VERSION_ID" ] && info "$NAME-$VERSION_ID"
982d59af 117
0375106c
HH
118source_conf /etc/conf.d
119
e4502814 120# run scriptlets to parse the command line
bbfff3e5 121make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab'
68e7661c 122getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline"
0b53ca70 123source_hook cmdline
e4502814 124
0fd1ab9d
PS
125[ -z "$root" ] && die "No or empty root= argument"
126[ -z "$rootok" ] && die "Don't know how to handle 'root=$root'"
d15c7a1a 127
2c031721 128export root rflags fstype netroot NEWROOT
7d7efa4a 129
a08c1f45 130# pre-udev scripts run before udev starts, and are run only once.
bbfff3e5 131make_trace_mem "hook pre-udev" '1:shortmem' '2+:mem' '3+:slab'
68e7661c 132getarg 'rd.break=pre-udev' -d 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break before pre-udev"
0b53ca70 133source_hook pre-udev
ec1ad334 134
ec9315e5 135# start up udev and trigger cold plugs
6c6d8057 136$systemdutildir/systemd-udevd --daemon --resolve-names=never
2a652c0b
HH
137
138UDEV_LOG_PRIO_ARG=--log-priority
139UDEV_QUEUE_EMPTY="udevadm settle --timeout=0"
140
141if [ $UDEVVERSION -lt 140 ]; then
cc02093d
HH
142 UDEV_LOG_PRIO_ARG=--log_priority
143 UDEV_QUEUE_EMPTY="udevadm settle --timeout=1"
2a652c0b
HH
144fi
145
68e7661c
HH
146getargbool 0 rd.udev.info -d -y rdudevinfo && udevadm control "$UDEV_LOG_PRIO_ARG=info"
147getargbool 0 rd.udev.debug -d -y rdudevdebug && udevadm control "$UDEV_LOG_PRIO_ARG=debug"
2a9b7039 148udevproperty "hookdir=$hookdir"
1eeddd31 149
bbfff3e5 150make_trace_mem "hook pre-trigger" '1:shortmem' '2+:mem' '3+:slab'
68e7661c 151getarg 'rd.break=pre-trigger' -d 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break before pre-trigger"
0b53ca70 152source_hook pre-trigger
1eeddd31 153
11c0e7d4 154udevadm control --reload >/dev/null 2>&1 || :
1eeddd31 155# then the rest
ab55a117
HH
156udevadm trigger --type=subsystems --action=add >/dev/null 2>&1
157udevadm trigger --type=devices --action=add >/dev/null 2>&1
eab677a2 158
bbfff3e5 159make_trace_mem "hook initqueue" '1:shortmem' '2+:mem' '3+:slab'
68e7661c 160getarg 'rd.break=initqueue' -d 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue"
53e1c5b9 161
68e7661c 162RDRETRY=$(getarg rd.retry -d 'rd_retry=')
5cd7c104 163RDRETRY=${RDRETRY:-30}
85fd75f9 164RDRETRY=$(($RDRETRY*2))
6b592c14
HH
165export RDRETRY
166main_loop=0
167export main_loop
58dbb43e 168while :; do
58dbb43e 169
8238850c 170 check_finished && break
3b403b32 171
5c6a593f 172 udevsettle
89056045 173
8238850c
HH
174 check_finished && break
175
0b53ca70 176 if [ -f $hookdir/initqueue/work ]; then
32bd2fbb 177 rm -f -- $hookdir/initqueue/work
58dbb43e 178 fi
3b403b32 179
0b53ca70 180 for job in $hookdir/initqueue/*.sh; do
cc02093d 181 [ -e "$job" ] || break
58dbb43e 182 job=$job . $job
8238850c 183 check_finished && break 2
58dbb43e
HH
184 done
185
8238850c 186 $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue
71094bee 187
0b53ca70 188 for job in $hookdir/initqueue/settled/*.sh; do
040f3d2f
HH
189 [ -e "$job" ] || break
190 job=$job . $job
191 check_finished && break 2
192 done
193
194 $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue
195
8238850c
HH
196 # no more udev jobs and queues empty.
197 sleep 0.5
0e0bf830 198
3b403b32 199
5cd7c104 200 if [ $main_loop -gt $((2*$RDRETRY/3)) ]; then
54f1a77f 201 for job in $hookdir/initqueue/timeout/*.sh; do
6b592c14
HH
202 [ -e "$job" ] || break
203 job=$job . $job
f62f3a21 204 udevadm settle --timeout=0 >/dev/null 2>&1 || main_loop=0
500861cd 205 [ -f $hookdir/initqueue/work ] && main_loop=0
54f1a77f 206 done
6b592c14
HH
207 fi
208
209 main_loop=$(($main_loop+1))
210 [ $main_loop -gt $RDRETRY ] \
9d787df1 211 && { flock -s 9 ; action_on_fail "Could not boot." && break; } 9>/.console_lock
58dbb43e
HH
212done
213unset job
214unset queuetriggered
6b592c14
HH
215unset main_loop
216unset RDRETRY
ec9315e5 217
a08c1f45
VL
218# pre-mount happens before we try to mount the root filesystem,
219# and happens once.
bbfff3e5 220make_trace_mem "hook pre-mount" '1:shortmem' '2+:mem' '3+:slab'
68e7661c 221getarg 'rd.break=pre-mount' -d 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break pre-mount"
0b53ca70 222source_hook pre-mount
bb040f93 223
a3a3448d 224
68e7661c 225getarg 'rd.break=mount' -d 'rdbreak=mount' && emergency_shell -n mount "Break mount"
a08c1f45
VL
226# mount scripts actually try to mount the root filesystem, and may
227# be sourced any number of times. As soon as one suceeds, no more are sourced.
87930555 228i=0
a08c1f45 229while :; do
f8342dd5
MS
230 if ismounted "$NEWROOT"; then
231 usable_root "$NEWROOT" && break;
232 umount "$NEWROOT"
233 fi
0b53ca70 234 for f in $hookdir/mount/*.sh; do
cc02093d 235 [ -f "$f" ] && . "$f"
f8342dd5
MS
236 if ismounted "$NEWROOT"; then
237 usable_root "$NEWROOT" && break;
238 warn "$NEWROOT has no proper rootfs layout, ignoring and removing offending mount hook"
239 umount "$NEWROOT"
32bd2fbb 240 rm -f -- "$f"
f8342dd5 241 fi
a08c1f45 242 done
bb040f93 243
7cd15fe7 244 i=$(($i+1))
a3a3448d 245 [ $i -gt 20 ] \
9d787df1 246 && { flock -s 9 ; action_on_fail "Can't mount root filesystem" && break; } 9>/.console_lock
a08c1f45
VL
247done
248
0b2de1f8
HH
249{
250 echo -n "Mounted root filesystem "
3b403b32 251 while read dev mp rest; do [ "$mp" = "$NEWROOT" ] && echo $dev; done < /proc/mounts
0b2de1f8
HH
252} | vinfo
253
2e7257a2
DY
254# pre pivot scripts are sourced just before we doing cleanup and switch over
255# to the new root.
bbfff3e5 256make_trace_mem "hook pre-pivot" '1:shortmem' '2+:mem' '3+:slab'
68e7661c 257getarg 'rd.break=pre-pivot' -d 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break pre-pivot"
0b53ca70 258source_hook pre-pivot
88ffd2df 259
bbfff3e5 260make_trace_mem "hook cleanup" '1:shortmem' '2+:mem' '3+:slab'
2e7257a2 261# pre pivot cleanup scripts are sourced just before we switch over to the new root.
68e7661c 262getarg 'rd.break=cleanup' -d 'rdbreak=cleanup' && emergency_shell -n cleanup "Break cleanup"
eef7649e 263source_hook cleanup
2e7257a2 264
470ee2d2
HH
265# By the time we get here, the root filesystem should be mounted.
266# Try to find init.
4951a119 267for i in "$(getarg real_init=)" "$(getarg init=)" $(getargs rd.distroinit=) /sbin/init; do
2c1f37d4 268 [ -n "$i" ] || continue
40ee8c18 269
470ee2d2 270 __p=$(readlink -f "${NEWROOT}/${i}")
cfede42f 271 if [ -x "$__p" -o -x "${NEWROOT}/${__p}" ]; then
7f7a91b7
HH
272 INIT="$i"
273 break
274 fi
d05f3c43 275done
0b2de1f8 276
6b0daf2e 277[ "$INIT" ] || {
a3a3448d
HH
278 echo "Cannot find init!"
279 echo "Please check to make sure you passed a valid root filesystem!"
9d787df1 280 action_on_fail
6b0daf2e 281}
a08c1f45 282
6a168568
HH
283if [ $UDEVVERSION -lt 168 ]; then
284 # stop udev queue before killing it
285 udevadm control --stop-exec-queue
286
287 HARD=""
ecc6da6b
HH
288 while pidof systemd-udevd >/dev/null 2>&1; do
289 for pid in $(pidof systemd-udevd); do
6a168568
HH
290 kill $HARD $pid >/dev/null 2>&1
291 done
292 HARD="-9"
7e87a0bf 293 done
6a168568
HH
294else
295 udevadm control --exit
296 udevadm info --cleanup-db
297fi
5fa49940 298
476eb1b3
HH
299debug_off # Turn off debugging for this section
300
301# unexport some vars
302export_n root rflags fstype netroot NEWROOT
4e25cf6e 303
bf512ee2 304export RD_TIMESTAMP
5fa49940
AT
305# Clean up the environment
306for i in $(export -p); do
307 i=${i#declare -x}
c79517b4 308 i=${i#export}
77e2cadd 309 strstr "$i" "=" || continue
c79517b4 310 i=${i%%=*}
77e2cadd
HH
311 [ -z "$i" ] && continue
312 case $i in
313 root|PATH|HOME|TERM|PS4|RD_*)
314 :;;
315 *)
316 unset "$i";;
317 esac
5fa49940 318done
dffb93fe 319. /tmp/export.orig 2>/dev/null || :
32bd2fbb 320rm -f -- /tmp/export.orig
5fa49940 321
faf88239 322initargs=""
b63fd4d9 323read CLINE </proc/cmdline
247c9f70
HH
324if getarg init= >/dev/null ; then
325 ignoreargs="console BOOT_IMAGE"
326 # only pass arguments after init= to the init
247c9f70 327 CLINE=${CLINE#*init=}
7573ac58
WW
328 set -- $CLINE
329 shift # clear out the rest of the "init=" arg
330 for x in "$@"; do
331 for s in $ignoreargs; do
332 [ "${x%%=*}" = $s ] && continue 2
247c9f70 333 done
7573ac58
WW
334 initargs="$initargs $x"
335 done
336 unset CLINE
b63fd4d9 337else
c32908ce 338 debug_off # Turn off debugging for this section
7573ac58 339 set -- $CLINE
b63fd4d9
AB
340 for x in "$@"; do
341 case "$x" in
cc02093d 342 [0-9]|s|S|single|emergency|auto ) \
b63fd4d9 343 initargs="$initargs $x"
cc02093d 344 ;;
b63fd4d9
AB
345 esac
346 done
247c9f70 347fi
c32908ce 348debug_on
3b403b32 349
abbb76fe 350if ! [ -d "$NEWROOT"/run ]; then
dbad9f46
HH
351 NEWRUN=/dev/.initramfs
352 mkdir -m 0755 "$NEWRUN"
abbb76fe 353 mount --rbind /run/initramfs "$NEWRUN"
dbad9f46 354fi
0b2de1f8 355
ac36d5db 356wait_for_loginit
3b403b32 357
6d82a047 358# remove helper symlink
32bd2fbb 359[ -h /dev/root ] && rm -f -- /dev/root
6d82a047 360
68e7661c 361getarg rd.break -d rdbreak && emergency_shell -n switch_root "Break before switch_root"
dbad9f46 362info "Switching root"
3b403b32 363
56ac6c7e 364
dbad9f46 365unset PS4
19f3a804 366
dbad9f46
HH
367CAPSH=$(command -v capsh)
368SWITCH_ROOT=$(command -v switch_root)
369PATH=$OLDPATH
370export PATH
98537743 371
529349c6
HH
372if [ -f /etc/capsdrop ]; then
373 . /etc/capsdrop
374 info "Calling $INIT with capabilities $CAPS_INIT_DROP dropped."
9e7a3bf2 375 unset RD_DEBUG
dbad9f46
HH
376 exec $CAPSH --drop="$CAPS_INIT_DROP" -- \
377 -c "exec switch_root \"$NEWROOT\" \"$INIT\" $initargs" || \
378 {
529349c6
HH
379 warn "Command:"
380 warn capsh --drop=$CAPS_INIT_DROP -- -c exec switch_root "$NEWROOT" "$INIT" $initargs
381 warn "failed."
9d787df1 382 action_on_fail
529349c6
HH
383 }
384else
9e7a3bf2 385 unset RD_DEBUG
dbad9f46 386 exec $SWITCH_ROOT "$NEWROOT" "$INIT" $initargs || {
529349c6
HH
387 warn "Something went very badly wrong in the initramfs. Please "
388 warn "file a bug against dracut."
9d787df1 389 action_on_fail
529349c6
HH
390 }
391fi