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