2 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3 # ex: ts=8 sw=4 sts=4 et filetype=sh
5 # Licensed under the GPLv2
7 # Copyright 2008-2010, Red Hat, Inc.
8 # Harald Hoyer <harald@redhat.com>
9 # Jeremy Katz <katzj@redhat.com>
11 export -p > /tmp
/export.orig
16 [ "$RD_DEBUG" = "yes" ] ||
return
17 [ -e /run
/initramfs
/loginit.pipe
] ||
return
19 exec 0<>/dev
/console
1<>/dev
/console
2<>/dev
/console
22 while [ $i -lt 10 ]; do
23 if [ ! -e /run
/initramfs
/loginit.pipe
]; then
26 [ -z "${j##*Running*}" ] ||
break
32 if [ $i -eq 10 ]; then
33 kill %1 >/dev
/null
2>&1
34 kill $
(while read line
;do echo $line;done</run
/initramfs
/loginit.pid
)
38 rm -f /run
/initramfs
/loginit.pipe
/run
/initramfs
/loginit.pid
45 if [ "$1" = "-n" ]; then
56 [ -e /run
/initramfs
/.die
] && exit 1
57 if getargbool
1 rd.shell
-y rdshell || getarg rd.
break rdbreak
; then
58 echo "Dropping to debug shell."
60 export PS1
="$_rdshell_name:\${PWD}# "
61 [ -e /.profile
] ||
>/.profile
63 if [ -n "$(command -v setsid)" ]; then
64 _ctty
="$(getarg rd.ctty=)" && _ctty
="/dev/${_ctty##*/}"
65 [ -c "$_ctty" ] || _ctty
=/dev
/tty1
66 setsid sh
-i -l 0<$_ctty 1>$_ctty 2>&1
67 elif [ -n "$(command -v openvt)" ] && ! getarg
"console=" >/dev
/null
2>&1 && getargbool
1 "rd.openvt" ; then
68 openvt
-f -c 1 -w -s -l -- sh
70 sh
-i -l 0<$_ctty 1>$_ctty 2>&1
73 warn
"Boot has failed. To debug this issue add \"rdshell\" to the kernel command line."
74 # cause a kernel panic
80 [ -d $NEWROOT ] || mkdir
-p -m 0755 $NEWROOT
82 trap "emergency_shell Signal caught!" 0
84 PATH
=/usr
/sbin
:/usr
/bin
:/sbin
:/bin
90 [ -c /dev
/null
] || mknod
-m 0666 /dev
/null c
1 3
92 # mount some important things
93 [ ! -d /proc
/self
] && \
94 mount
-t proc
-o nosuid
,noexec
,nodev proc
/proc
>/dev
/null
2>&1
96 [ ! -d /sys
/kernel
] && \
97 mount
-t sysfs
-o nosuid
,noexec
,nodev sysfs
/sys
>/dev
/null
2>&1
99 if [ -x /lib
/systemd
/systemd-timestamp
]; then
100 RD_TIMESTAMP
=$
(/lib
/systemd
/systemd-timestamp
)
102 read RD_TIMESTAMP _tmp
< /proc
/uptime
108 if [ "$RD_DEBUG" = "yes" ]; then
109 getarg quiet
&& DRACUT_QUIET
="yes"
110 a
=$
(getarg loglevel
=)
111 [ -n "$a" ] && [ $a -ge 8 ] && unset DRACUT_QUIET
114 if ! ismounted
/dev
; then
115 mount
-t devtmpfs
-o mode
=0755,nosuid devtmpfs
/dev
>/dev
/null
118 # prepare the /dev directory
119 [ ! -h /dev
/fd
] && ln -s /proc
/self
/fd
/dev
/fd
>/dev
/null
2>&1
120 [ ! -h /dev
/stdin
] && ln -s /proc
/self
/fd
/0 /dev
/stdin
>/dev
/null
2>&1
121 [ ! -h /dev
/stdout
] && ln -s /proc
/self
/fd
/1 /dev
/stdout
>/dev
/null
2>&1
122 [ ! -h /dev
/stderr
] && ln -s /proc
/self
/fd
/2 /dev
/stderr
>/dev
/null
2>&1
124 if ! ismounted
/dev
/pts
; then
125 mkdir
-m 0755 /dev
/pts
126 mount
-t devpts
-o gid
=5,mode
=620,noexec
,nosuid devpts
/dev
/pts
>/dev
/null
129 if ! ismounted
/dev
/shm
; then
130 mkdir
-m 0755 /dev
/shm
131 mount
-t tmpfs
-o mode
=1777,nosuid
,nodev tmpfs
/dev
/shm
>/dev
/null
134 if ! ismounted
/run
; then
135 mkdir
-m 0755 /newrun
136 mount
-t tmpfs
-o mode
=0755,nosuid
,nodev tmpfs
/newrun
>/dev
/null
138 mount
--move /newrun
/run
142 [ -d /run
/initramfs
] || mkdir
-p -m 0755 /run
/initramfs
144 UDEVVERSION
=$
(udevadm
--version)
145 if [ $UDEVVERSION -gt 166 ]; then
146 # newer versions of udev use /run/udev/rules.d
147 export UDEVRULESD
=/run
/udev
/rules.d
148 [ -d /run
/udev
] || mkdir
-p -m 0755 /run
/udev
149 [ -d $UDEVRULESD ] || mkdir
-p -m 0755 $UDEVRULESD
151 mkdir
-m 0755 /dev
/.udev
/dev
/.udev
/rules.d
152 export UDEVRULESD
=/dev
/.udev
/rules.d
155 if [ "$RD_DEBUG" = "yes" ]; then
156 mkfifo /run
/initramfs
/loginit.pipe
157 loginit
$DRACUT_QUIET </run
/initramfs
/loginit.pipe
>/dev
/console
2>&1 &
158 exec >/run
/initramfs
/loginit.pipe
2>&1
160 exec 0<>/dev
/console
1<>/dev
/console
2<>/dev
/console
163 source_conf
/etc
/conf.d
165 # run scriptlets to parse the command line
166 getarg
'rd.break=cmdline' 'rdbreak=cmdline' && emergency_shell
-n cmdline
"Break before cmdline"
169 [ -z "$root" ] && die
"No or empty root= argument"
170 [ -z "$rootok" ] && die
"Don't know how to handle 'root=$root'"
172 # Network root scripts may need updated root= options,
173 # so deposit them where they can see them (udev purges the env)
176 echo "rflags='$rflags'"
177 echo "fstype='$fstype'"
178 echo "netroot='$netroot'"
179 echo "NEWROOT='$NEWROOT'"
182 # pre-udev scripts run before udev starts, and are run only once.
183 getarg
'rd.break=pre-udev' 'rdbreak=pre-udev' && emergency_shell
-n pre-udev
"Break before pre-udev"
186 # start up udev and trigger cold plugs
187 udevd
--daemon --resolve-names=never
189 UDEV_LOG_PRIO_ARG
=--log-priority
190 UDEV_QUEUE_EMPTY
="udevadm settle --timeout=0"
192 if [ $UDEVVERSION -lt 140 ]; then
193 UDEV_LOG_PRIO_ARG
=--log_priority
194 UDEV_QUEUE_EMPTY
="udevadm settle --timeout=1"
197 getargbool
0 rd.udev.info
-y rdudevinfo
&& udevadm control
"$UDEV_LOG_PRIO_ARG=info"
198 getargbool
0 rd.udev.debug
-y rdudevdebug
&& udevadm control
"$UDEV_LOG_PRIO_ARG=debug"
199 udevproperty
"hookdir=$hookdir"
201 getarg
'rd.break=pre-trigger' 'rdbreak=pre-trigger' && emergency_shell
-n pre-trigger
"Break before pre-trigger"
202 source_hook pre-trigger
204 udevadm control
--reload >/dev
/null
2>&1 ||
:
206 udevadm trigger
--type=subsystems
--action=add
>/dev
/null
2>&1
207 udevadm trigger
--type=devices
--action=add
>/dev
/null
2>&1
209 getarg
'rd.break=initqueue' 'rdbreak=initqueue' && emergency_shell
-n initqueue
"Break before initqueue"
211 RDRETRY
=$
(getarg rd.retry
'rd_retry=')
212 RDRETRY
=${RDRETRY:-20}
213 RDRETRY
=$
(($RDRETRY*2))
219 check_finished
&& break
223 check_finished
&& break
225 if [ -f $hookdir/initqueue
/work
]; then
226 rm $hookdir/initqueue
/work
229 for job
in $hookdir/initqueue
/*.sh
; do
230 [ -e "$job" ] ||
break
232 check_finished
&& break 2
235 $UDEV_QUEUE_EMPTY >/dev
/null
2>&1 ||
continue
237 for job
in $hookdir/initqueue
/settled
/*.sh
; do
238 [ -e "$job" ] ||
break
240 check_finished
&& break 2
243 $UDEV_QUEUE_EMPTY >/dev
/null
2>&1 ||
continue
245 # no more udev jobs and queues empty.
248 if [ ! -e /sys
/module
/block
/parameters
/events_dfl_poll_msecs
]; then
249 # if the kernel does not support autopolling
250 # then we have to do a
251 # dirty hack for some cdrom drives,
252 # which report no medium for quiet
254 for cdrom
in /sys
/block
/sr
*; do
255 [ -e "$cdrom" ] ||
continue
256 # skip, if cdrom medium was already found
257 strstr
"$(udevadm info --query=env --path=${cdrom##/sys})" \
258 ID_CDROM_MEDIA
&& continue
259 echo change
> "$cdrom/uevent"
263 if [ $main_loop -gt $
(($RDRETRY/2)) ]; then
264 for job
in $hookdir/initqueue
/timeout
/*.sh
; do
265 [ -e "$job" ] ||
break
271 main_loop
=$
(($main_loop+1))
272 [ $main_loop -gt $RDRETRY ] \
273 && { flock
-s 9 ; emergency_shell
"Unable to process initqueue"; } 9>/.console_lock
280 # pre-mount happens before we try to mount the root filesystem,
282 getarg
'rd.break=pre-mount' 'rdbreak=pre-mount' && emergency_shell
-n pre-mount
"Break pre-mount"
283 source_hook pre-mount
286 getarg
'rd.break=mount' 'rdbreak=mount' && emergency_shell
-n mount
"Break mount"
287 # mount scripts actually try to mount the root filesystem, and may
288 # be sourced any number of times. As soon as one suceeds, no more are sourced.
291 if ismounted
"$NEWROOT"; then
292 usable_root
"$NEWROOT" && break;
295 for f
in $hookdir/mount
/*.sh
; do
296 [ -f "$f" ] && .
"$f"
297 if ismounted
"$NEWROOT"; then
298 usable_root
"$NEWROOT" && break;
299 warn
"$NEWROOT has no proper rootfs layout, ignoring and removing offending mount hook"
307 && { flock
-s 9 ; emergency_shell
"Can't mount root filesystem"; } 9>/.console_lock
311 echo -n "Mounted root filesystem "
312 while read dev mp rest
; do [ "$mp" = "$NEWROOT" ] && echo $dev; done < /proc
/mounts
315 # pre pivot scripts are sourced just before we switch over to the new root.
316 getarg
'rd.break=pre-pivot' 'rdbreak=pre-pivot' && emergency_shell
-n pre-pivot
"Break pre-pivot"
317 source_hook pre-pivot
319 # By the time we get here, the root filesystem should be mounted.
321 for i
in "$(getarg real_init=)" "$(getarg init=)" $
(getargs rd.distroinit
=) /sbin
/init
; do
322 [ -n "$i" ] ||
continue
324 __p
=$
(readlink
-f "${NEWROOT}/${i}")
325 if [ -x "$__p" ]; then
332 echo "Cannot find init!"
333 echo "Please check to make sure you passed a valid root filesystem!"
338 if [ $UDEVVERSION -lt 168 ]; then
339 # stop udev queue before killing it
340 udevadm control
--stop-exec-queue
343 while pidof udevd
>/dev
/null
2>&1; do
344 for pid
in $
(pidof udevd
); do
345 kill $HARD $pid >/dev
/null
2>&1
350 udevadm control
--exit
351 udevadm info
--cleanup-db
355 set +x
# Turn off debugging for this section
356 # Clean up the environment
357 for i
in $
(export -p); do
360 strstr
"$i" "=" ||
continue
362 [ -z "$i" ] && continue
364 root|PATH|HOME|TERM|PS4|RD_
*)
370 .
/tmp
/export.orig
2>/dev
/null ||
:
371 rm -f /tmp
/export.orig
374 read CLINE
</proc
/cmdline
375 if getarg init
= >/dev
/null
; then
376 set +x
# Turn off debugging for this section
377 ignoreargs
="console BOOT_IMAGE"
378 # only pass arguments after init= to the init
379 CLINE
=${CLINE#*init=}
381 shift # clear out the rest of the "init=" arg
383 for s
in $ignoreargs; do
384 [ "${x%%=*}" = $s ] && continue 2
386 initargs
="$initargs $x"
390 set +x
# Turn off debugging for this section
394 [0-9]|s|S|single|emergency|auto
) \
395 initargs
="$initargs $x"
400 [ "$RD_DEBUG" = "yes" ] && set -x
402 if [ -d "$NEWROOT"/run
]; then
403 NEWRUN
="${NEWROOT}/run"
404 mount
--bind /run
"$NEWRUN"
405 NEWINITRAMFSROOT
="$NEWRUN/initramfs"
407 if [ "$NEWINITRAMFSROOT/lib" -ef "/lib" ]; then
408 for d
in bin etc lib lib64 sbin tmp usr var
; do
409 [ -h /$d ] && ln -fsn $NEWINITRAMFSROOT/$d /$d
413 NEWRUN
=/dev
/.initramfs
414 mkdir
-m 0755 "$NEWRUN"
415 mount
--bind /run
/initramfs
"$NEWRUN"
420 # remove helper symlink
421 [ -h /dev
/root
] && rm -f /dev
/root
423 getarg rd.
break rdbreak
&& emergency_shell
-n switch_root
"Break before switch_root"
424 info
"Switching root"
430 CAPSH
=$
(command -v capsh
)
431 SWITCH_ROOT
=$
(command -v switch_root
)
435 if [ -f /etc
/capsdrop
]; then
437 info
"Calling $INIT with capabilities $CAPS_INIT_DROP dropped."
439 exec $CAPSH --drop="$CAPS_INIT_DROP" -- \
440 -c "exec switch_root \"$NEWROOT\" \"$INIT\" $initargs" || \
443 warn capsh
--drop=$CAPS_INIT_DROP -- -c exec switch_root
"$NEWROOT" "$INIT" $initargs
449 exec $SWITCH_ROOT "$NEWROOT" "$INIT" $initargs ||
{
450 warn
"Something went very badly wrong in the initramfs. Please "
451 warn
"file a bug against dracut."