network: don't use "ifup -m"
[dracut.git] / modules.d / 99base / init.sh
blobf96dbb5061f1244663c8133704164a6ca886a432
1 #!/bin/sh
3 # Licensed under the GPLv2
5 # Copyright 2008-2010, Red Hat, Inc.
6 # Harald Hoyer <harald@redhat.com>
7 # Jeremy Katz <katzj@redhat.com>
9 export -p > /tmp/export.orig
11 NEWROOT="/sysroot"
12 [ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT
14 OLDPATH=$PATH
15 PATH=/usr/sbin:/usr/bin:/sbin:/bin
16 export PATH
18 # mount some important things
19 [ ! -d /proc/self ] && \
20 mount -t proc -o nosuid,noexec,nodev proc /proc >/dev/null
22 if [ "$?" != "0" ]; then
23 echo "Cannot mount proc on /proc! Compile the kernel with CONFIG_PROC_FS!"
24 exit 1
27 [ ! -d /sys/kernel ] && \
28 mount -t sysfs -o nosuid,noexec,nodev sysfs /sys >/dev/null
30 if [ "$?" != "0" ]; then
31 echo "Cannot mount sysfs on /sys! Compile the kernel with CONFIG_SYSFS!"
32 exit 1
35 RD_DEBUG=""
36 . /lib/dracut-lib.sh
38 setdebug
40 if ! ismounted /dev; then
41 mount -t devtmpfs -o mode=0755,noexec,nosuid,strictatime devtmpfs /dev >/dev/null
44 if ! ismounted /dev; then
45 echo "Cannot mount devtmpfs on /dev! Compile the kernel with CONFIG_DEVTMPFS!"
46 exit 1
49 # prepare the /dev directory
50 [ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd >/dev/null 2>&1
51 [ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin >/dev/null 2>&1
52 [ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout >/dev/null 2>&1
53 [ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr >/dev/null 2>&1
55 if ! ismounted /dev/pts; then
56 mkdir -m 0755 /dev/pts
57 mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts >/dev/null
60 if ! ismounted /dev/shm; then
61 mkdir -m 0755 /dev/shm
62 mount -t tmpfs -o mode=1777,noexec,nosuid,nodev,strictatime tmpfs /dev/shm >/dev/null
65 if ! ismounted /run; then
66 mkdir -m 0755 /newrun
67 mount -t tmpfs -o mode=0755,noexec,nosuid,nodev,strictatime tmpfs /newrun >/dev/null
68 cp -a /run/* /newrun >/dev/null 2>&1
69 mount --move /newrun /run
70 rm -fr -- /newrun
73 if command -v kmod >/dev/null 2>/dev/null; then
74 kmod static-nodes --format=tmpfiles 2>/dev/null | \
75 while read type file mode a a a majmin || [ -n "$type" ]; do
76 type=${type%\!}
77 case $type in
79 mkdir -m $mode -p $file
82 mknod -m $mode $file $type ${majmin%:*} ${majmin#*:}
84 esac
85 done
88 trap "action_on_fail Signal caught!" 0
90 export UDEVVERSION=$(udevadm --version)
91 if [ $UDEVVERSION -gt 166 ]; then
92 # newer versions of udev use /run/udev/rules.d
93 export UDEVRULESD=/run/udev/rules.d
94 [ -d /run/udev ] || mkdir -p -m 0755 /run/udev
95 [ -d $UDEVRULESD ] || mkdir -p -m 0755 $UDEVRULESD
96 else
97 mkdir -m 0755 /dev/.udev /dev/.udev/rules.d
98 export UDEVRULESD=/dev/.udev/rules.d
101 if [ "$RD_DEBUG" = "yes" ]; then
102 mkfifo /run/initramfs/loginit.pipe
103 loginit $DRACUT_QUIET </run/initramfs/loginit.pipe >/dev/console 2>&1 &
104 exec >/run/initramfs/loginit.pipe 2>&1
105 else
106 exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
109 [ -f /usr/lib/initrd-release ] && . /usr/lib/initrd-release
110 [ -n "$VERSION_ID" ] && info "$NAME-$VERSION_ID"
112 source_conf /etc/conf.d
114 if getarg "rd.cmdline=ask"; then
115 echo "Enter additional kernel command line parameter (end with ctrl-d or .)"
116 while read -p "> " line || [ -n "$line" ]; do
117 [ "$line" = "." ] && break
118 echo "$line" >> /etc/cmdline.d/99-cmdline-ask.conf
119 done
122 if ! getargbool 1 'rd.hostonly'; then
123 remove_hostonly_files
126 # run scriptlets to parse the command line
127 make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab'
128 getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline"
129 source_hook cmdline
131 [ -z "$root" ] && die "No or empty root= argument"
132 [ -z "$rootok" ] && die "Don't know how to handle 'root=$root'"
134 export root rflags fstype netroot NEWROOT
136 # pre-udev scripts run before udev starts, and are run only once.
137 make_trace_mem "hook pre-udev" '1:shortmem' '2+:mem' '3+:slab'
138 getarg 'rd.break=pre-udev' -d 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break before pre-udev"
139 source_hook pre-udev
141 UDEV_LOG=err
142 getargbool 0 rd.udev.info -d -y rdudevinfo && UDEV_LOG=info
143 getargbool 0 rd.udev.debug -d -y rdudevdebug && UDEV_LOG=debug
145 # start up udev and trigger cold plugs
146 UDEV_LOG=$UDEV_LOG $systemdutildir/systemd-udevd --daemon --resolve-names=never
148 UDEV_QUEUE_EMPTY="udevadm settle --timeout=0"
150 if [ $UDEVVERSION -lt 140 ]; then
151 UDEV_QUEUE_EMPTY="udevadm settle --timeout=1"
154 udevproperty "hookdir=$hookdir"
156 make_trace_mem "hook pre-trigger" '1:shortmem' '2+:mem' '3+:slab'
157 getarg 'rd.break=pre-trigger' -d 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break before pre-trigger"
158 source_hook pre-trigger
160 udevadm control --reload >/dev/null 2>&1 || :
161 # then the rest
162 udevadm trigger --type=subsystems --action=add >/dev/null 2>&1
163 udevadm trigger --type=devices --action=add >/dev/null 2>&1
165 make_trace_mem "hook initqueue" '1:shortmem' '2+:mem' '3+:slab'
166 getarg 'rd.break=initqueue' -d 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue"
168 RDRETRY=$(getarg rd.retry -d 'rd_retry=')
169 RDRETRY=${RDRETRY:-180}
170 RDRETRY=$(($RDRETRY*2))
171 export RDRETRY
172 main_loop=0
173 export main_loop
174 while :; do
176 check_finished && break
178 udevsettle
180 check_finished && break
182 if [ -f $hookdir/initqueue/work ]; then
183 rm -f -- $hookdir/initqueue/work
186 for job in $hookdir/initqueue/*.sh; do
187 [ -e "$job" ] || break
188 job=$job . $job
189 check_finished && break 2
190 done
192 $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue
194 for job in $hookdir/initqueue/settled/*.sh; do
195 [ -e "$job" ] || break
196 job=$job . $job
197 check_finished && break 2
198 done
200 $UDEV_QUEUE_EMPTY >/dev/null 2>&1 || continue
202 # no more udev jobs and queues empty.
203 sleep 0.5
206 if [ $main_loop -gt $((2*$RDRETRY/3)) ]; then
207 for job in $hookdir/initqueue/timeout/*.sh; do
208 [ -e "$job" ] || break
209 job=$job . $job
210 udevadm settle --timeout=0 >/dev/null 2>&1 || main_loop=0
211 [ -f $hookdir/initqueue/work ] && main_loop=0
212 done
215 main_loop=$(($main_loop+1))
216 [ $main_loop -gt $RDRETRY ] \
217 && { flock -s 9 ; action_on_fail "Could not boot." && break; } 9>/.console_lock
218 done
219 unset job
220 unset queuetriggered
221 unset main_loop
222 unset RDRETRY
224 # pre-mount happens before we try to mount the root filesystem,
225 # and happens once.
226 make_trace_mem "hook pre-mount" '1:shortmem' '2+:mem' '3+:slab'
227 getarg 'rd.break=pre-mount' -d 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break pre-mount"
228 source_hook pre-mount
231 getarg 'rd.break=mount' -d 'rdbreak=mount' && emergency_shell -n mount "Break mount"
232 # mount scripts actually try to mount the root filesystem, and may
233 # be sourced any number of times. As soon as one suceeds, no more are sourced.
234 _i_mount=0
235 while :; do
236 if ismounted "$NEWROOT"; then
237 usable_root "$NEWROOT" && break;
238 umount "$NEWROOT"
240 for f in $hookdir/mount/*.sh; do
241 [ -f "$f" ] && . "$f"
242 if ismounted "$NEWROOT"; then
243 usable_root "$NEWROOT" && break;
244 warn "$NEWROOT has no proper rootfs layout, ignoring and removing offending mount hook"
245 umount "$NEWROOT"
246 rm -f -- "$f"
248 done
250 _i_mount=$(($_i_mount+1))
251 [ $_i_mount -gt 20 ] \
252 && { flock -s 9 ; action_on_fail "Can't mount root filesystem" && break; } 9>/.console_lock
253 done
256 echo -n "Mounted root filesystem "
257 while read dev mp rest || [ -n "$dev" ]; do [ "$mp" = "$NEWROOT" ] && echo $dev; done < /proc/mounts
258 } | vinfo
260 # pre pivot scripts are sourced just before we doing cleanup and switch over
261 # to the new root.
262 make_trace_mem "hook pre-pivot" '1:shortmem' '2+:mem' '3+:slab'
263 getarg 'rd.break=pre-pivot' -d 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break pre-pivot"
264 source_hook pre-pivot
266 make_trace_mem "hook cleanup" '1:shortmem' '2+:mem' '3+:slab'
267 # pre pivot cleanup scripts are sourced just before we switch over to the new root.
268 getarg 'rd.break=cleanup' -d 'rdbreak=cleanup' && emergency_shell -n cleanup "Break cleanup"
269 source_hook cleanup
271 # By the time we get here, the root filesystem should be mounted.
272 # Try to find init.
273 for i in "$(getarg real_init=)" "$(getarg init=)" $(getargs rd.distroinit=) /sbin/init; do
274 [ -n "$i" ] || continue
276 __p=$(readlink -f "${NEWROOT}/${i}")
277 if [ -x "$__p" -o -x "${NEWROOT}/${__p}" ]; then
278 INIT="$i"
279 break
281 done
283 [ "$INIT" ] || {
284 echo "Cannot find init!"
285 echo "Please check to make sure you passed a valid root filesystem!"
286 action_on_fail
289 if [ $UDEVVERSION -lt 168 ]; then
290 # stop udev queue before killing it
291 udevadm control --stop-exec-queue
293 HARD=""
294 while pidof udevd >/dev/null 2>&1; do
295 for pid in $(pidof udevd); do
296 kill $HARD $pid >/dev/null 2>&1
297 done
298 HARD="-9"
299 done
300 else
301 udevadm control --exit
302 udevadm info --cleanup-db
305 debug_off # Turn off debugging for this section
307 # unexport some vars
308 export_n root rflags fstype netroot NEWROOT
310 export RD_TIMESTAMP
311 # Clean up the environment
312 for i in $(export -p); do
313 i=${i#declare -x}
314 i=${i#export}
315 strstr "$i" "=" || continue
316 i=${i%%=*}
317 [ -z "$i" ] && continue
318 case $i in
319 root|PATH|HOME|TERM|PS4|RD_*)
322 unset "$i";;
323 esac
324 done
325 . /tmp/export.orig 2>/dev/null || :
326 rm -f -- /tmp/export.orig
328 initargs=""
329 read CLINE </proc/cmdline
330 if getarg init= >/dev/null ; then
331 ignoreargs="console BOOT_IMAGE"
332 # only pass arguments after init= to the init
333 CLINE=${CLINE#*init=}
334 set -- $CLINE
335 shift # clear out the rest of the "init=" arg
336 for x in "$@"; do
337 for s in $ignoreargs; do
338 [ "${x%%=*}" = $s ] && continue 2
339 done
340 initargs="$initargs $x"
341 done
342 unset CLINE
343 else
344 debug_off # Turn off debugging for this section
345 set -- $CLINE
346 for x in "$@"; do
347 case "$x" in
348 [0-9]|s|S|single|emergency|auto ) \
349 initargs="$initargs $x"
351 esac
352 done
354 debug_on
356 if ! [ -d "$NEWROOT"/run ]; then
357 NEWRUN=/dev/.initramfs
358 mkdir -m 0755 "$NEWRUN"
359 mount --rbind /run/initramfs "$NEWRUN"
362 wait_for_loginit
364 # remove helper symlink
365 [ -h /dev/root ] && rm -f -- /dev/root
367 bv=$(getarg rd.break -d rdbreak) && [ -z "$bv" ] &&
368 emergency_shell -n switch_root "Break before switch_root"
369 unset bv
370 info "Switching root"
373 unset PS4
375 CAPSH=$(command -v capsh)
376 SWITCH_ROOT=$(command -v switch_root)
377 PATH=$OLDPATH
378 export PATH
380 if [ -f /etc/capsdrop ]; then
381 . /etc/capsdrop
382 info "Calling $INIT with capabilities $CAPS_INIT_DROP dropped."
383 unset RD_DEBUG
384 exec $CAPSH --drop="$CAPS_INIT_DROP" -- \
385 -c "exec switch_root \"$NEWROOT\" \"$INIT\" $initargs" || \
387 warn "Command:"
388 warn capsh --drop=$CAPS_INIT_DROP -- -c exec switch_root "$NEWROOT" "$INIT" $initargs
389 warn "failed."
390 action_on_fail
392 else
393 unset RD_DEBUG
394 exec $SWITCH_ROOT "$NEWROOT" "$INIT" $initargs || {
395 warn "Something went very badly wrong in the initramfs. Please "
396 warn "file a bug against dracut."
397 action_on_fail