]> git.pld-linux.org Git - projects/geninitrd.git/blame - geninitrd
One install is fine.
[projects/geninitrd.git] / geninitrd
CommitLineData
bb529f94
JK
1#!/bin/sh
2
3# geninitrd
4#
45d4d8cb 5# by PLD Linux Team
bb529f94 6#
9e1ceabe 7# based on mkinitrd from RedHat Linux
e4b07ddc 8#
c31050f3 9
b7114dde 10VERSION='devel'
ca2c2012 11PROGRAM=${0##*/}
bb529f94
JK
12
13. /etc/rc.d/init.d/functions
ded87775 14. /lib/geninitrd/functions
e2405b29 15. /etc/sysconfig/system
bb529f94 16
c124d0cf
ER
17# list of geninitrd modules which need setup routine after commandline args parsing
18GENINITRD_MODS=""
c3667d07 19COMPRESS=yes
897d14b7 20STRIP=/usr/bin/strip
bb529f94
JK
21target=""
22kernel=""
23force=""
24verbose=""
25MODULES=""
26img_vers=""
c3667d07 27fstab=/etc/fstab
c3667d07 28modext=.o
4e9eb79c 29rootdev_nr=0
738c05d8
ER
30# device node for rootfs from fstab
31rootdev=""
bb529f94 32
8bd582f1
ER
33# internal variables
34# is /dev on tmpfs
b64f015b
ER
35dev_mounted=no
36# is /proc mounted
37proc_mounted=no
38# is /sys mounted
39sys_mounted=no
40# is /tmp mounted on tmpfs
41tmp_mounted=no
42
43# are /dev nodes already created from /proc/devices info?
8bd582f1 44proc_partitions=no
6b013929 45
b64f015b 46usage() {
46768f45 47 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
ac085800 48 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
8a6f083b 49 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
76a48507 50 echo " [--nostrip ] [--strip PATH/strip] [--strip=PATH/strip]"
92ed99b6 51 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
ba5d09f0 52 echo " [--with-bootsplash] [--without-bootsplash]"
6c69a2d4
ER
53 echo " [--with-fbsplash] [--without-fbsplash]"
54 echo " [--with-fbcondecor] [--without-fbcondecor]"
e4b07ddc 55 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
ba5d09f0 56 echo " [--with-suspend] [--without-suspend]"
1cd2aabd 57 echo " [--with-tuxonice] [--without-tuxonice]"
ecd7bf46
ER
58 echo " [--without-dmraid]"
59 echo " [--with-multipath=DEVPATH] [--without-multipath]"
3ef3d717 60 echo " [--without-blkid] [--without-luks]"
ac085800 61 echo " <initrd-image> <kernel-version>"
553786c4 62 echo ""
46768f45
ER
63 echo "Example:"
64
0ad676eb 65 local kdir kver dir=${target:-/boot}
46768f45
ER
66 for kdir in /lib/modules/*; do
67 [ -d $kdir ] || continue
68 kver=${kdir##*/}
dfe1a27c 69 echo " $0 -f --initrdfs=initramfs $dir/initrd-$kver.gz $kver $verbose"
63514069 70 done | sort -V
bb529f94
JK
71}
72
779a218a 73msg() {
f4010f7f
AM
74 echo "$PROGRAM: $*"
75}
76
77warn() {
4a60c01f 78 msg "WARNING: $*" >&2
779a218a
AM
79}
80
02ba8ab7 81verbose() {
34f3f0e9 82 [ -n "$verbose" ] && msg "$*" >&3
02ba8ab7
ER
83}
84
94769f11 85debug() {
02ba8ab7 86 [ x"$verbose" = x"-v -v" ] && msg "$*" >&3
94769f11 87}
aa69da6e 88
2b945b6b
ER
89# add initrd code to print to kmsg
90# @param string message
91# @param int loglevel. defaults to "6" (info)
92# Log levels can be:
93# Name String Meaning
94# KERN_EMERG "0" Emergency messages, system is about to crash or is unstable
95# KERN_ALERT "1" Something bad happened and action must be taken immediately
96# KERN_CRIT "2" A critical condition occurred like a serious hardware/software failure
97# KERN_ERR "3" An error condition, often used by drivers to indicate difficulties with the hardware
98# KERN_WARNING "4" A warning, meaning nothing serious by itself but might indicate problems
99# KERN_NOTICE "5" Nothing serious, but notably nevertheless. Often used to report security events.
100# KERN_INFO "6" Informational message e.g. startup information at driver initialization
101# KERN_DEBUG "7" Debug messages
102# KERN_CONT "c" "continued" line of log printout (only done after a line that had no enclosing \n)
103kmsg() {
104 local msg="$1" level=${2:-6}
105 echo "echo '<$level>$msg' > /dev/kmsg" | add_linuxrc
106}
107
bf6c3fcb
ER
108# aborts program abnormally
109die() {
b5f5c089 110 local rc=${2:-1}
046c68c9 111 msg "ERROR: $1" >&2
bf6c3fcb
ER
112 exit $rc
113}
114
684d5d2a
ER
115# find program from specified paths
116find_tool() {
27442691 117 local x p b n
c45a111c 118 local paths="$initrd_dirs /bin /sbin /usr/bin /usr/sbin"
684d5d2a 119 for x in "$@"; do
5493388d 120 debug "find_tool: checking $x"
684d5d2a
ER
121 if [ -x "$x" ]; then
122 echo $x
02ba8ab7 123 verbose "find_tool: found $x"
684d5d2a
ER
124 return 0
125 fi
27442691
JR
126 n="$x"
127 for p in $paths; do
128 b=$(basename $x)
5493388d 129 debug "find_tool: checking $p/$b"
27442691
JR
130 if [ -x "$p/$b" ]; then
131 echo $p/$b
132 verbose "find_tool: found $p/$b"
133 return 0
134 fi
135 n="$n $p/$b"
136 done
684d5d2a 137 done
27442691 138 debug "find_tool: did not find any of: $n"
684d5d2a
ER
139 return 1
140}
141
c124d0cf
ER
142# loads geninitrd modules
143geninitrd_load_mods() {
144 local mod
145 for mod in "$@"; do
146 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
147 die "$mod geninitrd module can't be loaded"
148 fi
149 . /lib/geninitrd/mod-$mod.sh
150
c34c6a69 151 GENINITRD_MODS="$GENINITRD_MODS $mod"
c124d0cf
ER
152 done
153}
154
155# setup geninitrd modules
156geninitrd_setup_mods() {
b7114dde 157 local mod
c124d0cf
ER
158
159 for mod in $GENINITRD_MODS; do
b7114dde 160 debug "# $mod"
c34c6a69
ER
161
162 # some mods want init
163 if type setup_mod_$mod > /dev/null; then
164 eval setup_mod_$mod
165 fi
c124d0cf
ER
166 done
167}
168
c6c6ce01
ER
169# append text to /linuxrc
170# takes STDIN as input
171add_linuxrc() {
b64f015b 172 cat >> "$RCFILE"
c6c6ce01
ER
173}
174
b64f015b
ER
175# generate code to mount /dev on tmpfs and create initial nodes
176# can be called multiple times. /dev is cleaned up (umounted) automatically at
177# the end of script.
178mount_dev() {
b64f015b
ER
179 # we already generated tmpfs code; return
180 if is_yes "$dev_mounted"; then
181 return
182 fi
183
184 dev_mounted=yes
185
186 busybox_applet mount mknod mkdir
187 add_linuxrc <<-EOF
188 : 'Creating /dev'
621695f6
AF
189 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
190 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
13659675
AM
191 mknod -m 600 /dev/console c 5 1
192 mknod -m 666 /dev/null c 1 3
193 mknod -m 666 /dev/zero c 1 5
194 mknod -m 666 /dev/random c 1 8
195 mknod -m 600 /dev/snapshot c 10 231
196 mknod -m 666 /dev/urandom c 1 9
197 mknod -m 666 /dev/ptmx c 5 2
198 mknod -m 644 /dev/kmsg c 1 11
621695f6 199 fi
b64f015b
ER
200 mkdir /dev/pts
201 mkdir /dev/shm
202 EOF
203}
204
ff9aded5
AM
205# load font
206load_font() {
207 local font
208 [ ! -r /etc/sysconfig/console ] && return
209 . /etc/sysconfig/console
210 if [ -n "$CONSOLEFONT" ]; then
211 font=$(ls -1 /lib/kbd/consolefonts/${CONSOLEFONT}*.gz 2> /dev/null)
212 if [ -n "$font" ]; then
213 verbose "Loading font $font"
214 busybox_applet loadfont
215 inst_d "/lib/kbd/consolefonts"
216 cp -a "$font" "$DESTDIR/lib/kbd/consolefonts/"
217 gunzip ${DESTDIR}/lib/kbd/consolefonts/${CONSOLEFONT}*.gz
218 font=${font%.gz}
219 echo "loadfont < $font" | add_linuxrc
220 fi
221 fi
222}
223
b64f015b
ER
224# generate code to mount /proc on initrd
225# can be called multiple times
226mount_proc() {
227 if is_yes "$proc_mounted"; then
228 return
229 fi
230
231 proc_mounted=yes
2bface63
ER
232 if [ "$INITRDFS" = "initramfs" ]; then
233 # /proc is mounted with initramfs 2.6.22.14 kernel
234 # XXX: remove when it is clear why proc was already mounted
235 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
236 else
237 echo "mount -t proc none /proc" | add_linuxrc
238 fi
b64f015b
ER
239}
240
241# generate code to mount /sys on initrd
242# can be called multiple times
243mount_sys() {
244 if is_yes "$sys_mounted"; then
245 return
246 fi
247
248 sys_mounted=yes
249 echo "mount -t sysfs none /sys" | add_linuxrc
250}
251
252# generate code to mount /tmp on initrd
253# can be called multiple times
254mount_tmp() {
255 if [ "$INITRDFS" = "initramfs" ]; then
256 # initramfs is read-write filesystem, no need for tmpfs
257 return
258 fi
259
260 if is_yes "$tmp_mounted"; then
261 return
262 fi
263
264 tmp_mounted=yes
265 echo "mount -t tmpfs none /tmp" | add_linuxrc
266}
267
d63131e0
AF
268# generate code to mount /run on initrd
269# can be called multiple times
270mount_run() {
271 if is_yes "$run_mounted"; then
272 return
273 fi
274
275 run_mounted=yes
276 echo "mount -t tmpfs run /run" | add_linuxrc
277}
278
b64f015b 279# unmount all mountpoints mounted by geninitrd
c6d164fb 280# try to move pseudo filesystems to newroot if possible
b64f015b 281umount_all() {
ec49b7e6
ER
282
283 add_linuxrc <<-'EOF'
903f21ea 284 : Last shell before umounting all and giving control over to real init.
ec49b7e6
ER
285 debugshell
286 EOF
5b70f84d 287
d63131e0 288 if is_yes "$run_mounted"; then
c6d164fb
ER
289 add_linuxrc <<-EOF
290 mount --bind /run /newroot/run
291 umount /run
292 EOF
d63131e0
AF
293 run_mounted=no
294 fi
b64f015b 295 if is_yes "$dev_mounted"; then
c6d164fb
ER
296 add_linuxrc <<-EOF
297 mount --bind /dev /newroot/dev
298 umount /dev
299 EOF
b64f015b
ER
300 dev_mounted=no
301 fi
b64f015b 302 if is_yes "$sys_mounted"; then
c6d164fb
ER
303 add_linuxrc <<-EOF
304 mount --bind /sys /newroot/sys
305 umount /sys
306 EOF
b64f015b
ER
307 sys_mounted=no
308 fi
c6d164fb
ER
309 if is_yes "$proc_mounted"; then
310 add_linuxrc <<-EOF
311 mount --bind /proc /newroot/proc
312 umount /proc
313 EOF
314 proc_mounted=no
315 fi
b64f015b
ER
316 if is_yes "$tmp_mounted"; then
317 echo 'umount /tmp' | add_linuxrc
318 tmp_mounted=no
319 fi
320}
321
9299682f
ER
322# Checks if busybox has support for APPLET(s)
323# Exits from geninitrd if the support is not present.
324#
325# NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
326busybox_applet() {
30495bbf 327 local err=0 applet
9299682f
ER
328
329 if [ -z "$busybox_functions" ]; then
684d5d2a 330 local tmp=$($busybox 2>&1)
9b1373fb
ER
331
332 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
333 if [[ "$tmp" = *applet\ not\ found* ]]; then
334 local t=$(mktemp -d)
684d5d2a 335 ln -s $busybox $t/busybox
9b1373fb
ER
336 local tmp=$($t/busybox 2>&1)
337 rm -rf $t
338 fi
339
340 busybox_functions=$(echo "$tmp" | \
9299682f
ER
341 sed -ne '/Currently defined functions:/,$p' | \
342 xargs | sed -e 's,.*Currently defined functions: ,,'
343 )
344 fi
345 for applet in $*; do
346 local have
347 # try cache
348 eval have='$'busybox_have_$applet
349 if [ -z "$have" ]; then
e871f497 350 have=$(echo "$busybox_functions" | grep -Ec "( |^)$applet(,|$)")
9299682f 351 if [ "$have" = 0 ]; then
f4010f7f 352 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
9299682f
ER
353 err=1
354 fi
355 eval busybox_have_$applet=$have
356 fi
357 done
358 if [ $err = 1 ]; then
00eaa938 359 die "Aborted"
9299682f
ER
360 fi
361}
362
755e5cdc
ER
363# Extract the .config file from a kernel image
364# uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
365ikconfig() {
61d20b49 366 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
755e5cdc
ER
367 if [ -n "$kofile" ]; then
368 /lib/geninitrd/extract-ikconfig $kofile
7283bf35 369 return
25cb53df 370 fi
7283bf35
ER
371
372 # see if config available as separate file
373 if [ -f /boot/config-$kernel ]; then
374 cat /boot/config-$kernel
375 return
376 fi
377
378 # finally try vmlinuz itself
379 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
25cb53df
ER
380}
381
faee129c
AM
382# @param $module
383basename_module() {
384 local module=$1
385
386 module=${module##*/}
387 module=${module%$modext*}
388 echo $module
389}
390
7ffba534
ER
391# Finds module dependencies
392#
7ffba534
ER
393# @param $module
394#
046c68c9 395# Outputs full path to module and it's dependencies
7ffba534 396find_depmod() {
fe280785 397 local module="$1"
046c68c9
ER
398 local skiperrors=0
399
400 # if module is prefixed with dash, we should ignore errors if the module
401 # can't be found.
402 if [ ${module#-} != $module ]; then
403 skiperrors=1
404 module=${module#-}
405 fi
406
046c68c9
ER
407 # This works when user has module-init-tools installed even on 2.4 kernels
408 local modprobe
409 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
410
411 if [ $? != 0 ]; then
412 if [ $skiperrors = 1 ]; then
0c7e9123 413 return 0
7cac5014 414 fi
046c68c9 415 echo >&2 "$modprobe"
7cac5014 416
7ffba534 417 if ! is_no "$EXIT_IF_MISSING"; then
046c68c9 418 die "$module: module not found for $kernel kernel"
7ffba534 419 fi
046c68c9
ER
420
421 warn "$module: module not found for $kernel kernel"
422 warn "If $module isn't compiled in kernel then this initrd may not start your system."
7ffba534
ER
423 fi
424
faee129c
AM
425 local smodule
426
046c68c9 427 echo "$modprobe" | \
c25765ed 428 while read insmod modpath options; do
faee129c
AM
429 if [ "$insmod" = "insmod" ]; then
430
431 # XXX: find a away to autodetect
432 smodule=$(basename_module $modpath)
433 case "$smodule" in
b771ab7f
AM
434 btrfs)
435 find_depmod "-libcrc32c"
436 ;;
bb0ca032 437 crc-t10dif)
e7d76a06 438 find_depmod "-crct10dif-pclmul"
bb0ca032
AM
439 find_depmod "-crct10dif"
440 ;;
faee129c
AM
441 libcrc32c)
442 find_depmod "-crc32c-intel"
443 find_depmod "-crc32c"
444 ;;
dd1e5379
AM
445 virtio_blk|virtio_scsi)
446 find_depmod "-virtio_pci"
447 find_depmod "-virtio_mmio"
448 ;;
faee129c
AM
449 esac
450
451 echo $modpath
452 fi
7ffba534 453 done
0c7e9123 454 return 0
7ffba534
ER
455}
456
4a60c01f
AM
457find_firmware() {
458 local module="$1"
601127ea
ER
459
460 # no firmware support in 2.4 kernels
461 if [ "$kernel_version_long" -lt "002005048" ]; then
462 return
463 fi
464 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
4a60c01f
AM
465}
466
046c68c9
ER
467# @param $module
468find_module() {
469 local mod depmod module=$1
ac085800 470
046c68c9 471 depmod=$(find_depmod $module) || exit 1
fe280785 472 for mod in $depmod; do
7ffba534 473 mod=${mod#/lib/modules/$kernel/}
fe280785
ER
474
475 # add each module only once
476 local m have=0
477 for m in $MODULES; do
478 [ $m = $mod ] && have=1
479 done
480 if [ $have = 0 ]; then
c2eb7d4f 481 MODULES="$MODULES $mod"
fe280785 482 fi
10c3df06 483 done
bb529f94
JK
484}
485
034fdd5d
ER
486# install a file to temporary mount image.
487# it will operate recursively (copying directories)
488# and will symlink destinations if source is symlink.
bb529f94 489inst() {
17e97aec 490 if [ $# -lt 2 ]; then
a9ace64a 491 die 'Usage: inst <file> [<file>] <destination>'
c31050f3 492 fi
17e97aec
ER
493
494 local src i=0 c=$(($# - 1))
495 while [ $i -lt $c ]; do
496 src="$src $1"
497 i=$((i + 1))
498 shift
499 done
500 local dest=$1
501 set -- $src
ce40ba21 502 local parentDir=$(dirname $DESTDIR$dest)
02ba8ab7 503 if [ ! -d "$parentDir" ]; then
7f5eccc0 504 verbose "+ mkdir -p DESTDIR${parentDir#$DESTDIR}"
02ba8ab7
ER
505 mkdir -p $parentDir
506 fi
7f5eccc0 507 verbose "+ cp $* DESTDIR$dest"
9b557a09 508 cp -HR "$@" "$DESTDIR$dest"
bb529f94
JK
509}
510
dab92b1d 511inst_d() {
17e97aec 512 if [ $# = 0 ]; then
a9ace64a 513 die 'Usage: inst_d <destination> <destination>'
034fdd5d 514 fi
7c239866 515 local dir
034fdd5d 516 for dir in "$@"; do
9b557a09 517 install -d "$DESTDIR$dir"
034fdd5d
ER
518 done
519}
520
209061e3
ER
521# install executable and it's shared libraries
522inst_exec() {
17e97aec 523 if [ $# -lt 2 ]; then
3601c2fa 524 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
17e97aec 525 fi
209061e3
ER
526 local src i=0 c=$(($# - 1))
527 while [ $i -lt $c ]; do
528 src="$src $1"
529 i=$((i + 1))
530 shift
531 done
9b532fe6 532 local dest=$1
209061e3
ER
533 set -- $src
534
9b532fe6
ER
535 inst "$@" $dest
536
c45a111c 537 local obj lib libs libdir
10e8125f 538 for obj in "$@"; do
66aec48b 539 case "$obj" in
68c2e3b2 540 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2 | /libx32/ld-linux-x32.so.2)
66aec48b
ER
541 continue
542 esac
543
544 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
545 for lib in $libs; do
1be24d6e
ER
546 libdir=$(cd $(dirname "$lib"); pwd)
547 if [ ! -f "$DESTDIR/$lib" ]; then
548 inst_d $libdir
549 inst_exec $lib $libdir
66aec48b
ER
550 fi
551 done
209061e3 552 done
c7ade647
ER
553
554 # hack for uclibc linked binaries requiring this fixed path
555 # XXX: shouldn't rpath be used here instead so th
54c9f5ee
AM
556 for _lib in $(get_libdir LIBDIR); do
557 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
558 lib=$DESTDIR/$_lib/libc.so.0
559 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
560 libdir=$(cd $(dirname "$lib"); pwd)
561 if [ ! -e $DESTDIR$libdir ]; then
562 libdir=$(dirname "$libdir")
563 inst_d $libdir
564 verbose "+ ln -s /$_lib $DESTDIR$libdir"
565 ln -s /$_lib $DESTDIR$libdir
566 break
567 fi
c7ade647 568 fi
54c9f5ee 569 done
209061e3
ER
570}
571
82474db9
ER
572# output modules.conf / modprobe.conf
573modprobe_conf() {
574 echo "$modprobe_conf_cache"
575}
576
38ac83a5
ER
577# return options for MODULE
578# @param $1 module name
579modprobe_options() {
580 local module=$1
915ff812 581 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
38ac83a5
ER
582 echo ${options# }
583}
584
82474db9
ER
585#
586# defaults to modprobe -c if not told otherwise, this means include statements
587# work from there.
588cache_modprobe_conf() {
707f5e60 589 if [ "$kernel_version" -lt "002005" ]; then
82474db9
ER
590 modulefile=/etc/modules.conf
591 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
592 modulefile=/etc/conf.modules
593 fi
594 fi
595
596 if [ -n "$modulefile" ]; then
d8056591 597 debug "Using $modulefile for modules config"
99e7251e
ER
598 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
599
82474db9 600 else
d8056591 601 debug "Using modprobe -c to get modules config"
99e7251e 602 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
82474db9
ER
603 fi
604}
605
bc0d6f2d 606# find modules for $devpath
d8056591 607find_modules_for_devpath() {
bc0d6f2d
ER
608 local devpath="$1"
609 if [ -z "$devpath" ]; then
d8056591 610 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
f6536797 611 fi
ac085800 612
c2eb7d4f
ER
613 if [[ "$devpath" = /dev/dm-* ]]; then
614 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
d2cb46cf 615 devpath=$(dm_node "$devpath")
c2eb7d4f
ER
616 fi
617
336018a5 618 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
c2eb7d4f
ER
619 # sanitize things like:
620 # /dev/block/104:2 -> /dev/cciss/c0d0p2
621 devpath=$(readlink -f "$devpath")
622 fi
623
02ba8ab7 624 verbose "Finding modules for device path $devpath"
bc0d6f2d 625
3ef3d717
ER
626 if is_luks "$devpath"; then
627 find_modules_luks "$devpath"
628 return
629 fi
630
74d45ce1
ER
631 if is_nfs "$devpath"; then
632 find_modules_nfs "$devpath"
d9179777
ER
633 return
634 fi
635
e16414d9 636 if is_md "$devpath"; then
df738638 637 find_modules_md "$devpath"
d9179777
ER
638 return
639 fi
640
c3b54060 641 if is_multipath "$devpath"; then
07137fe3 642 if find_modules_multipath "$devpath"; then
9baf4f3f 643 return
9baf4f3f 644 fi
ecd7bf46 645
9baf4f3f
ER
646 # fallback
647 fi
648
36523626 649 if is_dmraid "$devpath"; then
c083ae23
ER
650 if find_modules_dmraid "$devpath"; then
651 return
652 fi
653 # fallback
654 fi
655
35043b20
ER
656 if is_scsi "$devpath"; then
657 find_modules_scsi "$devpath"
d9179777
ER
658 return
659 fi
660
30ca4815 661 if is_ide "$devpath"; then
bc0d6f2d 662 find_modules_ide "$devpath"
d9179777
ER
663 return
664 fi
665
0bdde1a1
ER
666 if [[ "$devpath" == /dev/bcache* ]]; then
667 find_modules_bcache "$devpath"
668 return
669 fi
670
07b09cf9 671 if [[ "$devpath" == /dev/rd/* ]]; then
046c68c9 672 find_module "DAC960"
c3313cd6 673 rootdev_add=/dev/rd/
d9179777
ER
674 return
675 fi
676
07b09cf9 677 if [[ "$devpath" == /dev/ida/* ]]; then
046c68c9 678 find_module "cpqarray"
c3313cd6 679 rootdev_add=/dev/ida/
d9179777
ER
680 return
681 fi
682
08651ad1 683 if [[ "$devpath" == /dev/cciss/* ]]; then
c3313cd6 684 rootdev_add=/dev/cciss/
df11fbe8
ER
685
686 # load hpsa for future kernels, cciss for backwards compat
687 if [ "$kernel_version_long" -ge "003000000" ]; then
688 find_module "hpsa" "-cciss"
649df3de 689 find_modules_scsi "$devpath"
df11fbe8
ER
690 else
691 find_module "cciss"
692 fi
693
d9179777
ER
694 return
695 fi
696
07b09cf9 697 if [[ "$devpath" == /dev/ataraid/* ]]; then
ac085800 698 find_modules_ide
046c68c9 699 find_module "ataraid"
99e7251e 700 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
9ae446b9 701 if [ -n "$ataraidmodules" ]; then
7c38b114 702 # FIXME: think about modules compiled in kernel
82474db9 703 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
7c38b114
AF
704 fi
705 for n in $ataraidmodules; do
046c68c9 706 find_module "$n"
7c38b114 707 done
c3313cd6 708 rootdev_add=/dev/ataraid/
d9179777
ER
709 return
710 fi
711
7c38b114 712 # check to see if we need to set up a loopback filesystem
07b09cf9 713 if [[ "$devpath" == /dev/loop* ]]; then
00eaa938 714 die "Sorry, root on loop device isn't supported."
7c38b114
AF
715 # TODO: rewrite for bsp and make nfs ready
716 if [ ! -x /sbin/losetup ]; then
00eaa938 717 die "losetup is missing"
7c38b114 718 fi
bc0d6f2d 719 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
82474db9 720 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
42820142 721 die "The root filesystem is on a $devpath, but there is no magic entry in $fstab for this device. Consult the $PROGRAM man page for more information"
7c38b114
AF
722 fi
723
724 line="`awk '/'$key'/ { print $0; }' $fstab`"
725 loopDev="$(echo $line | awk '{print $3}')"
726 loopFs="$(echo $line | awk '{print $4}')"
727 loopFile="$(echo $line | awk '{print $5}')"
728
729 BASICMODULES="$BASICMODULES -loop"
046c68c9 730 find_module "-$loopFs"
7c38b114 731 BASICMODULES="$BASICMODULES -${loopFs}"
d9179777
ER
732 return
733 fi
734
67aa84bd
ER
735 if is_lvm "$devpath"; then
736 find_modules_lvm "$devpath"
d9179777 737 return
7c38b114
AF
738 fi
739}
740
b64f015b 741firmware_install_module() {
c3667d07 742 local module="$1"
c6c6ce01 743 local firmware_files="$2"
9ed6e1db 744
02ba8ab7 745 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
9ed6e1db 746 # firmware not yet installed
9b557a09 747 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
034fdd5d 748 inst_d /lib/firmware
9b557a09 749cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
9ed6e1db 750#!/bin/sh -e
45294dc1
ER
751# handle only firmware add requests
752if [ "$SUBSYSTEM" != "firmware" ]; then
753 exit 0
754fi
755if [ "$ACTION" != "add" ]; then
756 exit 0
757fi
8639f99a
AM
758echo 1 > /sys$DEVPATH/loading
759cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
760echo 0 > /sys$DEVPATH/loading
761exit 0
9ed6e1db 762EOF
9b557a09 763 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
63cb815e
ER
764
765 # setup firmware loader agent
766 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
9ed6e1db
AM
767 fi
768
769 for firmware in $firmware_files; do
80b23733 770 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
486d26a5 771 FIRMWAREDIR=${firmware%/*}
4a9920e7 772 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
80b23733
ER
773 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
774 elif [ -f "/lib/firmware/$firmware" ]; then
c661b23c 775 FIRMWAREDIR=${firmware%/*}
776 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
80b23733 777 inst /lib/firmware/$firmware /lib/firmware/$firmware
c661b23c 778 else
6652b089 779 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
4a60c01f 780 fi
9ed6e1db
AM
781 done
782
b64f015b 783 mount_sys
9ed6e1db
AM
784}
785
2a5bcca9 786modules_install() {
c3667d07
ER
787 local modules="$1"
788 local mod
2a5bcca9
AM
789
790 for mod in $modules; do
fe280785 791 MODULEDIR=${mod%/*}
4a9920e7 792 inst_d "/lib/modules/$kernel/$MODULEDIR"
9b557a09 793 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
5d62840e
AM
794 case $mod in
795 *.gz)
b657b865 796 gunzip "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress gz"
5d62840e
AM
797 mod=${mod%.gz}
798 ;;
799 *.xz)
b657b865 800 xz -d "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress xz"
5d62840e
AM
801 mod=${mod%.xz}
802 ;;
803 *.bz2)
b657b865 804 bzip2 -d "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress bz2"
5d62840e
AM
805 mod=${mod%.bz2}
806 ;;
807 esac
897d14b7 808 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
5d62840e 809 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod}"
ccd1f65f 810 fi
2a5bcca9
AM
811 done
812}
813
814modules_add_linuxrc() {
fe280785 815 local mod modpath
ac085800 816
fe280785
ER
817 for mod in "$@"; do
818 # module path without optional compression
819 modpath=${mod%.gz}
5d62840e
AM
820 modpath=${modpath%.xz}
821 modpath=${modpath%.bz2}
fe280785
ER
822
823 # name of the module
8011a76c 824 local module=${modpath##*/}; module=${module%$modext}
38ac83a5 825 local options=$(modprobe_options "$module")
8011a76c
ER
826 local genericname=$(echo $module | tr - _)
827 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
828 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
2a5bcca9 829
3e1d0df9
AM
830 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
831 options="scan=sync $options"
832 fi
833
02ba8ab7 834 if [ x"$verbose" = x"-v" ]; then
8a47b72c
ER
835 s=""
836 if [ "$options" ]; then
837 s="$s with options [$options]"
838 fi
8011a76c
ER
839 if [ "$usleep" ]; then
840 s="$s and $usleep usleep"
8a47b72c 841 fi
02ba8ab7 842 verbose "Loading module [$module]$s"
ac085800
ER
843 fi
844
8011a76c
ER
845 if [ -n "$firmware" ]; then
846 firmware_install_module "$module" "$firmware"
4a60c01f 847 else
06e481d7
ER
848 for file in $(find_firmware "$module"); do
849 firmware_install_module "$module" "$file"
850 done
9ed6e1db 851 fi
4a60c01f 852
18ece493 853 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
8011a76c
ER
854 if [ -n "$usleep" ]; then
855 echo "usleep $usleep" | add_linuxrc
8e598759 856 fi
e00dcfcb 857 if [ "$module" = "scsi_wait_scan" ]; then
d29583e0
ER
858 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
859 echo "rmmod scsi_wait_scan" | add_linuxrc
860 fi
e00dcfcb
AM
861 fi
862
2a5bcca9
AM
863 done
864}
865
82b2dba2
ER
866# Generates /dev nodes based on /proc/partitions information.
867# Needs /proc mounted.
868# Can be called multiple times.
869initrd_gen_devices() {
870 if is_yes "$proc_partitions"; then
871 return
872 fi
873 proc_partitions=yes
335cd101 874
82b2dba2
ER
875 mount_dev
876 add_linuxrc <<-'EOF'
877 : 'Making device nodes'
878 cat /proc/partitions | (
8d4aba01 879 # ignore first two lines: header, empty line
82b2dba2 880 read b; read b
2cc3ae8b 881
82b2dba2
ER
882 while read major minor blocks dev rest; do
883 node=/dev/$dev
884 mkdir -p ${node%/*}
6b45dd6c 885 [ -e $node ] || mknod -m 660 $node b $major $minor
82b2dba2
ER
886 done
887 )
888 EOF
889}
bb529f94 890
82b2dba2 891
4828c787 892initrd_gen_setrootdev() {
02ba8ab7 893 verbose "Adding rootfs finding based on kernel cmdline root= option support."
71b2d771 894 busybox_applet ls
b7114dde 895 debug "Current /proc/partitions:\n$(sed -e 's,^,| ,' /proc/partitions)"
82b2dba2 896 add_linuxrc <<-'EOF'
dcdf6b49
ER
897 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
898 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
94da85db
ER
899 # fallback to ls, try two different formats
900 # http://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2014-May/023915.html
901 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
902 # busybox up to 1.22
5efa9a2e 903 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
71b2d771 904 fi
94da85db
ER
905 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
906 # busybox 1.22 and upwards
907 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $5 + $6; }}')"
908 fi
909 if [ "${rootnr:-0}" -gt 0 ]; then
82b2dba2
ER
910 echo "$rootnr" > /proc/sys/kernel/real-root-dev
911 fi
912 fi
b64f015b 913 EOF
1606e343
AM
914}
915
4671d086
ER
916initrd_gen_initramfs_switchroot() {
917 inst_d /newroot
918 if [ "$rootdev" = "/dev/nfs" ]; then
919 echo "rootfs on NFS root=/dev/nfs"
920 else
921 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
922 fi
5845b321
ER
923
924 # parse 'root=xxx' kernel commandline
4671d086 925 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
ec21900e
ER
926
927 # from lilo-23.2/readme/README:
928 # root=<device> changes the root device. This overrides settings that may
929 # have been made in the boot image and on the LILO command line. <device> is
930 # either the hexadecimal device number or the full path name of the device,
931 # e.g. /dev/hda3 [*]
932 #
933 # * The device names are hard-coded in the kernel. Therefore, only the
934 # "standard" names are supported and some less common devices may not be
935 # recognized. In those cases, only numbers can be used.
5436b31f 936 busybox_applet cat
4671d086 937 add_linuxrc <<-'EOF'
7f187a08 938 device=
3564e6b6 939 eval "$(busybox awk -v root="$ROOT" '
f9194b15
ER
940 # http://9fans.net/archive/2006/09/261
941 function h2d(str, hstr, res, num, n, digit, i) {
942 hstr = "0123456789abdcef";
943 res = 0;
944 n = split(tolower(str), digit, "");
945
946 for (i = 1; i <= n; i++) {
947 num = index(hstr, digit[i]) - 1;
948 res = res + (num * 16 ^ (n - i));
949 }
950
951 return res;
952 }
4671d086 953 BEGIN {
f9194b15
ER
954
955 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
956 num_pattern = "[0-9a-fA-F]" num_pattern_short;
4671d086 957 dev_pattern = "[hms][a-z][a-z]([0-9])+";
7f187a08 958 partition = "";
4671d086
ER
959 min = -1; maj = -1;
960
3564e6b6
ER
961 # see if we have /dev/hdX or hdX, we can just take partition name
962 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
963 partition = root
964 sub("^/dev/", "", partition);
965
966 } else {
967 # unify values first
968 if (root ~ "^" num_pattern_short "$") {
969 # change "303" => "0x0303"
970 root = "0x0" root
971 } else if (root ~ "^" num_pattern "$") {
972 # change "0303" => "0x0303"
973 root = "0x" root
974 }
975
f9194b15
ER
976 maj = h2d(substr(root, 3, 2));
977 min = h2d(substr(root, 5, 2));
4671d086 978 }
4671d086
ER
979 }
980
7f187a08 981 partition && $4 == partition { maj = $1; min = $2; }
afa32d0e 982 $1 == maj && $2 == min { partition = $4; }
4671d086
ER
983
984 END {
fa3a5452 985 if (maj >= 0 && min >= 0) {
7f187a08
ER
986 printf("maj=%s; min=%s;\n", maj, min);
987 }
988 if (partition) {
989 printf("device=/dev/%s;\n", partition);
fa3a5452 990 }
4671d086
ER
991 }
992 ' /proc/partitions)"
4671d086 993
7f187a08 994 if [ -z "$device" ]; then
5436b31f
AM
995 if [ "$DEBUGINITRD" ]; then
996 cat /proc/partitions
997 fi
0fb9dda3 998 device=$ROOT
4671d086
ER
999 fi
1000
481bdb77 1001 if [ "$device" -a ! -b $device -a "$maj$min" ]; then
6b45dd6c 1002 mknod -m 660 $device b $maj $min
7f187a08
ER
1003 fi
1004
86aa389f
ER
1005 # XXX hack, if no device, try to parse it from /proc/partitions using /proc/sys/kernel/real-root-dev
1006 if [ ! -e "$device" ]; then
1007 rrd=$(cat /proc/sys/kernel/real-root-dev)
1008 major=$(($rrd / 256))
1009 minor=$(($rrd % 256))
1010
1011 while read pmajor pminor blocks dev rest; do
1012 # skip header and empty line
1013 [ -z "$pmajor" -o "$pmajor" = "major" ] && continue
1014
1015 if [ $pmajor = $major -a $pminor = $minor ]; then
1016 device=/dev/$dev
1017 echo "DEVICE set to $device based on real-root-dev"
1018 fi
1019 done < /proc/partitions
1020 fi
1021
144396dd 1022 [ -n "$ROOTFLAGS" ] && ROOTFLAGS="-o $ROOTFLAGS"
41d3645c 1023
144396dd 1024 mount -t $ROOTFS -r $device $ROOTFLAGS /newroot || echo "Mount of rootfs failed."
0fb9dda3 1025 init=$INIT
4671d086
ER
1026 if [ -z "$init" -o ! -x "/newroot$init" ]; then
1027 init=/sbin/init
1028 fi
1029 EOF
1030
b1ae7c80
AM
1031 busybox_applet dmesg
1032 busybox_applet tail
1033 add_linuxrc <<-'EOF'
1034 if [ "$DEBUGINITRD" ]; then
1035 echo "Last 20 lines of dmesg:"
1036 dmesg | tail -n 20
1037 fi
2b945b6b 1038
b1ae7c80
AM
1039 EOF
1040
2b945b6b
ER
1041 kmsg "geninitrd/$VERSION switching root"
1042
4671d086 1043 umount_all
0273c2c4 1044 busybox_applet switch_root usleep
4671d086 1045 add_linuxrc <<-'EOF'
278e5013 1046 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
0273c2c4
ER
1047
1048 # switch root to empty dir will make kernel panic, so sleep 10s before it
1049 # switch_root needs to be pid 1, so there's no other way to recover from here
1050 # if /dev is missing, switch root will likely fail, give debug shell before that
1051 if [ ! -d /newroot/dev ]; then
1052 echo "/dev is missing, switch_root will likely fail"
1053 echo "if you booted with debugrd=sh, then you be given shell and you might able to recover this situation"
1054 debugshell
1055 [ "$DEBUGINITRD" ] || usleep 10000000
1056 fi
1057
72a1b0ef
ER
1058 # systemd[1]: /usr appears to be on its own filesytem and is not
1059 # already mounted. This is not a supported setup. Some things will
1060 # probably break (sometimes even silently) in mysterious ways. Consult
1061 # http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
1062 # for more information.
1063 echo trying to mount /usr
1064 chroot /newroot mount -n /usr
1065
f8ea6a63 1066 exec switch_root /newroot $init ${1:+"$@"}
4671d086 1067
0273c2c4
ER
1068 # FIXME: this code is never executed, as "exec" does not return!
1069
4671d086
ER
1070 echo "Error! initramfs should not reach this place."
1071 echo "It probably means you've got old version of busybox, with broken"
1072 echo "initramfs support. Trying to boot anyway, but won't promise anything."
1073
f8ea6a63 1074 exec chroot /newroot $init ${1:+"$@"}
4671d086
ER
1075
1076 echo "Failed to chroot!"
b61aa273 1077 debugshell
4671d086
ER
1078 EOF
1079 # we need /init being real file, not symlink, otherwise the initramfs will
1080 # not be ran by pid 1 which is required for switch_root
1081 mv $DESTDIR/linuxrc $DESTDIR/init
1082 ln -s init $DESTDIR/linuxrc
1083}
1084
c552503c
ER
1085# find if $symbol exists in System.map $mapfile
1086sym_exists() {
1087 local mapfile="$1"
1088 local symbol="$2"
1089 if [ ! -f $mapfile ]; then
1090 # missing mapfile (not a pld kernel?)
1091 return 1
1092 fi
1093
1094 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
1095}
1096
1097# find best compressor (or forced one) for initrd
1098find_compressor() {
1099 local mode="$1"
1b89c904
AM
1100 # fastest initrd decompression speed is first
1101 local compressors='lzo gzip xz lzma bzip2'
c552503c
ER
1102
1103 # a specified one, take it
55aaf2fe
AM
1104 if ! is_yes "$mode"; then
1105 compressors="$mode"
c552503c
ER
1106 fi
1107
02ba8ab7 1108 verbose "finding compressor: $compressors (via $mode)"
c552503c
ER
1109 # check for compressor validity
1110 local c prog map=/boot/System.map-$kernel
1111 for c in $compressors; do
1112 case $c in
66d146a5 1113 xz)
29f7d622
AM
1114 sym=unxz
1115 prog=/usr/bin/xz
1116 ;;
1117 lzma)
c552503c 1118 sym=unlzma
66d146a5 1119 prog=/usr/bin/xz
c552503c
ER
1120 ;;
1121 bzip2)
1122 sym=bzip2
c42692d4 1123 prog=/usr/bin/bzip2
c552503c
ER
1124 ;;
1125 gzip)
1126 sym=gunzip
c42692d4 1127 prog=/bin/gzip
c552503c 1128 ;;
8a6f083b
AM
1129 lzo)
1130 sym=unlzo
1131 prog=/usr/bin/lzop
1132 ;;
5fcc3d04
AM
1133 none|no)
1134 # any existing sym will work
1135 sym=initrd_load
1136 prog=/bin/cat
1137 ;;
c552503c
ER
1138 *)
1139 die "Unknown compressor $c"
1140 ;;
1141 esac
c454c66e 1142 if sym_exists $map $sym && [ -x $prog ]; then
c552503c
ER
1143 echo $c
1144 return
1145 fi
1146 done
1147
02ba8ab7 1148 verbose "using gzip for compressor (fallback)"
c552503c
ER
1149 echo gzip
1150}
1151
97f51b6e
ER
1152# compresses kernel image image
1153# in function so we could retry with other compressor on failure
1154compress_image() {
1155 local compressor="$1" IMAGE="$2" target="$3" tmp
1156 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1157
1158 case "$compressor" in
1159 xz)
1160 # don't use -9 here since kernel won't understand it
1161 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1162 ;;
1163 lzma)
1164 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1165 ;;
1166 bzip2)
1167 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1168 ;;
1169 gzip)
1170 gzip -9 < "$IMAGE" > "$tmp" || return $?
1171 ;;
8a6f083b
AM
1172 lzo)
1173 lzop -9 < "$IMAGE" > "$tmp" || return $?
1174 ;;
5fcc3d04
AM
1175 none|no)
1176 cat < "$IMAGE" > "$tmp" || return $?
1177 ;;
97f51b6e
ER
1178 esac
1179
1180 mv -f "$tmp" "$target"
1181}
1182
82b2dba2
ER
1183if [ -r /etc/sysconfig/geninitrd ]; then
1184 . /etc/sysconfig/geninitrd
1185fi
2cc3ae8b 1186
c215292c
AG
1187if [ ! -f /proc/mounts ]; then
1188 warn "/proc filesystem not mounted, may cause wrong results or failure."
1189fi
1190
2d769917 1191geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd bcache
c124d0cf 1192
82b2dba2
ER
1193while [ $# -gt 0 ]; do
1194 case $1 in
1195 --fstab=*)
1196 fstab=${1#--fstab=}
1197 ;;
1198 --fstab)
1199 fstab=$2
1200 shift
1201 ;;
1202 --modules-conf=*)
1203 modulefile=${1#--modules-conf=}
1204 ;;
1205 --modules-conf)
1206 modulefile=$2
1207 shift
1208 ;;
82b2dba2
ER
1209 --with-bootsplash)
1210 BOOT_SPLASH=yes
1211 ;;
1212 --without-bootsplash)
1213 BOOT_SPLASH=no
1214 ;;
1215 --with-fbsplash)
1216 FB_SPLASH=yes
1217 ;;
1218 --without-fbsplash)
1219 FB_SPLASH=no
1220 ;;
6c69a2d4
ER
1221 --with-fbcondecor)
1222 FB_CON_DECOR=yes
1223 ;;
1224 --without-fbcondecor)
1225 FB_CON_DECOR=no
1226 ;;
82b2dba2
ER
1227 --with-suspend)
1228 USE_SUSPEND=yes
1229 ;;
1230 --without-suspend)
1231 USE_SUSPEND=no
1232 ;;
1233 --with-suspend2 | --with-tuxonice)
1234 USE_TUXONICE=yes
1235 ;;
1236 --without-suspend2 | --without-tuxonice)
1237 USE_TUXONICE=no
1238 ;;
80b1ed79 1239 --lvmversion=*)
7308edee 1240 LVMTOOLSVERSION=${1#--lvmversion=}
82b2dba2 1241 ;;
80b1ed79 1242 --lvmtoolsversion=*)
1243 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1244 ;;
82b2dba2
ER
1245 --lvmtoolsversion|--lvmversion)
1246 LVMTOOLSVERSION=$2
1247 shift
1248 ;;
1249 --without-udev)
1250 USE_UDEV=no
1251 ;;
1252 --with-udev)
1253 USE_UDEV=yes
1254 ;;
1255 --without-dmraid)
1256 USE_DMRAID=no
1257 ;;
1258 --without-multipath)
ecd7bf46
ER
1259 USE_MULTIPATH=no
1260 ;;
1261 --with-multipath=*)
1262 USE_MULTIPATH=${1#--with-multipath=}
82b2dba2 1263 ;;
af075488 1264 --without-blkid)
1265 USE_BLKID=no
289fbc9b 1266 ;;
3ef3d717
ER
1267 --without-luks)
1268 USE_LUKS=no
1269 ;;
82b2dba2
ER
1270 --with=*)
1271 BASICMODULES="$BASICMODULES ${1#--with=}"
1272 ;;
1273 --with)
1274 BASICMODULES="$BASICMODULES $2"
1275 shift
1276 ;;
1277 --version)
1278 echo "$PROGRAM: version $VERSION"
1279 exit 0
1280 ;;
1281 -v)
02ba8ab7
ER
1282 if [ x"$verbose" = x"-v" ]; then
1283 verbose="-v -v"
1284 else
1285 verbose="-v"
1286 fi
11ab0dea 1287 exec 3>&1
82b2dba2 1288 ;;
c552503c
ER
1289 --compress)
1290 COMPRESS=$2
1291 ;;
1292 --compress=*)
1293 COMPRESS="${1#--compress=}"
1294 ;;
82b2dba2
ER
1295 --nocompress)
1296 COMPRESS=no
1297 ;;
ccd1f65f 1298 --nostrip)
76a48507
ER
1299 STRIP=
1300 ;;
1301 --strip=*)
1302 STRIP="${1#--strip=}"
1303 ;;
1304 --strip)
1305 STRIP=$2
1306 shift
ccd1f65f 1307 ;;
82b2dba2
ER
1308 --ifneeded)
1309 ifneeded=1
1310 ;;
1311 -f)
1312 force=1
1313 ;;
1314 --preload=*)
1315 PREMODS="$PREMODS ${1#--preload=}"
1316 ;;
1317 --preload)
1318 PREMODS="$PREMODS $2"
1319 shift
1320 ;;
2965cab9 1321 --fs=* | --fs)
bbbc32d0 1322 die "--fs option is obsoleted. Use --initrdfs instead"
82b2dba2
ER
1323 ;;
1324 --initrdfs=*)
1325 INITRDFS=${1#--initrdfs=}
1326 ;;
1327 --initrdfs)
1328 INITRDFS=$2
1329 shift
1330 ;;
1331 --image-version)
1332 img_vers=yes
1333 ;;
1334 --ide-only-root)
1335 ide_only_root="yes"
1336 ;;
1337 *)
1338 if [ -z "$target" ]; then
1339 target="$1"
1340 elif [ -z "$kernel" ]; then
1341 kernel="$1"
1342 else
7f6e5359 1343 usage
36523626 1344 exit 1
82b2dba2
ER
1345 fi
1346 ;;
1347 esac
f5db170b 1348
82b2dba2
ER
1349 shift
1350done
1351
1352if [ -z "$target" -o -z "$kernel" ]; then
7f6e5359 1353 usage
36523626 1354 exit 1
82b2dba2
ER
1355fi
1356
93a38d1a
ER
1357# main()
1358if [ "$(id -u)" != 0 ]; then
1359 die "You need to be root to generate initrd"
1360fi
1361
c45a111c
ER
1362for dir in libx32 lib64 lib; do
1363 initrd_dir=/usr/$dir/initrd
1364 if [ -d "$initrd_dir" ]; then
1365 initrd_dirs="$initrd_dirs $initrd_dir"
1366 fi
1367done
1368
e4487862
AM
1369kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1370kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
82b2dba2 1371
b7114dde 1372verbose "# geninitrd $VERSION"
c124d0cf
ER
1373debug "Using initrd_dir: $initrd_dir"
1374
6ec4aea6 1375busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
c124d0cf
ER
1376
1377# we setup mods after parsing command line args
1378geninitrd_setup_mods
1379
1380if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1381 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1382fi
1383
82b2dba2 1384if [ -z "$INITRDFS" ]; then
bbbc32d0
ER
1385 if [ -n "$FS" ]; then
1386 # FS= can came only via /etc/sysconfig/geninitrd likely?
1387 die "FS configuration option is obsoleted. Use INITRDFS instead"
f5db170b 1388 fi
f5db170b 1389
bbbc32d0
ER
1390 # default value
1391 if [ "$kernel_version" -ge "002005" ]; then
1392 INITRDFS="initramfs"
1393 else
1394 INITRDFS="rom"
1395 fi
82b2dba2 1396fi
966c32cc 1397
82b2dba2 1398case "$INITRDFS" in
4877276e
ER
1399 ext2)
1400 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1401 ;;
1402 rom|romfs)
1403 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1404 ;;
1405 cram|cramfs)
1406 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1407 ;;
1408 initramfs)
1409 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1410 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1411 ;;
1412 *)
1413 die "Filesystem $INITRDFS on initrd is not supported"
1414 ;;
82b2dba2 1415esac
f5db170b 1416
9323ada3 1417if [ -L "$target" ]; then
1418 target=$(readlink -f "$target")
1419fi
1420
82b2dba2
ER
1421if [ -n "$img_vers" ]; then
1422 target="$target-$kernel"
1423fi
8bd582f1 1424
82b2dba2
ER
1425if [ -z "$force" -a -f "$target" ]; then
1426 die "$target already exists."
1427fi
c6c6ce01 1428
82b2dba2
ER
1429if [ ! -d "/lib/modules/$kernel" ]; then
1430 die "/lib/modules/$kernel is not a directory."
1431fi
2ffb1734 1432
bbbc32d0
ER
1433if [ "$kernel_version" -ge "002005" ]; then
1434 modext=".ko"
1435fi
1436
82b2dba2
ER
1437cache_modprobe_conf
1438
1439for n in $PREMODS; do
046c68c9 1440 find_module "$n"
82b2dba2
ER
1441done
1442
ed30e3a8 1443if [ "$FBMODULE" ]; then
046c68c9 1444 find_module "$FBMODULE"
ed30e3a8
ER
1445fi
1446
cefcd7bb
AM
1447# autodetect USB keyboards
1448find_modules_usbkbd
1449
82b2dba2 1450# allow forcing loading SCSI and/or IDE modules
35043b20 1451# XXX: where ADDSCSI cames from? drop?
82b2dba2
ER
1452if is_yes "$ADDSCSI"; then
1453 find_modules_scsi
1454fi
1455
3f53322c 1456# autodetect SATA modules
1457find_modules_sata
e2d6ca6c 1458
35043b20 1459# XXX: where ADDIDE cames from? drop?
82b2dba2
ER
1460if is_yes "$ADDIDE"; then
1461 find_modules_ide
1462fi
1463
4c16dac4
ER
1464if is_yes "$USE_SUSPEND"; then
1465 find_modules_suspend
1466fi
1467
82b2dba2 1468find_root "$fstab" || exit
02ba8ab7 1469verbose "Using $rootdev as device for rootfs"
82b2dba2 1470
d8056591 1471find_modules_for_devpath "$rootdev"
ac085800 1472
ecd7bf46
ER
1473# if USE_MULTIPATH is path to device, scan that too
1474# this is to bootstrap multipath setup into initrd.
1475if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1476 find_modules_multipath $USE_MULTIPATH
1477fi
1478
046c68c9 1479find_module "-$rootFs"
ac085800 1480
82b2dba2 1481for n in $BASICMODULES; do
046c68c9 1482 find_module "$n"
82b2dba2 1483done
4e9eb79c 1484
82b2dba2 1485if is_yes "$USE_TUXONICE"; then
046c68c9 1486 find_module "-lzf"
82b2dba2 1487fi
33d24e12 1488
2d769917 1489find_modules_uvesafb
bf6d9c64 1490find_modules_fbsplash
2968c9dd 1491
82b2dba2 1492if [ -n "$ifneeded" -a -z "$MODULES" ]; then
02ba8ab7 1493 verbose "No modules are needed -- not building initrd image."
82b2dba2
ER
1494 exit 0
1495fi
c6c6ce01 1496
02ba8ab7 1497verbose "Building initrd..."
d8056591 1498DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
9b557a09 1499RCFILE="$DESTDIR/linuxrc"
82b2dba2
ER
1500> "$RCFILE"
1501chmod a+rx "$RCFILE"
9b557a09 1502ln -s linuxrc $DESTDIR/init
e8d178ff 1503
82b2dba2 1504# create dirs that we really need
d63131e0 1505inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
e8d178ff 1506
82b2dba2 1507modules_install "$MODULES"
b64f015b 1508
82b2dba2
ER
1509# mknod'ing the devices instead of copying them works both with and
1510# without devfs...
6b45dd6c
AM
1511mknod -m 600 "$DESTDIR/dev/console" c 5 1
1512mknod -m 666 "$DESTDIR/dev/null" c 1 3
1513mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1514mknod -m 666 "$DESTDIR/dev/random" c 1 8
1515mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
2b945b6b 1516mknod -m 644 "$DESTDIR/dev/kmsg" c 1 11
be2f3ecc 1517
6ec4aea6
JR
1518inst_exec $busybox /bin/busybox
1519ln -s busybox $DESTDIR/bin/sh
1520# for older busyboxes who had /bin/initrd-busybox as EXEPATH
1521ln -s busybox $DESTDIR/bin/initrd-busybox
2ffb1734 1522
82b2dba2
ER
1523add_linuxrc <<EOF
1524#!/bin/sh
b7114dde 1525# initrd generated by geninitrd/$VERSION
8938f33d 1526# on $(LC_ALL=C date)
c6c6ce01 1527
82b2dba2 1528EOF
ff9aded5 1529load_font
82b2dba2 1530mount_proc
2b945b6b
ER
1531
1532kmsg "geninitrd/$VERSION starting"
1533
0fb9dda3
ER
1534add_linuxrc <<-EOF
1535 # builtin defaults from geninitrd
1536 ROOT=$rootdev
1537 ROOTFS=$rootFs
1538EOF
82b2dba2 1539add_linuxrc <<-'EOF'
48d98595 1540 read CMDLINE < /proc/cmdline
c6c6ce01 1541
82b2dba2 1542 for arg in $CMDLINE; do
04bffd7a 1543 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
82b2dba2
ER
1544 DEBUGINITRD=yes
1545 fi
04bffd7a
ER
1546 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1547 DEBUGINITRD=${arg##debug*rd=}
82b2dba2 1548 fi
fc787d45 1549 if [ "${arg##root=}" != "${arg}" ]; then
1550 ROOT=${arg##root=}
1551 fi
144396dd
AM
1552 if [ "${arg##rootflags=}" != "${arg}" ]; then
1553 ROOTFLAGS=${arg##rootflags=}
db795d06 1554 fi
41d3645c
AM
1555 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1556 ROOTFSFLAGS=${arg##rootfsflags=}
1557 fi
0fb9dda3
ER
1558 if [ "${arg##init=}" != "${arg}" ]; then
1559 INIT=${arg##init=}
1560 fi
82b2dba2 1561 done
c6c6ce01 1562
144396dd
AM
1563 # handling of invalid, rootfsflags, option
1564 if [ -n "$ROOTFSFLAGS" ]; then
1565 if [ -n "$ROOTFLAGS" ]; then
1566 ROOTFLAGS="$ROOTFLAGS,$ROOTFSFLAGS"
1567 else
1568 ROOTFLAGS="$ROOTFSFLAGS"
1569 fi
1570 fi
1571
82b2dba2 1572 if [ "$DEBUGINITRD" = "sh" ]; then
8938f33d 1573 # export some vars to subshell for debug to work
144396dd 1574 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFLAGS DEBUGINITRD INIT
4569a02c
ER
1575 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1576 export rootnr attrs majmin major minor device
1577
1578 # make debugshell() invoke subshell if $DEBUGINITRD=sh
82b2dba2 1579 debugshell() {
e2405b29
AM
1580EOF
1581if is_yes "$RUN_SULOGIN_ON_ERR"; then
1582add_linuxrc <<-'EOF'
0273c2c4 1583 echo "debug shell disabled by RUN_SULOGIN_ON_ERR=yes from /etc/sysconfig/system during initrd generation time"
e2405b29
AM
1584EOF
1585else
1586add_linuxrc <<-'EOF'
1587 sh
1588EOF
1589fi
1590add_linuxrc <<-'EOF'
82b2dba2
ER
1591 }
1592 else
1593 debugshell() {
1594 :
1595 }
1596 fi
e934d044 1597
82b2dba2
ER
1598 if [ "$DEBUGINITRD" ]; then
1599 set -x
cff3058d 1600 fi
82b2dba2 1601EOF
2df2e995 1602
fe280785 1603modules_add_linuxrc $MODULES
82b2dba2
ER
1604
1605# TODO: rewrite for busybox
1606#if [ -n "$loopDev" ]; then
1607# if [ ! -d /initrd ]; then
1608# mkdir /initrd
1609# fi
1610#
9b557a09
ER
1611# cp -a "$loopDev" "$DESTDIR/dev"
1612# cp -a "$rootdev" "$DESTDIR/dev"
82b2dba2
ER
1613# echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1614# echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1615# echo "echo Setting up loopback device $rootdev" >> $RCFILE
1616# echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1617#fi
2b1a3707 1618
1606e343
AM
1619if is_yes "$USE_UDEV"; then
1620 initrd_gen_udev
382ce856
AM
1621else
1622 initrd_gen_mdev
1606e343
AM
1623fi
1624
3dd50160 1625initrd_gen_uvesafb
1b481849
ER
1626initrd_gen_luks
1627initrd_gen_dmraid
1628initrd_gen_multipath
1629initrd_gen_blkid
289fbc9b 1630
69b1e935 1631if is_yes "$have_nfs"; then
2df2e995 1632 initrd_gen_nfs
1b481849
ER
1633else
1634 initrd_gen_md
1635 initrd_gen_lvm
2d769917 1636 initrd_gen_bcache
d222b474 1637 initrd_gen_blkid
1b481849 1638 initrd_gen_luks
4828c787 1639 initrd_gen_setrootdev
7c38b114
AF
1640fi
1641
5101a385 1642# additional devs always needed
9b557a09 1643[ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
5101a385 1644
1b481849 1645initrd_gen_stop_udevd
382ce856 1646initrd_gen_stop_mdev
6fadace4 1647initrd_gen_stop_uvesafb
82de999f 1648
4a362aea
ER
1649# resume after killing local processes
1650initrd_gen_tuxonice
1651initrd_gen_suspend
1652
52a92a2a
ER
1653# clean up env
1654add_linuxrc <<-'EOF'
4569a02c 1655if [ ! "$DEBUGINITRD" ]; then
52a92a2a
ER
1656 ifs=$IFS
1657 IFS="
1658 "
1659 for i in $(export -p); do
1660 i=${i#declare -x } # ksh/bash
1661 i=${i#export } # busybox
1662
1663 case "$i" in
1664 *=*)
1665 : ;;
1666 *)
1667 continue ;;
1668 esac
1669
1670 i=${i%%=*}
1671
1672 [ -z "$i" ] && continue
1673
1674 case "$i" in
62028605 1675 ROOT|PATH|HOME|TERM)
52a92a2a
ER
1676 :
1677 ;;
1678 *)
62028605 1679 unset $i
52a92a2a
ER
1680 ;;
1681 esac
1682 done
1683 IFS=$ifs
4569a02c 1684fi
52a92a2a
ER
1685EOF
1686
f8f9e56d 1687if [ "$INITRDFS" = "initramfs" ]; then
4671d086 1688 initrd_gen_initramfs_switchroot
b64f015b 1689else
b64f015b 1690 umount_all
f8f9e56d
AM
1691fi
1692
1b481849
ER
1693initrd_gen_fbsplash
1694initrd_gen_fbcondecor
6c69a2d4 1695
b7114dde 1696debug "Current /linuxrc:\n$(sed -e 's,^,| ,' $DESTDIR/linuxrc)"
2990ac33 1697
d8056591 1698IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
51dc1fe6 1699
5c7359e3 1700IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
02ba8ab7 1701verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
5c7359e3 1702
02ba8ab7 1703verbose "Creating $INITRDFS image $IMAGE"
2ad94d8a 1704case "$INITRDFS" in
4877276e 1705 ext2)
4877276e 1706 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
c091a192
ER
1707 # NOTE: ext2 label is max 16 chars
1708 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
4877276e
ER
1709 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1710
1711 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1712 debug "Mounting ext2 image $IMAGE to $tmpmnt"
5c7359e3 1713 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
4877276e
ER
1714 # We don't need this directory, so let's save space
1715 rm -rf "$tmpmnt"/lost+found
1716
1717 debug "Copy recursively $DESTDIR -> $tmpmnt"
1718 cp -a $DESTDIR/* $tmpmnt
1719 umount "$IMAGE"
1720 rmdir "$tmpmnt"
1721
1722 ;;
1723 rom|romfs)
c091a192 1724 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
4877276e
ER
1725 ;;
1726 cram|cramfs)
1727 mkcramfs "$DESTDIR" "$IMAGE"
1728 ;;
1729 initramfs)
1730 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1731 ;;
1732 *)
93a38d1a 1733 die "Filesystem $INITRDFS not supported by $PROGRAM"
c31050f3 1734esac
bb529f94 1735
755e5cdc 1736CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
25cb53df
ER
1737if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1738 CONFIG_BLK_DEV_RAM_SIZE=4096
3fbd853a 1739 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
25cb53df 1740fi
e3bc44e2 1741
e3bc44e2
ER
1742if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1743 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1744fi
1745
c552503c 1746if ! is_no "$COMPRESS"; then
c552503c 1747 compressor=$(find_compressor "$COMPRESS")
02ba8ab7 1748 verbose "Compressing $target with $compressor"
c552503c
ER
1749
1750 # TODO: the image name (specified from kernel.spec) already contains
1751 # extension, which is .gz most of the time.
97f51b6e
ER
1752 compress_image "$compressor" "$IMAGE" "$target" || {
1753 if [ $compressor != gzip ]; then
1754 warn "Could not compress with $compressor, retrying with gzip"
1755 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1756 else
1757 die "Could not compress image with $compressor"
1758 fi
1759 }
bb529f94 1760else
7d2fc5eb 1761 cp -a "$IMAGE" "$target"
bb529f94 1762fi
5b71959c 1763
7992356a 1764# XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1b481849 1765initrd_gen_bootsplash "$target"
5b71959c 1766
d8056591 1767rm -rf "$DESTDIR" "$IMAGE"
ac085800
ER
1768
1769# vim:ts=4:sw=4:noet:fdm=marker
This page took 1.011243 seconds and 4 git commands to generate.