]>
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 | |
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 |
41 | emergency_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 | 69 | OLD_PATH="$PATH" |
ec9315e5 | 70 | export PATH=/sbin:/bin:/usr/sbin:/usr/bin |
bb040f93 HH |
71 | NEWROOT="/sysroot" |
72 | ||
a75c29be | 73 | trap "emergency_shell Signal caught!" 0 |
a890fe29 | 74 | |
52aeb3f3 | 75 | RDDEBUG="" |
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 |
81 | mount -t proc -o nosuid,noexec,nodev /proc /proc >/dev/null 2>&1 |
82 | mount -t sysfs -o nosuid,noexec,nodev /sys /sys >/dev/null 2>&1 | |
a890fe29 | 83 | |
b2415f44 HH |
84 | if [ -x /lib/systemd/systemd-timestamp ]; then |
85 | RD_TIMESTAMP=$(/lib/systemd/systemd-timestamp) | |
86 | else | |
87 | read RD_TIMESTAMP _tmp < /proc/uptime | |
88 | unset _tmp | |
89 | fi | |
647bef8c | 90 | |
3473f5d9 | 91 | if [ ! -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 |
102 | fi | |
d0e2110a | 103 | |
4af673c3 | 104 | # prepare the /dev directory |
f2a716d4 | 105 | ln -s /proc/self/fd /dev/fd >/dev/null 2>&1 |
2ca35ac7 HH |
106 | ln -s /proc/self/fd/0 /dev/stdin >/dev/null 2>&1 |
107 | ln -s /proc/self/fd/1 /dev/stdout >/dev/null 2>&1 | |
108 | ln -s /proc/self/fd/2 /dev/stderr >/dev/null 2>&1 | |
19f3a804 | 109 | mkdir -m 0755 /dev/shm /dev/pts /run |
4af673c3 | 110 | mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts >/dev/null 2>&1 |
444061de | 111 | mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /dev/shm >/dev/null 2>&1 |
19f3a804 HH |
112 | # create /run which will obsolete /var/run |
113 | mount -t tmpfs -o mode=0755,nodev,noexec,nosuid tmpfs /run >/dev/null 2>&1 | |
b177e913 | 114 | |
19f3a804 | 115 | mkdir -m 0755 /run/initramfs |
77e607a3 HH |
116 | |
117 | UDEVVERSION=$(udevadm --version) | |
0afae1c7 | 118 | if [ $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 |
122 | else |
123 | mkdir -m 0755 /dev/.udev /dev/.udev/rules.d | |
124 | export UDEVRULESD=/dev/.udev/rules.d | |
125 | fi | |
126 | ||
19f3a804 HH |
127 | [ -e /var/run ] && mv /var/run /var/run.bak |
128 | [ -e /var/lock ] && mv /var/lock /var/lock.bak | |
129 | ln -fs /run /var/run | |
130 | mkdir -m 0755 /run/lock | |
131 | ln -fs /run/lock /var/lock | |
132 | # copy over any possible directory structure | |
133 | cp -ar /var/run.bak/* /run/ 2>/dev/null | |
134 | cp -ar /var/lock.bak/* /run/lock/ 2>/dev/null | |
b177e913 | 135 | |
fa7ada31 | 136 | if 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 |
141 | else |
142 | exec 0<>/dev/console 1<>/dev/console 2<>/dev/console | |
4592b698 | 143 | fi |
ac36d5db | 144 | |
52aeb3f3 | 145 | setdebug |
83701d66 | 146 | |
0375106c HH |
147 | source_conf /etc/conf.d |
148 | ||
e4502814 | 149 | # run scriptlets to parse the command line |
fa7ada31 | 150 | getarg 'rd.break=cmdline' 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline" |
0b53ca70 | 151 | source_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 | 167 | getarg 'rd.break=pre-udev' 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break before pre-udev" |
0b53ca70 | 168 | source_hook pre-udev |
ec1ad334 | 169 | |
ec9315e5 | 170 | # start up udev and trigger cold plugs |
0e0031dc | 171 | udevd --daemon --resolve-names=never |
2a652c0b HH |
172 | |
173 | UDEV_LOG_PRIO_ARG=--log-priority | |
174 | UDEV_QUEUE_EMPTY="udevadm settle --timeout=0" | |
175 | ||
176 | if [ $UDEVVERSION -lt 140 ]; then | |
cc02093d HH |
177 | UDEV_LOG_PRIO_ARG=--log_priority |
178 | UDEV_QUEUE_EMPTY="udevadm settle --timeout=1" | |
2a652c0b HH |
179 | fi |
180 | ||
fa7ada31 HH |
181 | getargbool 0 rd.udev.info -y rdudevinfo && udevadm control $UDEV_LOG_PRIO_ARG=info |
182 | getargbool 0 rd.udev.debug -y rdudevdebug && udevadm control $UDEV_LOG_PRIO_ARG=debug | |
1eeddd31 | 183 | |
fa7ada31 | 184 | getarg 'rd.break=pre-trigger' 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break before pre-trigger" |
0b53ca70 | 185 | source_hook pre-trigger |
1eeddd31 HH |
186 | |
187 | # then the rest | |
cd83e4c5 | 188 | udevadm trigger --action=add $udevtriggeropts >/dev/null 2>&1 |
eab677a2 | 189 | |
fa7ada31 | 190 | getarg 'rd.break=initqueue' 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue" |
53e1c5b9 | 191 | |
fa7ada31 | 192 | RDRETRY=$(getarg rd.retry 'rd_retry=') |
85fd75f9 HH |
193 | RDRETRY=${RDRETRY:-20} |
194 | RDRETRY=$(($RDRETRY*2)) | |
195 | ||
58dbb43e HH |
196 | i=0 |
197 | while :; 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 |
248 | done |
249 | unset job | |
250 | unset queuetriggered | |
ec9315e5 | 251 | |
9edf1b20 HH |
252 | # reset cdrom polling |
253 | for 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 | |
258 | done | |
259 | ||
a08c1f45 VL |
260 | # pre-mount happens before we try to mount the root filesystem, |
261 | # and happens once. | |
fa7ada31 | 262 | getarg 'rd.break=pre-mount' 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break pre-mount" |
0b53ca70 | 263 | source_hook pre-mount |
bb040f93 | 264 | |
a3a3448d | 265 | |
fa7ada31 | 266 | getarg '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 | 269 | i=0 |
a08c1f45 | 270 | while :; 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 |
280 | done |
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 | 288 | getarg 'rd.break=pre-pivot' 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break pre-pivot" |
0b53ca70 | 289 | source_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 | 293 | for 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 | 299 | done |
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 | 307 | getarg rd.break rdbreak && emergency_shell -n switch_root "Break before switch_root" |
7e87a0bf | 308 | |
de439e24 HH |
309 | # stop udev queue before killing it |
310 | udevadm control --stop-exec-queue | |
311 | ||
7e87a0bf HH |
312 | HARD="" |
313 | while 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" | |
318 | done | |
5fa49940 AT |
319 | |
320 | # Clean up the environment | |
321 | for 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 |
328 | done |
329 | ||
faf88239 | 330 | initargs="" |
52c3715f | 331 | |
b63fd4d9 | 332 | read CLINE </proc/cmdline |
247c9f70 HH |
333 | if 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 |
346 | else |
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 | 356 | fi |
e1ee9353 | 357 | |
a89fb6da | 358 | # Debug: Copy state |
fa7ada31 | 359 | if getargbool 0 rd.copystate -y rdcopystate; then |
e94f4cce | 360 | cp -axr /tmp/* /run/initramfs/ >/dev/null 2>&1 |
e1ee9353 WT |
361 | fi |
362 | ||
fa7ada31 | 363 | if getargbool 1 rd.timestamp; then |
577b1fc8 | 364 | export RD_TIMESTAMP |
647bef8c | 365 | else |
577b1fc8 | 366 | unset RD_TIMESTAMP |
647bef8c HH |
367 | fi |
368 | ||
0b2de1f8 HH |
369 | info "Switching root" |
370 | ||
ac36d5db | 371 | wait_for_loginit |
4592b698 | 372 | |
4bacdf28 AŻ |
373 | export PATH="$OLD_PATH" |
374 | ||
19f3a804 HH |
375 | if [ -d "$NEWROOT"/run ]; then |
376 | mount --move /run "$NEWROOT"/run | |
377 | else | |
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 |
386 | fi |
387 | ||
529349c6 HH |
388 | if [ -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 | } | |
398 | else | |
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 | } | |
405 | fi |