]>
Commit | Line | Data |
---|---|---|
7f64a3fe | 1 | #!/bin/sh |
a5e56335 JK |
2 | # |
3 | # Licensed under the GPLv2 | |
4 | # | |
5 | # Copyright 2008, Red Hat, Inc. | |
6 | # Jeremy Katz <katzj@redhat.com> | |
ec9315e5 JK |
7 | |
8 | emergency_shell() | |
9 | { | |
4592b698 HH |
10 | set +x |
11 | exec 0<>/dev/console 1<>/dev/console 2<>/dev/console | |
12 | # wait for loginit | |
13 | wait | |
a3a3448d HH |
14 | echo ; echo |
15 | echo $@ | |
0fd1ab9d | 16 | source_all emergency |
81f83dab | 17 | echo |
dacba778 | 18 | if getarg rdshell || getarg rdbreak; then |
81f83dab | 19 | echo "Dropping to debug shell." |
a3a3448d HH |
20 | echo |
21 | sh -i | |
22 | else | |
c3cd4c76 | 23 | echo "Boot has failed, sleeping forever." |
81f83dab | 24 | while :; do sleep 365d;done |
a3a3448d | 25 | fi |
ec9315e5 | 26 | } |
ec9315e5 | 27 | |
ec9315e5 JK |
28 | export PATH=/sbin:/bin:/usr/sbin:/usr/bin |
29 | export TERM=linux | |
bb040f93 HH |
30 | NEWROOT="/sysroot" |
31 | ||
a75c29be | 32 | trap "emergency_shell Signal caught!" 0 |
a890fe29 | 33 | |
52aeb3f3 | 34 | RDDEBUG="" |
b8f39ef1 | 35 | . /lib/dracut-lib.sh |
df44688f | 36 | |
a890fe29 HH |
37 | mknod /dev/null c 1 3 |
38 | ||
ec9315e5 | 39 | # mount some important things |
a890fe29 HH |
40 | mount -t proc /proc /proc >/dev/null 2>&1 |
41 | mount -t sysfs /sys /sys >/dev/null 2>&1 | |
a890fe29 | 42 | |
3473f5d9 | 43 | if [ ! -c /dev/ptmx ]; then |
e0364f95 HH |
44 | # try to mount devtmpfs |
45 | if ! mount -t devtmpfs -omode=0755 udev /dev >/dev/null 2>&1; then | |
46 | # if it failed fall back to normal tmpfs | |
3473f5d9 HH |
47 | mount -t tmpfs -omode=0755 udev /dev >/dev/null 2>&1 |
48 | # Make some basic devices first, let udev handle the rest | |
49 | mknod /dev/null c 1 3 | |
50 | mknod /dev/ptmx c 5 2 | |
51 | mknod /dev/console c 5 1 | |
52 | mknod /dev/kmsg c 1 11 | |
53 | fi | |
54 | fi | |
d0e2110a | 55 | |
4592b698 HH |
56 | if getarg rdinitdebug; then |
57 | getarg quiet && DRACUT_QUIET="yes" | |
58 | mkfifo /dev/initlog.pipe | |
59 | /sbin/loginit $DRACUT_QUIET </dev/initlog.pipe >/dev/console 2>&1 & | |
60 | exec >/dev/initlog.pipe 2>&1 | |
61 | fi | |
52aeb3f3 | 62 | setdebug |
83701d66 | 63 | |
d0e2110a | 64 | mkdir /dev/shm |
0c70846e | 65 | mkdir /dev/pts |
a890fe29 | 66 | mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts >/dev/null 2>&1 |
2168327b | 67 | mount -t tmpfs /dev/shm /dev/shm >/dev/null 2>&1 |
0c70846e | 68 | |
eab677a2 HH |
69 | UDEVVERSION=$(udevadm --version) |
70 | ||
0375106c HH |
71 | source_conf /etc/conf.d |
72 | ||
e4502814 | 73 | # run scriptlets to parse the command line |
a3a3448d | 74 | getarg 'rdbreak=cmdline' && emergency_shell "Break before cmdline" |
e4502814 DD |
75 | source_all cmdline |
76 | ||
0fd1ab9d PS |
77 | [ -z "$root" ] && die "No or empty root= argument" |
78 | [ -z "$rootok" ] && die "Don't know how to handle 'root=$root'" | |
d15c7a1a | 79 | |
7d7efa4a DD |
80 | # Network root scripts may need updated root= options, |
81 | # so deposit them where they can see them (udev purges the env) | |
82 | { | |
83 | echo "root='$root'" | |
84 | echo "rflags='$rflags'" | |
85 | echo "fstype='$fstype'" | |
2734a875 | 86 | echo "netroot='$netroot'" |
7d7efa4a DD |
87 | echo "NEWROOT='$NEWROOT'" |
88 | } > /tmp/root.info | |
89 | ||
a08c1f45 | 90 | # pre-udev scripts run before udev starts, and are run only once. |
a3a3448d | 91 | getarg 'rdbreak=pre-udev' && emergency_shell "Break before pre-udev" |
ec1ad334 VL |
92 | source_all pre-udev |
93 | ||
ec9315e5 | 94 | # start up udev and trigger cold plugs |
0e0031dc | 95 | udevd --daemon --resolve-names=never |
2a652c0b HH |
96 | |
97 | UDEV_LOG_PRIO_ARG=--log-priority | |
98 | UDEV_QUEUE_EMPTY="udevadm settle --timeout=0" | |
99 | ||
100 | if [ $UDEVVERSION -lt 140 ]; then | |
101 | UDEV_LOG_PRIO_ARG=--log_priority | |
102 | UDEV_QUEUE_EMPTY="udevadm settle --timeout=1" | |
103 | fi | |
104 | ||
105 | getarg rdudevinfo && udevadm control $UDEV_LOG_PRIO_ARG=info | |
106 | getarg rdudevdebug && udevadm control $UDEV_LOG_PRIO_ARG=debug | |
1eeddd31 | 107 | |
53e1c5b9 | 108 | getarg 'rdbreak=pre-trigger' && emergency_shell "Break before pre-trigger" |
1eeddd31 HH |
109 | source_all pre-trigger |
110 | ||
111 | # then the rest | |
53759538 | 112 | udevadm trigger $udevtriggeropts >/dev/null 2>&1 |
eab677a2 | 113 | |
53e1c5b9 HH |
114 | getarg 'rdbreak=initqueue' && emergency_shell "Break before initqueue" |
115 | ||
58dbb43e HH |
116 | i=0 |
117 | while :; do | |
58dbb43e | 118 | |
8238850c HH |
119 | check_finished && break |
120 | ||
5c6a593f | 121 | udevsettle |
89056045 | 122 | |
8238850c HH |
123 | check_finished && break |
124 | ||
58dbb43e HH |
125 | if [ -f /initqueue/work ]; then |
126 | rm /initqueue/work | |
58dbb43e HH |
127 | fi |
128 | ||
129 | for job in /initqueue/*.sh; do | |
130 | [ -e "$job" ] || break | |
131 | job=$job . $job | |
8238850c | 132 | check_finished && break 2 |
58dbb43e HH |
133 | done |
134 | ||
8238850c | 135 | $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue |
71094bee | 136 | |
8238850c | 137 | modprobe scsi_wait_scan && rmmod scsi_wait_scan |
71094bee | 138 | |
8238850c | 139 | $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue |
71094bee | 140 | |
8238850c HH |
141 | for job in /initqueue-settled/*.sh; do |
142 | [ -e "$job" ] || break | |
143 | job=$job . $job | |
144 | check_finished && break 2 | |
145 | done | |
273b197d | 146 | |
8238850c | 147 | $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue |
273b197d | 148 | |
8238850c HH |
149 | # no more udev jobs and queues empty. |
150 | sleep 0.5 | |
151 | i=$(($i+1)) | |
152 | [ $i -gt 20 ] \ | |
153 | && { flock -s 9 ; emergency_shell "No root device found"; } 9>/.console_lock | |
58dbb43e HH |
154 | done |
155 | unset job | |
156 | unset queuetriggered | |
ec9315e5 | 157 | |
a08c1f45 VL |
158 | # pre-mount happens before we try to mount the root filesystem, |
159 | # and happens once. | |
a3a3448d | 160 | getarg 'rdbreak=pre-mount' && emergency_shell "Break pre-mount" |
ec1ad334 | 161 | source_all pre-mount |
bb040f93 | 162 | |
a3a3448d HH |
163 | |
164 | getarg 'rdbreak=mount' && emergency_shell "Break mount" | |
a08c1f45 VL |
165 | # mount scripts actually try to mount the root filesystem, and may |
166 | # be sourced any number of times. As soon as one suceeds, no more are sourced. | |
87930555 | 167 | i=0 |
a08c1f45 | 168 | while :; do |
37dcb400 | 169 | [ -d "$NEWROOT/proc" ] && break; |
a08c1f45 | 170 | for f in /mount/*.sh; do |
eab677a2 | 171 | [ -f "$f" ] && . "$f" |
58dbb43e | 172 | [ -d "$NEWROOT/proc" ] && break; |
a08c1f45 | 173 | done |
bb040f93 | 174 | |
7cd15fe7 | 175 | i=$(($i+1)) |
a3a3448d HH |
176 | [ $i -gt 20 ] \ |
177 | && { flock -s 9 ; emergency_shell "Can't mount root filesystem"; } 9>/.console_lock | |
a08c1f45 VL |
178 | done |
179 | ||
0b2de1f8 HH |
180 | { |
181 | echo -n "Mounted root filesystem " | |
182 | while read dev mp rest; do [ "$mp" = "$NEWROOT" ] && echo $dev; done < /proc/mounts | |
183 | } | vinfo | |
184 | ||
b5c7c7e8 | 185 | # pre pivot scripts are sourced just before we switch over to the new root. |
81f83dab | 186 | getarg 'rdbreak=pre-pivot' && emergency_shell "Break pre-pivot" |
88ffd2df VL |
187 | source_all pre-pivot |
188 | ||
a08c1f45 | 189 | # by the time we get here, the root filesystem should be mounted. |
d05f3c43 VL |
190 | # Try to find init. |
191 | for i in "$(getarg init=)" /sbin/init /etc/init /init /bin/sh; do | |
192 | [ -f "$NEWROOT$i" -a -x "$NEWROOT$i" ] && { INIT="$i"; break; } | |
193 | done | |
0b2de1f8 | 194 | |
6b0daf2e | 195 | [ "$INIT" ] || { |
a3a3448d HH |
196 | echo "Cannot find init!" |
197 | echo "Please check to make sure you passed a valid root filesystem!" | |
d05f3c43 | 198 | emergency_shell |
6b0daf2e | 199 | } |
a08c1f45 | 200 | |
81f83dab | 201 | getarg rdbreak && emergency_shell "Break before switch_root" |
7e87a0bf | 202 | |
de439e24 HH |
203 | # stop udev queue before killing it |
204 | udevadm control --stop-exec-queue | |
205 | ||
7e87a0bf HH |
206 | HARD="" |
207 | while pidof udevd >/dev/null 2>&1; do | |
208 | for pid in $(pidof udevd); do | |
209 | kill $HARD $pid >/dev/null 2>&1 | |
210 | done | |
211 | HARD="-9" | |
212 | done | |
5fa49940 AT |
213 | |
214 | # Clean up the environment | |
215 | for i in $(export -p); do | |
216 | i=${i#declare -x} | |
217 | i=${i#export} | |
218 | i=${i%%=*} | |
219 | [ "$i" = "root" -o "$i" = "PATH" -o "$i" = "HOME" -o "$i" = "TERM" ] || unset $i | |
220 | done | |
221 | ||
faf88239 | 222 | initargs="" |
52c3715f | 223 | |
247c9f70 HH |
224 | if getarg init= >/dev/null ; then |
225 | ignoreargs="console BOOT_IMAGE" | |
226 | # only pass arguments after init= to the init | |
227 | read CLINE </proc/cmdline | |
228 | CLINE=${CLINE#*init=} | |
229 | set $CLINE | |
230 | for x in "$@"; do | |
231 | for s in $ignoreargs; do | |
232 | [ "${x%%=*}" = $s ] && continue 2 | |
233 | done | |
234 | initargs="$initargs $x" | |
52c3715f | 235 | done |
247c9f70 HH |
236 | unset CLINE |
237 | fi | |
e1ee9353 | 238 | |
a89fb6da | 239 | # Debug: Copy state |
e1ee9353 | 240 | if getarg rdcopystate; then |
a71f1b49 | 241 | mkdir /dev/.initramfs/ |
e1ee9353 | 242 | cp /tmp/* /dev/.initramfs/ >/dev/null 2>&1 |
e1ee9353 WT |
243 | fi |
244 | ||
0b2de1f8 HH |
245 | info "Switching root" |
246 | ||
4592b698 HH |
247 | exec 0<>/dev/console 1<>/dev/console 2<>/dev/console |
248 | # wait for loginit | |
249 | wait | |
250 | ||
faf88239 | 251 | exec switch_root "$NEWROOT" "$INIT" $initargs || { |
247c9f70 HH |
252 | echo "Something went very badly wrong in the initramfs. Please " |
253 | echo "file a bug against dracut." | |
9cead591 VL |
254 | emergency_shell |
255 | } |