]> git.ipfire.org Git - thirdparty/dracut.git/blame - modules.d/99base/init
dracut: set TMPDIR to /var/tmp
[thirdparty/dracut.git] / modules.d / 99base / init
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
ac36d5db
HH
11wait_for_loginit()
12{
8f5d3689
HH
13 set +x
14 [ "$RD_DEBUG" = "yes" ] || return
7eb40c48 15 [ -e /run/initramfs/loginit.pipe ] || return
8f5d3689
HH
16 echo "DRACUT_LOG_END"
17 exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
cc02093d 18 # wait for loginit
8f5d3689 19 i=0
3b403b32 20 while [ $i -lt 10 ]; do
7eb40c48 21 if [ ! -e /run/initramfs/loginit.pipe ]; then
8f5d3689
HH
22 j=$(jobs)
23 [ -z "$j" ] && break
24 [ -z "${j##*Running*}" ] || break
25 fi
26 sleep 0.1
27 i=$(($i+1))
3b403b32 28 done
ac36d5db 29
8f5d3689
HH
30 if [ $i -eq 10 ]; then
31 kill %1 >/dev/null 2>&1
7eb40c48 32 kill $(while read line;do echo $line;done</run/initramfs/loginit.pid)
ac36d5db 33 fi
8f5d3689
HH
34
35 set -x
7eb40c48 36 rm -f /run/initramfs/loginit.pipe /run/initramfs/loginit.pid
ac36d5db
HH
37}
38
ec9315e5
JK
39emergency_shell()
40{
a382492b 41 set +e
5db587d7 42 if [ "$1" = "-n" ]; then
b5664d5d 43 _rdshell_name=$2
3b403b32 44 shift 2
b5664d5d
LB
45 else
46 _rdshell_name=dracut
47 fi
a3a3448d 48 echo ; echo
a382492b 49 warn $@
0b53ca70 50 source_hook emergency
81f83dab 51 echo
a382492b 52 wait_for_loginit
03f405bc 53 [ -e /run/initramfs/.die ] && exit 1
9b793450 54 if getargbool 1 rd.shell -y rdshell || getarg rd.break rdbreak; then
81f83dab 55 echo "Dropping to debug shell."
a3a3448d 56 echo
b5664d5d
LB
57 export PS1="$_rdshell_name:\${PWD}# "
58 [ -e /.profile ] || echo "exec 0<>/dev/console 1<>/dev/console 2<>/dev/console" > /.profile
59 sh -i -l
a3a3448d 60 else
a382492b
HH
61 warn "Boot has failed. To debug this issue add \"rdshell\" to the kernel command line."
62 # cause a kernel panic
63 exit 1
a3a3448d 64 fi
ec9315e5 65}
ec9315e5 66
bb040f93
HH
67NEWROOT="/sysroot"
68
a75c29be 69trap "emergency_shell Signal caught!" 0
182660d8
HH
70OLDPATH=$PATH
71PATH=/usr/sbin:/usr/bin:/sbin:/bin
72export PATH
a890fe29 73
36e30eb0 74RD_DEBUG=""
b8f39ef1 75. /lib/dracut-lib.sh
df44688f 76
5e1898fa 77[ -c /dev/null ] || mknod -m 0666 /dev/null c 1 3
a890fe29 78
ec9315e5 79# mount some important things
a6c34848
HH
80[ ! -d /proc/self ] && \
81 mount -t proc -o nosuid,noexec,nodev /proc /proc >/dev/null 2>&1
82
83[ ! -d /sys/kernel ] && \
84 mount -t sysfs -o nosuid,noexec,nodev /sys /sys >/dev/null 2>&1
85
86setdebug
87
88if [ "$RD_DEBUG" = "yes" ]; then
89 getarg quiet && DRACUT_QUIET="yes"
90 a=$(getarg loglevel=)
91 [ -n "$a" ] && [ $a -ge 8 ] && unset DRACUT_QUIET
92fi
a890fe29 93
b2415f44
HH
94if [ -x /lib/systemd/systemd-timestamp ]; then
95 RD_TIMESTAMP=$(/lib/systemd/systemd-timestamp)
96else
97 read RD_TIMESTAMP _tmp < /proc/uptime
98 unset _tmp
99fi
647bef8c 100
336eb5b0 101ismounted /sys || \
dbad9f46
HH
102 mount -t sysfs -o nosuid,noexec,nodev /sys /sys >/dev/null 2>&1
103
104if ! ismounted /dev; then
e0364f95 105 # try to mount devtmpfs
44110df2 106 if ! mount -t devtmpfs -o mode=0755,nosuid,noexec udev /dev >/dev/null 2>&1; then
e0364f95 107 # if it failed fall back to normal tmpfs
3b403b32 108 mount -t tmpfs -o mode=0755,nosuid udev /dev >/dev/null 2>&1
cc02093d
HH
109 # Make some basic devices first, let udev handle the rest
110 mknod -m 0666 /dev/null c 1 3
111 mknod -m 0666 /dev/ptmx c 5 2
112 mknod -m 0600 /dev/console c 5 1
113 mknod -m 0660 /dev/kmsg c 1 11
3473f5d9
HH
114 fi
115fi
d0e2110a 116
4af673c3 117# prepare the /dev directory
dbad9f46
HH
118[ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd >/dev/null 2>&1
119[ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin >/dev/null 2>&1
120[ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout >/dev/null 2>&1
121[ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr >/dev/null 2>&1
122
123if ! ismounted /dev/pts; then
124 mkdir -m 0755 /dev/pts
125 mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts >/dev/null 2>&1
126fi
127
128if ! ismounted /dev/shm; then
129 mkdir -m 0755 /dev/shm
130 mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /dev/shm >/dev/null 2>&1
131fi
132
133if ! ismounted /run; then
134 mkdir -m 0755 /newrun
135 mount -t tmpfs -o mode=0755,nosuid,nodev tmpfs /newrun >/dev/null 2>&1
136 cp -a -t /newrun /run/*
137 mount --move /newrun /run
138 rm -fr /newrun
139fi
77e607a3
HH
140
141UDEVVERSION=$(udevadm --version)
0afae1c7 142if [ $UDEVVERSION -gt 166 ]; then
19f3a804 143 # newer versions of udev use /run/udev/rules.d
19f3a804 144 export UDEVRULESD=/run/udev/rules.d
77e607a3 145else
3b403b32 146 mkdir -m 0755 /dev/.udev /dev/.udev/rules.d
77e607a3
HH
147 export UDEVRULESD=/dev/.udev/rules.d
148fi
149
a6c34848 150if [ "$RD_DEBUG" = "yes" ]; then
7eb40c48
HH
151 mkfifo /run/initramfs/loginit.pipe
152 loginit $DRACUT_QUIET </run/initramfs/loginit.pipe >/dev/console 2>&1 &
153 exec >/run/initramfs/loginit.pipe 2>&1
ac36d5db
HH
154else
155 exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
4592b698 156fi
ac36d5db 157
0375106c
HH
158source_conf /etc/conf.d
159
e4502814 160# run scriptlets to parse the command line
fa7ada31 161getarg 'rd.break=cmdline' 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline"
0b53ca70 162source_hook cmdline
e4502814 163
0fd1ab9d
PS
164[ -z "$root" ] && die "No or empty root= argument"
165[ -z "$rootok" ] && die "Don't know how to handle 'root=$root'"
d15c7a1a 166
7d7efa4a
DD
167# Network root scripts may need updated root= options,
168# so deposit them where they can see them (udev purges the env)
169{
170 echo "root='$root'"
171 echo "rflags='$rflags'"
172 echo "fstype='$fstype'"
2734a875 173 echo "netroot='$netroot'"
7d7efa4a
DD
174 echo "NEWROOT='$NEWROOT'"
175} > /tmp/root.info
176
a08c1f45 177# pre-udev scripts run before udev starts, and are run only once.
fa7ada31 178getarg 'rd.break=pre-udev' 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break before pre-udev"
0b53ca70 179source_hook pre-udev
ec1ad334 180
ec9315e5 181# start up udev and trigger cold plugs
0e0031dc 182udevd --daemon --resolve-names=never
2a652c0b
HH
183
184UDEV_LOG_PRIO_ARG=--log-priority
185UDEV_QUEUE_EMPTY="udevadm settle --timeout=0"
186
187if [ $UDEVVERSION -lt 140 ]; then
cc02093d
HH
188 UDEV_LOG_PRIO_ARG=--log_priority
189 UDEV_QUEUE_EMPTY="udevadm settle --timeout=1"
2a652c0b
HH
190fi
191
2a9b7039
HH
192getargbool 0 rd.udev.info -y rdudevinfo && udevproperty "$UDEV_LOG_PRIO_ARG=info"
193getargbool 0 rd.udev.debug -y rdudevdebug && udevproperty "$UDEV_LOG_PRIO_ARG=debug"
194udevproperty "hookdir=$hookdir"
1eeddd31 195
fa7ada31 196getarg 'rd.break=pre-trigger' 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break before pre-trigger"
0b53ca70 197source_hook pre-trigger
1eeddd31
HH
198
199# then the rest
cd83e4c5 200udevadm trigger --action=add $udevtriggeropts >/dev/null 2>&1
eab677a2 201
fa7ada31 202getarg 'rd.break=initqueue' 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue"
53e1c5b9 203
fa7ada31 204RDRETRY=$(getarg rd.retry 'rd_retry=')
85fd75f9
HH
205RDRETRY=${RDRETRY:-20}
206RDRETRY=$(($RDRETRY*2))
207
58dbb43e
HH
208i=0
209while :; do
58dbb43e 210
8238850c 211 check_finished && break
3b403b32 212
5c6a593f 213 udevsettle
89056045 214
8238850c
HH
215 check_finished && break
216
0b53ca70
HH
217 if [ -f $hookdir/initqueue/work ]; then
218 rm $hookdir/initqueue/work
58dbb43e 219 fi
3b403b32 220
0b53ca70 221 for job in $hookdir/initqueue/*.sh; do
cc02093d 222 [ -e "$job" ] || break
58dbb43e 223 job=$job . $job
8238850c 224 check_finished && break 2
58dbb43e
HH
225 done
226
8238850c 227 $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue
71094bee 228
0b53ca70 229 for job in $hookdir/initqueue/settled/*.sh; do
040f3d2f
HH
230 [ -e "$job" ] || break
231 job=$job . $job
232 check_finished && break 2
233 done
234
235 $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue
236
8238850c
HH
237 # no more udev jobs and queues empty.
238 sleep 0.5
0e0bf830
HH
239
240 # dirty hack for some cdrom drives,
241 # which report no medium for quiet
242 # some time.
9edf1b20 243 for cdrom in /sys/block/sr*; do
3b403b32 244 [ -e "$cdrom" ] || continue
5b2cc025
HH
245 # skip, if cdrom medium was already found
246 strstr "$(udevadm info --query=env --path=${cdrom##/sys})" \
247 ID_CDROM_MEDIA && continue
248
e620bb01 249 if [ -e "$cdrom"/events_poll_msecs -a ! -e "/tmp/.poll_${cdrom##*/}" ]; then
9edf1b20 250 msecs=$(while read a; do echo $a;done < "$cdrom"/events_poll_msecs)
5b2cc025
HH
251 if [ "$msecs" = "-1" ]; then
252 echo 250 > "$cdrom"/events_poll_msecs
253 > "/tmp/.poll_${cdrom##*/}"
254 fi
9edf1b20 255 else
5b2cc025 256 echo change > "$cdrom/uevent"
9edf1b20
HH
257 fi
258 done
3b403b32 259
8238850c 260 i=$(($i+1))
85fd75f9 261 [ $i -gt $RDRETRY ] \
a382492b 262 && { flock -s 9 ; emergency_shell "No root device \"$root\" found"; } 9>/.console_lock
58dbb43e
HH
263done
264unset job
265unset queuetriggered
ec9315e5 266
9edf1b20
HH
267# reset cdrom polling
268for cdrom in /sys/block/sr*; do
3b403b32 269 [ -e "$cdrom" ] || continue
9edf1b20
HH
270 if [ -e "$cdrom"/events_poll_msecs ]; then
271 echo -1 > "$cdrom"/events_poll_msecs
272 fi
273done
274
a08c1f45
VL
275# pre-mount happens before we try to mount the root filesystem,
276# and happens once.
fa7ada31 277getarg 'rd.break=pre-mount' 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break pre-mount"
0b53ca70 278source_hook pre-mount
bb040f93 279
a3a3448d 280
fa7ada31 281getarg 'rd.break=mount' 'rdbreak=mount' && emergency_shell -n mount "Break mount"
a08c1f45
VL
282# mount scripts actually try to mount the root filesystem, and may
283# be sourced any number of times. As soon as one suceeds, no more are sourced.
87930555 284i=0
a08c1f45 285while :; do
37dcb400 286 [ -d "$NEWROOT/proc" ] && break;
0b53ca70 287 for f in $hookdir/mount/*.sh; do
cc02093d
HH
288 [ -f "$f" ] && . "$f"
289 [ -d "$NEWROOT/proc" ] && break;
a08c1f45 290 done
bb040f93 291
7cd15fe7 292 i=$(($i+1))
a3a3448d
HH
293 [ $i -gt 20 ] \
294 && { flock -s 9 ; emergency_shell "Can't mount root filesystem"; } 9>/.console_lock
a08c1f45
VL
295done
296
0b2de1f8
HH
297{
298 echo -n "Mounted root filesystem "
3b403b32 299 while read dev mp rest; do [ "$mp" = "$NEWROOT" ] && echo $dev; done < /proc/mounts
0b2de1f8
HH
300} | vinfo
301
b5c7c7e8 302# pre pivot scripts are sourced just before we switch over to the new root.
fa7ada31 303getarg 'rd.break=pre-pivot' 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break pre-pivot"
0b53ca70 304source_hook pre-pivot
88ffd2df 305
a08c1f45 306# by the time we get here, the root filesystem should be mounted.
d05f3c43 307# Try to find init.
770b796e 308for i in "$(getarg real_init=)" "$(getarg init=)" /sbin/init /etc/init /init /bin/sh; do
2c1f37d4 309 [ -n "$i" ] || continue
7f7a91b7
HH
310 if ! [ -d "$NEWROOT$i" ] && [ -L "$NEWROOT$i" -o -x "$NEWROOT$i" ]; then
311 INIT="$i"
312 break
313 fi
d05f3c43 314done
0b2de1f8 315
6b0daf2e 316[ "$INIT" ] || {
a3a3448d
HH
317 echo "Cannot find init!"
318 echo "Please check to make sure you passed a valid root filesystem!"
d05f3c43 319 emergency_shell
6b0daf2e 320}
a08c1f45 321
fa7ada31 322getarg rd.break rdbreak && emergency_shell -n switch_root "Break before switch_root"
7e87a0bf 323
6a168568
HH
324if [ $UDEVVERSION -lt 168 ]; then
325 # stop udev queue before killing it
326 udevadm control --stop-exec-queue
327
328 HARD=""
3b403b32 329 while pidof udevd >/dev/null 2>&1; do
6a168568
HH
330 for pid in $(pidof udevd); do
331 kill $HARD $pid >/dev/null 2>&1
332 done
333 HARD="-9"
7e87a0bf 334 done
6a168568
HH
335else
336 udevadm control --exit
337 udevadm info --cleanup-db
338fi
5fa49940 339
bf512ee2 340export RD_TIMESTAMP
a6c34848 341set +x # Turn off debugging for this section
5fa49940
AT
342# Clean up the environment
343for i in $(export -p); do
344 i=${i#declare -x}
c79517b4 345 i=${i#export}
77e2cadd 346 strstr "$i" "=" || continue
c79517b4 347 i=${i%%=*}
77e2cadd
HH
348 [ -z "$i" ] && continue
349 case $i in
350 root|PATH|HOME|TERM|PS4|RD_*)
351 :;;
352 *)
353 unset "$i";;
354 esac
5fa49940
AT
355done
356
faf88239 357initargs=""
b63fd4d9 358read CLINE </proc/cmdline
247c9f70 359if getarg init= >/dev/null ; then
a6c34848 360 set +x # Turn off debugging for this section
247c9f70
HH
361 ignoreargs="console BOOT_IMAGE"
362 # only pass arguments after init= to the init
247c9f70 363 CLINE=${CLINE#*init=}
cc02093d
HH
364 set $CLINE
365 shift
366 for x in "$@"; do
3b403b32 367 for s in $ignoreargs; do
cc02093d
HH
368 [ "${x%%=*}" = $s ] && continue 2
369 done
370 initargs="$initargs $x"
247c9f70 371 done
cc02093d 372 unset CLINE
b63fd4d9 373else
a6c34848 374 set +x # Turn off debugging for this section
b63fd4d9
AB
375 set $CLINE
376 shift
377 for x in "$@"; do
378 case "$x" in
cc02093d 379 [0-9]|s|S|single|emergency|auto ) \
b63fd4d9 380 initargs="$initargs $x"
cc02093d 381 ;;
b63fd4d9
AB
382 esac
383 done
247c9f70 384fi
dbad9f46 385[ "$RD_DEBUG" = "yes" ] && set -x
3b403b32 386
dbad9f46
HH
387if [ -d "$NEWROOT"/run ]; then
388 NEWRUN="${NEWROOT}/run"
389 mount --bind /run "$NEWRUN"
390 NEWINITRAMFSROOT="$NEWRUN/initramfs"
e1ee9353 391
dbad9f46 392 if [ "$NEWINITRAMFSROOT/lib" -ef "/lib" ]; then
3b403b32 393 for d in bin etc lib lib64 sbin tmp usr var; do
dbad9f46
HH
394 [ -h /$d ] && ln -fsn $NEWINITRAMFSROOT/$d /$d
395 done
396 fi
397else
398 NEWRUN=/dev/.initramfs
399 mkdir -m 0755 "$NEWRUN"
400 mount --bind /run/initramfs "$NEWRUN"
401fi
0b2de1f8 402
ac36d5db 403wait_for_loginit
3b403b32 404
dbad9f46 405info "Switching root"
3b403b32 406
dbad9f46 407umount -l /run
4592b698 408
dbad9f46 409unset PS4
19f3a804 410
dbad9f46
HH
411CAPSH=$(command -v capsh)
412SWITCH_ROOT=$(command -v switch_root)
413PATH=$OLDPATH
414export PATH
98537743 415
529349c6
HH
416if [ -f /etc/capsdrop ]; then
417 . /etc/capsdrop
418 info "Calling $INIT with capabilities $CAPS_INIT_DROP dropped."
9e7a3bf2 419 unset RD_DEBUG
dbad9f46
HH
420 exec $CAPSH --drop="$CAPS_INIT_DROP" -- \
421 -c "exec switch_root \"$NEWROOT\" \"$INIT\" $initargs" || \
422 {
529349c6
HH
423 warn "Command:"
424 warn capsh --drop=$CAPS_INIT_DROP -- -c exec switch_root "$NEWROOT" "$INIT" $initargs
425 warn "failed."
426 emergency_shell
427 }
428else
9e7a3bf2 429 unset RD_DEBUG
dbad9f46 430 exec $SWITCH_ROOT "$NEWROOT" "$INIT" $initargs || {
529349c6
HH
431 warn "Something went very badly wrong in the initramfs. Please "
432 warn "file a bug against dracut."
433 emergency_shell
434 }
435fi