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