]> git.pld-linux.org Git - projects/geninitrd.git/blame - geninitrd
Support discard/allow-discard cryptsetup LUKS option. Replace deprecated luksOpen...
[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
JR
117 local x p b n
118 local paths="$initrd_dir /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
10e8125f
AF
537 local obj lib libs
538 for obj in "$@"; do
66aec48b
ER
539 case "$obj" in
540 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
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
546 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
547 inst_d /$_lib
548 inst_exec $lib /$_lib
549 fi
550 done
209061e3 551 done
c7ade647
ER
552
553 # hack for uclibc linked binaries requiring this fixed path
554 # XXX: shouldn't rpath be used here instead so th
555 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
556 local lib=$DESTDIR/$_lib/libc.so.0
557 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
558 local libdir=$(cd $(dirname "$lib"); pwd)
559 if [ ! -e $DESTDIR$libdir ]; then
560 libdir=$(dirname "$libdir")
561 inst_d $libdir
02ba8ab7 562 verbose "+ ln -s /$_lib $DESTDIR$libdir"
c7ade647
ER
563 ln -s /$_lib $DESTDIR$libdir
564 fi
565 fi
209061e3
ER
566}
567
82474db9
ER
568# output modules.conf / modprobe.conf
569modprobe_conf() {
570 echo "$modprobe_conf_cache"
571}
572
38ac83a5
ER
573# return options for MODULE
574# @param $1 module name
575modprobe_options() {
576 local module=$1
915ff812 577 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
38ac83a5
ER
578 echo ${options# }
579}
580
82474db9
ER
581#
582# defaults to modprobe -c if not told otherwise, this means include statements
583# work from there.
584cache_modprobe_conf() {
707f5e60 585 if [ "$kernel_version" -lt "002005" ]; then
82474db9
ER
586 modulefile=/etc/modules.conf
587 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
588 modulefile=/etc/conf.modules
589 fi
590 fi
591
592 if [ -n "$modulefile" ]; then
d8056591 593 debug "Using $modulefile for modules config"
99e7251e
ER
594 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
595
82474db9 596 else
d8056591 597 debug "Using modprobe -c to get modules config"
99e7251e 598 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
82474db9
ER
599 fi
600}
601
bc0d6f2d 602# find modules for $devpath
d8056591 603find_modules_for_devpath() {
bc0d6f2d
ER
604 local devpath="$1"
605 if [ -z "$devpath" ]; then
d8056591 606 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
f6536797 607 fi
ac085800 608
c2eb7d4f
ER
609 if [[ "$devpath" = /dev/dm-* ]]; then
610 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
d2cb46cf 611 devpath=$(dm_node "$devpath")
c2eb7d4f
ER
612 fi
613
336018a5 614 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
c2eb7d4f
ER
615 # sanitize things like:
616 # /dev/block/104:2 -> /dev/cciss/c0d0p2
617 devpath=$(readlink -f "$devpath")
618 fi
619
02ba8ab7 620 verbose "Finding modules for device path $devpath"
bc0d6f2d 621
3ef3d717
ER
622 if is_luks "$devpath"; then
623 find_modules_luks "$devpath"
624 return
625 fi
626
74d45ce1
ER
627 if is_nfs "$devpath"; then
628 find_modules_nfs "$devpath"
d9179777
ER
629 return
630 fi
631
e16414d9 632 if is_md "$devpath"; then
df738638 633 find_modules_md "$devpath"
d9179777
ER
634 return
635 fi
636
c3b54060 637 if is_multipath "$devpath"; then
07137fe3 638 if find_modules_multipath "$devpath"; then
9baf4f3f 639 return
9baf4f3f 640 fi
ecd7bf46 641
9baf4f3f
ER
642 # fallback
643 fi
644
36523626 645 if is_dmraid "$devpath"; then
c083ae23
ER
646 if find_modules_dmraid "$devpath"; then
647 return
648 fi
649 # fallback
650 fi
651
35043b20
ER
652 if is_scsi "$devpath"; then
653 find_modules_scsi "$devpath"
d9179777
ER
654 return
655 fi
656
30ca4815 657 if is_ide "$devpath"; then
bc0d6f2d 658 find_modules_ide "$devpath"
d9179777
ER
659 return
660 fi
661
0bdde1a1
ER
662 if [[ "$devpath" == /dev/bcache* ]]; then
663 find_modules_bcache "$devpath"
664 return
665 fi
666
07b09cf9 667 if [[ "$devpath" == /dev/rd/* ]]; then
046c68c9 668 find_module "DAC960"
c3313cd6 669 rootdev_add=/dev/rd/
d9179777
ER
670 return
671 fi
672
07b09cf9 673 if [[ "$devpath" == /dev/ida/* ]]; then
046c68c9 674 find_module "cpqarray"
c3313cd6 675 rootdev_add=/dev/ida/
d9179777
ER
676 return
677 fi
678
08651ad1 679 if [[ "$devpath" == /dev/cciss/* ]]; then
c3313cd6 680 rootdev_add=/dev/cciss/
df11fbe8
ER
681
682 # load hpsa for future kernels, cciss for backwards compat
683 if [ "$kernel_version_long" -ge "003000000" ]; then
684 find_module "hpsa" "-cciss"
649df3de 685 find_modules_scsi "$devpath"
df11fbe8
ER
686 else
687 find_module "cciss"
688 fi
689
d9179777
ER
690 return
691 fi
692
07b09cf9 693 if [[ "$devpath" == /dev/ataraid/* ]]; then
ac085800 694 find_modules_ide
046c68c9 695 find_module "ataraid"
99e7251e 696 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
9ae446b9 697 if [ -n "$ataraidmodules" ]; then
7c38b114 698 # FIXME: think about modules compiled in kernel
82474db9 699 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
7c38b114
AF
700 fi
701 for n in $ataraidmodules; do
046c68c9 702 find_module "$n"
7c38b114 703 done
c3313cd6 704 rootdev_add=/dev/ataraid/
d9179777
ER
705 return
706 fi
707
7c38b114 708 # check to see if we need to set up a loopback filesystem
07b09cf9 709 if [[ "$devpath" == /dev/loop* ]]; then
00eaa938 710 die "Sorry, root on loop device isn't supported."
7c38b114
AF
711 # TODO: rewrite for bsp and make nfs ready
712 if [ ! -x /sbin/losetup ]; then
00eaa938 713 die "losetup is missing"
7c38b114 714 fi
bc0d6f2d 715 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
82474db9 716 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
42820142 717 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
718 fi
719
720 line="`awk '/'$key'/ { print $0; }' $fstab`"
721 loopDev="$(echo $line | awk '{print $3}')"
722 loopFs="$(echo $line | awk '{print $4}')"
723 loopFile="$(echo $line | awk '{print $5}')"
724
725 BASICMODULES="$BASICMODULES -loop"
046c68c9 726 find_module "-$loopFs"
7c38b114 727 BASICMODULES="$BASICMODULES -${loopFs}"
d9179777
ER
728 return
729 fi
730
67aa84bd
ER
731 if is_lvm "$devpath"; then
732 find_modules_lvm "$devpath"
d9179777 733 return
7c38b114
AF
734 fi
735}
736
b64f015b 737firmware_install_module() {
c3667d07 738 local module="$1"
c6c6ce01 739 local firmware_files="$2"
9ed6e1db 740
02ba8ab7 741 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
9ed6e1db 742 # firmware not yet installed
9b557a09 743 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
034fdd5d 744 inst_d /lib/firmware
9b557a09 745cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
9ed6e1db 746#!/bin/sh -e
45294dc1
ER
747# handle only firmware add requests
748if [ "$SUBSYSTEM" != "firmware" ]; then
749 exit 0
750fi
751if [ "$ACTION" != "add" ]; then
752 exit 0
753fi
8639f99a
AM
754echo 1 > /sys$DEVPATH/loading
755cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
756echo 0 > /sys$DEVPATH/loading
757exit 0
9ed6e1db 758EOF
9b557a09 759 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
63cb815e
ER
760
761 # setup firmware loader agent
762 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
9ed6e1db
AM
763 fi
764
765 for firmware in $firmware_files; do
80b23733 766 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
486d26a5 767 FIRMWAREDIR=${firmware%/*}
4a9920e7 768 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
80b23733
ER
769 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
770 elif [ -f "/lib/firmware/$firmware" ]; then
c661b23c 771 FIRMWAREDIR=${firmware%/*}
772 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
80b23733 773 inst /lib/firmware/$firmware /lib/firmware/$firmware
c661b23c 774 else
6652b089 775 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
4a60c01f 776 fi
9ed6e1db
AM
777 done
778
b64f015b 779 mount_sys
9ed6e1db
AM
780}
781
2a5bcca9 782modules_install() {
c3667d07
ER
783 local modules="$1"
784 local mod
2a5bcca9
AM
785
786 for mod in $modules; do
fe280785 787 MODULEDIR=${mod%/*}
4a9920e7 788 inst_d "/lib/modules/$kernel/$MODULEDIR"
9b557a09 789 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
5d62840e
AM
790 case $mod in
791 *.gz)
5bcfb27f 792 gunzip "$DESTDIR/lib/modules/$kernel/$mod"
5d62840e
AM
793 mod=${mod%.gz}
794 ;;
795 *.xz)
5bcfb27f 796 xz -d "$DESTDIR/lib/modules/$kernel/$mod"
5d62840e
AM
797 mod=${mod%.xz}
798 ;;
799 *.bz2)
5bcfb27f 800 bzip2 -d "$DESTDIR/lib/modules/$kernel/$mod"
5d62840e
AM
801 mod=${mod%.bz2}
802 ;;
803 esac
897d14b7 804 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
5d62840e 805 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod}"
ccd1f65f 806 fi
2a5bcca9
AM
807 done
808}
809
810modules_add_linuxrc() {
fe280785 811 local mod modpath
ac085800 812
fe280785
ER
813 for mod in "$@"; do
814 # module path without optional compression
815 modpath=${mod%.gz}
5d62840e
AM
816 modpath=${modpath%.xz}
817 modpath=${modpath%.bz2}
fe280785
ER
818
819 # name of the module
8011a76c 820 local module=${modpath##*/}; module=${module%$modext}
38ac83a5 821 local options=$(modprobe_options "$module")
8011a76c
ER
822 local genericname=$(echo $module | tr - _)
823 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
824 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
2a5bcca9 825
3e1d0df9
AM
826 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
827 options="scan=sync $options"
828 fi
829
02ba8ab7 830 if [ x"$verbose" = x"-v" ]; then
8a47b72c
ER
831 s=""
832 if [ "$options" ]; then
833 s="$s with options [$options]"
834 fi
8011a76c
ER
835 if [ "$usleep" ]; then
836 s="$s and $usleep usleep"
8a47b72c 837 fi
02ba8ab7 838 verbose "Loading module [$module]$s"
ac085800
ER
839 fi
840
8011a76c
ER
841 if [ -n "$firmware" ]; then
842 firmware_install_module "$module" "$firmware"
4a60c01f 843 else
06e481d7
ER
844 for file in $(find_firmware "$module"); do
845 firmware_install_module "$module" "$file"
846 done
9ed6e1db 847 fi
4a60c01f 848
18ece493 849 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
8011a76c
ER
850 if [ -n "$usleep" ]; then
851 echo "usleep $usleep" | add_linuxrc
8e598759 852 fi
e00dcfcb 853 if [ "$module" = "scsi_wait_scan" ]; then
d29583e0
ER
854 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
855 echo "rmmod scsi_wait_scan" | add_linuxrc
856 fi
e00dcfcb
AM
857 fi
858
2a5bcca9
AM
859 done
860}
861
82b2dba2
ER
862# Generates /dev nodes based on /proc/partitions information.
863# Needs /proc mounted.
864# Can be called multiple times.
865initrd_gen_devices() {
866 if is_yes "$proc_partitions"; then
867 return
868 fi
869 proc_partitions=yes
335cd101 870
82b2dba2
ER
871 mount_dev
872 add_linuxrc <<-'EOF'
873 : 'Making device nodes'
874 cat /proc/partitions | (
8d4aba01 875 # ignore first two lines: header, empty line
82b2dba2 876 read b; read b
2cc3ae8b 877
82b2dba2
ER
878 while read major minor blocks dev rest; do
879 node=/dev/$dev
880 mkdir -p ${node%/*}
6b45dd6c 881 [ -e $node ] || mknod -m 660 $node b $major $minor
82b2dba2
ER
882 done
883 )
884 EOF
885}
bb529f94 886
82b2dba2 887
4828c787 888initrd_gen_setrootdev() {
02ba8ab7 889 verbose "Adding rootfs finding based on kernel cmdline root= option support."
71b2d771 890 busybox_applet ls
b7114dde 891 debug "Current /proc/partitions:\n$(sed -e 's,^,| ,' /proc/partitions)"
82b2dba2 892 add_linuxrc <<-'EOF'
dcdf6b49
ER
893 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
894 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
94da85db
ER
895 # fallback to ls, try two different formats
896 # http://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2014-May/023915.html
897 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
898 # busybox up to 1.22
5efa9a2e 899 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
71b2d771 900 fi
94da85db
ER
901 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
902 # busybox 1.22 and upwards
903 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $5 + $6; }}')"
904 fi
905 if [ "${rootnr:-0}" -gt 0 ]; then
82b2dba2
ER
906 echo "$rootnr" > /proc/sys/kernel/real-root-dev
907 fi
908 fi
b64f015b 909 EOF
1606e343
AM
910}
911
4671d086
ER
912initrd_gen_initramfs_switchroot() {
913 inst_d /newroot
914 if [ "$rootdev" = "/dev/nfs" ]; then
915 echo "rootfs on NFS root=/dev/nfs"
916 else
917 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
918 fi
5845b321
ER
919
920 # parse 'root=xxx' kernel commandline
4671d086 921 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
ec21900e
ER
922
923 # from lilo-23.2/readme/README:
924 # root=<device> changes the root device. This overrides settings that may
925 # have been made in the boot image and on the LILO command line. <device> is
926 # either the hexadecimal device number or the full path name of the device,
927 # e.g. /dev/hda3 [*]
928 #
929 # * The device names are hard-coded in the kernel. Therefore, only the
930 # "standard" names are supported and some less common devices may not be
931 # recognized. In those cases, only numbers can be used.
5436b31f 932 busybox_applet cat
4671d086 933 add_linuxrc <<-'EOF'
7f187a08 934 device=
3564e6b6 935 eval "$(busybox awk -v root="$ROOT" '
f9194b15
ER
936 # http://9fans.net/archive/2006/09/261
937 function h2d(str, hstr, res, num, n, digit, i) {
938 hstr = "0123456789abdcef";
939 res = 0;
940 n = split(tolower(str), digit, "");
941
942 for (i = 1; i <= n; i++) {
943 num = index(hstr, digit[i]) - 1;
944 res = res + (num * 16 ^ (n - i));
945 }
946
947 return res;
948 }
4671d086 949 BEGIN {
f9194b15
ER
950
951 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
952 num_pattern = "[0-9a-fA-F]" num_pattern_short;
4671d086 953 dev_pattern = "[hms][a-z][a-z]([0-9])+";
7f187a08 954 partition = "";
4671d086
ER
955 min = -1; maj = -1;
956
3564e6b6
ER
957 # see if we have /dev/hdX or hdX, we can just take partition name
958 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
959 partition = root
960 sub("^/dev/", "", partition);
961
962 } else {
963 # unify values first
964 if (root ~ "^" num_pattern_short "$") {
965 # change "303" => "0x0303"
966 root = "0x0" root
967 } else if (root ~ "^" num_pattern "$") {
968 # change "0303" => "0x0303"
969 root = "0x" root
970 }
971
f9194b15
ER
972 maj = h2d(substr(root, 3, 2));
973 min = h2d(substr(root, 5, 2));
4671d086 974 }
4671d086
ER
975 }
976
7f187a08 977 partition && $4 == partition { maj = $1; min = $2; }
afa32d0e 978 $1 == maj && $2 == min { partition = $4; }
4671d086
ER
979
980 END {
fa3a5452 981 if (maj >= 0 && min >= 0) {
7f187a08
ER
982 printf("maj=%s; min=%s;\n", maj, min);
983 }
984 if (partition) {
985 printf("device=/dev/%s;\n", partition);
fa3a5452 986 }
4671d086
ER
987 }
988 ' /proc/partitions)"
4671d086 989
7f187a08 990 if [ -z "$device" ]; then
5436b31f
AM
991 if [ "$DEBUGINITRD" ]; then
992 cat /proc/partitions
993 fi
0fb9dda3 994 device=$ROOT
4671d086
ER
995 fi
996
481bdb77 997 if [ "$device" -a ! -b $device -a "$maj$min" ]; then
6b45dd6c 998 mknod -m 660 $device b $maj $min
7f187a08
ER
999 fi
1000
86aa389f
ER
1001 # XXX hack, if no device, try to parse it from /proc/partitions using /proc/sys/kernel/real-root-dev
1002 if [ ! -e "$device" ]; then
1003 rrd=$(cat /proc/sys/kernel/real-root-dev)
1004 major=$(($rrd / 256))
1005 minor=$(($rrd % 256))
1006
1007 while read pmajor pminor blocks dev rest; do
1008 # skip header and empty line
1009 [ -z "$pmajor" -o "$pmajor" = "major" ] && continue
1010
1011 if [ $pmajor = $major -a $pminor = $minor ]; then
1012 device=/dev/$dev
1013 echo "DEVICE set to $device based on real-root-dev"
1014 fi
1015 done < /proc/partitions
1016 fi
1017
144396dd 1018 [ -n "$ROOTFLAGS" ] && ROOTFLAGS="-o $ROOTFLAGS"
41d3645c 1019
144396dd 1020 mount -t $ROOTFS -r $device $ROOTFLAGS /newroot || echo "Mount of rootfs failed."
0fb9dda3 1021 init=$INIT
4671d086
ER
1022 if [ -z "$init" -o ! -x "/newroot$init" ]; then
1023 init=/sbin/init
1024 fi
1025 EOF
1026
b1ae7c80
AM
1027 busybox_applet dmesg
1028 busybox_applet tail
1029 add_linuxrc <<-'EOF'
1030 if [ "$DEBUGINITRD" ]; then
1031 echo "Last 20 lines of dmesg:"
1032 dmesg | tail -n 20
1033 fi
2b945b6b 1034
b1ae7c80
AM
1035 EOF
1036
2b945b6b
ER
1037 kmsg "geninitrd/$VERSION switching root"
1038
4671d086 1039 umount_all
0273c2c4 1040 busybox_applet switch_root usleep
4671d086 1041 add_linuxrc <<-'EOF'
278e5013 1042 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
0273c2c4
ER
1043
1044 # switch root to empty dir will make kernel panic, so sleep 10s before it
1045 # switch_root needs to be pid 1, so there's no other way to recover from here
1046 # if /dev is missing, switch root will likely fail, give debug shell before that
1047 if [ ! -d /newroot/dev ]; then
1048 echo "/dev is missing, switch_root will likely fail"
1049 echo "if you booted with debugrd=sh, then you be given shell and you might able to recover this situation"
1050 debugshell
1051 [ "$DEBUGINITRD" ] || usleep 10000000
1052 fi
1053
f8ea6a63 1054 exec switch_root /newroot $init ${1:+"$@"}
4671d086 1055
0273c2c4
ER
1056 # FIXME: this code is never executed, as "exec" does not return!
1057
4671d086
ER
1058 echo "Error! initramfs should not reach this place."
1059 echo "It probably means you've got old version of busybox, with broken"
1060 echo "initramfs support. Trying to boot anyway, but won't promise anything."
1061
f8ea6a63 1062 exec chroot /newroot $init ${1:+"$@"}
4671d086
ER
1063
1064 echo "Failed to chroot!"
b61aa273 1065 debugshell
4671d086
ER
1066 EOF
1067 # we need /init being real file, not symlink, otherwise the initramfs will
1068 # not be ran by pid 1 which is required for switch_root
1069 mv $DESTDIR/linuxrc $DESTDIR/init
1070 ln -s init $DESTDIR/linuxrc
1071}
1072
c552503c
ER
1073# find if $symbol exists in System.map $mapfile
1074sym_exists() {
1075 local mapfile="$1"
1076 local symbol="$2"
1077 if [ ! -f $mapfile ]; then
1078 # missing mapfile (not a pld kernel?)
1079 return 1
1080 fi
1081
1082 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
1083}
1084
1085# find best compressor (or forced one) for initrd
1086find_compressor() {
1087 local mode="$1"
1b89c904
AM
1088 # fastest initrd decompression speed is first
1089 local compressors='lzo gzip xz lzma bzip2'
c552503c
ER
1090
1091 # a specified one, take it
55aaf2fe
AM
1092 if ! is_yes "$mode"; then
1093 compressors="$mode"
c552503c
ER
1094 fi
1095
02ba8ab7 1096 verbose "finding compressor: $compressors (via $mode)"
c552503c
ER
1097 # check for compressor validity
1098 local c prog map=/boot/System.map-$kernel
1099 for c in $compressors; do
1100 case $c in
66d146a5 1101 xz)
29f7d622
AM
1102 sym=unxz
1103 prog=/usr/bin/xz
1104 ;;
1105 lzma)
c552503c 1106 sym=unlzma
66d146a5 1107 prog=/usr/bin/xz
c552503c
ER
1108 ;;
1109 bzip2)
1110 sym=bzip2
c42692d4 1111 prog=/usr/bin/bzip2
c552503c
ER
1112 ;;
1113 gzip)
1114 sym=gunzip
c42692d4 1115 prog=/bin/gzip
c552503c 1116 ;;
8a6f083b
AM
1117 lzo)
1118 sym=unlzo
1119 prog=/usr/bin/lzop
1120 ;;
5fcc3d04
AM
1121 none|no)
1122 # any existing sym will work
1123 sym=initrd_load
1124 prog=/bin/cat
1125 ;;
c552503c
ER
1126 *)
1127 die "Unknown compressor $c"
1128 ;;
1129 esac
c454c66e 1130 if sym_exists $map $sym && [ -x $prog ]; then
c552503c
ER
1131 echo $c
1132 return
1133 fi
1134 done
1135
02ba8ab7 1136 verbose "using gzip for compressor (fallback)"
c552503c
ER
1137 echo gzip
1138}
1139
97f51b6e
ER
1140# compresses kernel image image
1141# in function so we could retry with other compressor on failure
1142compress_image() {
1143 local compressor="$1" IMAGE="$2" target="$3" tmp
1144 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1145
1146 case "$compressor" in
1147 xz)
1148 # don't use -9 here since kernel won't understand it
1149 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1150 ;;
1151 lzma)
1152 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1153 ;;
1154 bzip2)
1155 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1156 ;;
1157 gzip)
1158 gzip -9 < "$IMAGE" > "$tmp" || return $?
1159 ;;
8a6f083b
AM
1160 lzo)
1161 lzop -9 < "$IMAGE" > "$tmp" || return $?
1162 ;;
5fcc3d04
AM
1163 none|no)
1164 cat < "$IMAGE" > "$tmp" || return $?
1165 ;;
97f51b6e
ER
1166 esac
1167
1168 mv -f "$tmp" "$target"
1169}
1170
82b2dba2
ER
1171if [ -r /etc/sysconfig/geninitrd ]; then
1172 . /etc/sysconfig/geninitrd
1173fi
2cc3ae8b 1174
c215292c
AG
1175if [ ! -f /proc/mounts ]; then
1176 warn "/proc filesystem not mounted, may cause wrong results or failure."
1177fi
1178
2d769917 1179geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd bcache
c124d0cf 1180
82b2dba2
ER
1181while [ $# -gt 0 ]; do
1182 case $1 in
1183 --fstab=*)
1184 fstab=${1#--fstab=}
1185 ;;
1186 --fstab)
1187 fstab=$2
1188 shift
1189 ;;
1190 --modules-conf=*)
1191 modulefile=${1#--modules-conf=}
1192 ;;
1193 --modules-conf)
1194 modulefile=$2
1195 shift
1196 ;;
82b2dba2
ER
1197 --with-bootsplash)
1198 BOOT_SPLASH=yes
1199 ;;
1200 --without-bootsplash)
1201 BOOT_SPLASH=no
1202 ;;
1203 --with-fbsplash)
1204 FB_SPLASH=yes
1205 ;;
1206 --without-fbsplash)
1207 FB_SPLASH=no
1208 ;;
6c69a2d4
ER
1209 --with-fbcondecor)
1210 FB_CON_DECOR=yes
1211 ;;
1212 --without-fbcondecor)
1213 FB_CON_DECOR=no
1214 ;;
82b2dba2
ER
1215 --with-suspend)
1216 USE_SUSPEND=yes
1217 ;;
1218 --without-suspend)
1219 USE_SUSPEND=no
1220 ;;
1221 --with-suspend2 | --with-tuxonice)
1222 USE_TUXONICE=yes
1223 ;;
1224 --without-suspend2 | --without-tuxonice)
1225 USE_TUXONICE=no
1226 ;;
80b1ed79 1227 --lvmversion=*)
7308edee 1228 LVMTOOLSVERSION=${1#--lvmversion=}
82b2dba2 1229 ;;
80b1ed79 1230 --lvmtoolsversion=*)
1231 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1232 ;;
82b2dba2
ER
1233 --lvmtoolsversion|--lvmversion)
1234 LVMTOOLSVERSION=$2
1235 shift
1236 ;;
1237 --without-udev)
1238 USE_UDEV=no
1239 ;;
1240 --with-udev)
1241 USE_UDEV=yes
1242 ;;
1243 --without-dmraid)
1244 USE_DMRAID=no
1245 ;;
1246 --without-multipath)
ecd7bf46
ER
1247 USE_MULTIPATH=no
1248 ;;
1249 --with-multipath=*)
1250 USE_MULTIPATH=${1#--with-multipath=}
82b2dba2 1251 ;;
af075488 1252 --without-blkid)
1253 USE_BLKID=no
289fbc9b 1254 ;;
3ef3d717
ER
1255 --without-luks)
1256 USE_LUKS=no
1257 ;;
82b2dba2
ER
1258 --with=*)
1259 BASICMODULES="$BASICMODULES ${1#--with=}"
1260 ;;
1261 --with)
1262 BASICMODULES="$BASICMODULES $2"
1263 shift
1264 ;;
1265 --version)
1266 echo "$PROGRAM: version $VERSION"
1267 exit 0
1268 ;;
1269 -v)
02ba8ab7
ER
1270 if [ x"$verbose" = x"-v" ]; then
1271 verbose="-v -v"
1272 else
1273 verbose="-v"
1274 fi
11ab0dea 1275 exec 3>&1
82b2dba2 1276 ;;
c552503c
ER
1277 --compress)
1278 COMPRESS=$2
1279 ;;
1280 --compress=*)
1281 COMPRESS="${1#--compress=}"
1282 ;;
82b2dba2
ER
1283 --nocompress)
1284 COMPRESS=no
1285 ;;
ccd1f65f 1286 --nostrip)
76a48507
ER
1287 STRIP=
1288 ;;
1289 --strip=*)
1290 STRIP="${1#--strip=}"
1291 ;;
1292 --strip)
1293 STRIP=$2
1294 shift
ccd1f65f 1295 ;;
82b2dba2
ER
1296 --ifneeded)
1297 ifneeded=1
1298 ;;
1299 -f)
1300 force=1
1301 ;;
1302 --preload=*)
1303 PREMODS="$PREMODS ${1#--preload=}"
1304 ;;
1305 --preload)
1306 PREMODS="$PREMODS $2"
1307 shift
1308 ;;
2965cab9 1309 --fs=* | --fs)
bbbc32d0 1310 die "--fs option is obsoleted. Use --initrdfs instead"
82b2dba2
ER
1311 ;;
1312 --initrdfs=*)
1313 INITRDFS=${1#--initrdfs=}
1314 ;;
1315 --initrdfs)
1316 INITRDFS=$2
1317 shift
1318 ;;
1319 --image-version)
1320 img_vers=yes
1321 ;;
1322 --ide-only-root)
1323 ide_only_root="yes"
1324 ;;
1325 *)
1326 if [ -z "$target" ]; then
1327 target="$1"
1328 elif [ -z "$kernel" ]; then
1329 kernel="$1"
1330 else
7f6e5359 1331 usage
36523626 1332 exit 1
82b2dba2
ER
1333 fi
1334 ;;
1335 esac
f5db170b 1336
82b2dba2
ER
1337 shift
1338done
1339
1340if [ -z "$target" -o -z "$kernel" ]; then
7f6e5359 1341 usage
36523626 1342 exit 1
82b2dba2
ER
1343fi
1344
93a38d1a
ER
1345# main()
1346if [ "$(id -u)" != 0 ]; then
1347 die "You need to be root to generate initrd"
1348fi
1349
a48c38c7 1350if [ -d /lib64 -a -d /usr/lib64 ]; then
c124d0cf
ER
1351 _lib=lib64
1352else
1353 _lib=lib
130aadc1
ER
1354fi
1355
c124d0cf 1356initrd_dir=/usr/$_lib/initrd
e4487862
AM
1357kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1358kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
82b2dba2 1359
b7114dde 1360verbose "# geninitrd $VERSION"
c124d0cf
ER
1361debug "Using _lib: $_lib"
1362debug "Using initrd_dir: $initrd_dir"
1363
6ec4aea6 1364busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
c124d0cf
ER
1365
1366# we setup mods after parsing command line args
1367geninitrd_setup_mods
1368
1369if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1370 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1371fi
1372
82b2dba2 1373if [ -z "$INITRDFS" ]; then
bbbc32d0
ER
1374 if [ -n "$FS" ]; then
1375 # FS= can came only via /etc/sysconfig/geninitrd likely?
1376 die "FS configuration option is obsoleted. Use INITRDFS instead"
f5db170b 1377 fi
f5db170b 1378
bbbc32d0
ER
1379 # default value
1380 if [ "$kernel_version" -ge "002005" ]; then
1381 INITRDFS="initramfs"
1382 else
1383 INITRDFS="rom"
1384 fi
82b2dba2 1385fi
966c32cc 1386
82b2dba2 1387case "$INITRDFS" in
4877276e
ER
1388 ext2)
1389 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1390 ;;
1391 rom|romfs)
1392 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1393 ;;
1394 cram|cramfs)
1395 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1396 ;;
1397 initramfs)
1398 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1399 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1400 ;;
1401 *)
1402 die "Filesystem $INITRDFS on initrd is not supported"
1403 ;;
82b2dba2 1404esac
f5db170b 1405
9323ada3 1406if [ -L "$target" ]; then
1407 target=$(readlink -f "$target")
1408fi
1409
82b2dba2
ER
1410if [ -n "$img_vers" ]; then
1411 target="$target-$kernel"
1412fi
8bd582f1 1413
82b2dba2
ER
1414if [ -z "$force" -a -f "$target" ]; then
1415 die "$target already exists."
1416fi
c6c6ce01 1417
82b2dba2
ER
1418if [ ! -d "/lib/modules/$kernel" ]; then
1419 die "/lib/modules/$kernel is not a directory."
1420fi
2ffb1734 1421
bbbc32d0
ER
1422if [ "$kernel_version" -ge "002005" ]; then
1423 modext=".ko"
1424fi
1425
82b2dba2
ER
1426cache_modprobe_conf
1427
1428for n in $PREMODS; do
046c68c9 1429 find_module "$n"
82b2dba2
ER
1430done
1431
ed30e3a8 1432if [ "$FBMODULE" ]; then
046c68c9 1433 find_module "$FBMODULE"
ed30e3a8
ER
1434fi
1435
cefcd7bb
AM
1436# autodetect USB keyboards
1437find_modules_usbkbd
1438
82b2dba2 1439# allow forcing loading SCSI and/or IDE modules
35043b20 1440# XXX: where ADDSCSI cames from? drop?
82b2dba2
ER
1441if is_yes "$ADDSCSI"; then
1442 find_modules_scsi
1443fi
1444
3f53322c 1445# autodetect SATA modules
1446find_modules_sata
e2d6ca6c 1447
35043b20 1448# XXX: where ADDIDE cames from? drop?
82b2dba2
ER
1449if is_yes "$ADDIDE"; then
1450 find_modules_ide
1451fi
1452
4c16dac4
ER
1453if is_yes "$USE_SUSPEND"; then
1454 find_modules_suspend
1455fi
1456
82b2dba2 1457find_root "$fstab" || exit
02ba8ab7 1458verbose "Using $rootdev as device for rootfs"
82b2dba2 1459
d8056591 1460find_modules_for_devpath "$rootdev"
ac085800 1461
ecd7bf46
ER
1462# if USE_MULTIPATH is path to device, scan that too
1463# this is to bootstrap multipath setup into initrd.
1464if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1465 find_modules_multipath $USE_MULTIPATH
1466fi
1467
046c68c9 1468find_module "-$rootFs"
ac085800 1469
82b2dba2 1470for n in $BASICMODULES; do
046c68c9 1471 find_module "$n"
82b2dba2 1472done
4e9eb79c 1473
82b2dba2 1474if is_yes "$USE_TUXONICE"; then
046c68c9 1475 find_module "-lzf"
82b2dba2 1476fi
33d24e12 1477
2d769917 1478find_modules_uvesafb
bf6d9c64 1479find_modules_fbsplash
2968c9dd 1480
82b2dba2 1481if [ -n "$ifneeded" -a -z "$MODULES" ]; then
02ba8ab7 1482 verbose "No modules are needed -- not building initrd image."
82b2dba2
ER
1483 exit 0
1484fi
c6c6ce01 1485
02ba8ab7 1486verbose "Building initrd..."
d8056591 1487DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
9b557a09 1488RCFILE="$DESTDIR/linuxrc"
82b2dba2
ER
1489> "$RCFILE"
1490chmod a+rx "$RCFILE"
9b557a09 1491ln -s linuxrc $DESTDIR/init
e8d178ff 1492
82b2dba2 1493# create dirs that we really need
d63131e0 1494inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
e8d178ff 1495
82b2dba2 1496modules_install "$MODULES"
b64f015b 1497
82b2dba2
ER
1498# mknod'ing the devices instead of copying them works both with and
1499# without devfs...
6b45dd6c
AM
1500mknod -m 600 "$DESTDIR/dev/console" c 5 1
1501mknod -m 666 "$DESTDIR/dev/null" c 1 3
1502mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1503mknod -m 666 "$DESTDIR/dev/random" c 1 8
1504mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
2b945b6b 1505mknod -m 644 "$DESTDIR/dev/kmsg" c 1 11
be2f3ecc 1506
6ec4aea6
JR
1507inst_exec $busybox /bin/busybox
1508ln -s busybox $DESTDIR/bin/sh
1509# for older busyboxes who had /bin/initrd-busybox as EXEPATH
1510ln -s busybox $DESTDIR/bin/initrd-busybox
2ffb1734 1511
82b2dba2
ER
1512add_linuxrc <<EOF
1513#!/bin/sh
b7114dde 1514# initrd generated by geninitrd/$VERSION
8938f33d 1515# on $(LC_ALL=C date)
c6c6ce01 1516
82b2dba2 1517EOF
ff9aded5 1518load_font
82b2dba2 1519mount_proc
2b945b6b
ER
1520
1521kmsg "geninitrd/$VERSION starting"
1522
0fb9dda3
ER
1523add_linuxrc <<-EOF
1524 # builtin defaults from geninitrd
1525 ROOT=$rootdev
1526 ROOTFS=$rootFs
1527EOF
82b2dba2 1528add_linuxrc <<-'EOF'
48d98595 1529 read CMDLINE < /proc/cmdline
c6c6ce01 1530
82b2dba2 1531 for arg in $CMDLINE; do
04bffd7a 1532 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
82b2dba2
ER
1533 DEBUGINITRD=yes
1534 fi
04bffd7a
ER
1535 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1536 DEBUGINITRD=${arg##debug*rd=}
82b2dba2 1537 fi
fc787d45 1538 if [ "${arg##root=}" != "${arg}" ]; then
1539 ROOT=${arg##root=}
1540 fi
144396dd
AM
1541 if [ "${arg##rootflags=}" != "${arg}" ]; then
1542 ROOTFLAGS=${arg##rootflags=}
db795d06 1543 fi
41d3645c
AM
1544 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1545 ROOTFSFLAGS=${arg##rootfsflags=}
1546 fi
0fb9dda3
ER
1547 if [ "${arg##init=}" != "${arg}" ]; then
1548 INIT=${arg##init=}
1549 fi
82b2dba2 1550 done
c6c6ce01 1551
144396dd
AM
1552 # handling of invalid, rootfsflags, option
1553 if [ -n "$ROOTFSFLAGS" ]; then
1554 if [ -n "$ROOTFLAGS" ]; then
1555 ROOTFLAGS="$ROOTFLAGS,$ROOTFSFLAGS"
1556 else
1557 ROOTFLAGS="$ROOTFSFLAGS"
1558 fi
1559 fi
1560
82b2dba2 1561 if [ "$DEBUGINITRD" = "sh" ]; then
8938f33d 1562 # export some vars to subshell for debug to work
144396dd 1563 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFLAGS DEBUGINITRD INIT
4569a02c
ER
1564 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1565 export rootnr attrs majmin major minor device
1566
1567 # make debugshell() invoke subshell if $DEBUGINITRD=sh
82b2dba2 1568 debugshell() {
e2405b29
AM
1569EOF
1570if is_yes "$RUN_SULOGIN_ON_ERR"; then
1571add_linuxrc <<-'EOF'
0273c2c4 1572 echo "debug shell disabled by RUN_SULOGIN_ON_ERR=yes from /etc/sysconfig/system during initrd generation time"
e2405b29
AM
1573EOF
1574else
1575add_linuxrc <<-'EOF'
1576 sh
1577EOF
1578fi
1579add_linuxrc <<-'EOF'
82b2dba2
ER
1580 }
1581 else
1582 debugshell() {
1583 :
1584 }
1585 fi
e934d044 1586
82b2dba2
ER
1587 if [ "$DEBUGINITRD" ]; then
1588 set -x
cff3058d 1589 fi
82b2dba2 1590EOF
2df2e995 1591
fe280785 1592modules_add_linuxrc $MODULES
82b2dba2
ER
1593
1594# TODO: rewrite for busybox
1595#if [ -n "$loopDev" ]; then
1596# if [ ! -d /initrd ]; then
1597# mkdir /initrd
1598# fi
1599#
9b557a09
ER
1600# cp -a "$loopDev" "$DESTDIR/dev"
1601# cp -a "$rootdev" "$DESTDIR/dev"
82b2dba2
ER
1602# echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1603# echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1604# echo "echo Setting up loopback device $rootdev" >> $RCFILE
1605# echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1606#fi
2b1a3707 1607
1606e343
AM
1608if is_yes "$USE_UDEV"; then
1609 initrd_gen_udev
382ce856
AM
1610else
1611 initrd_gen_mdev
1606e343
AM
1612fi
1613
3dd50160 1614initrd_gen_uvesafb
1b481849
ER
1615initrd_gen_luks
1616initrd_gen_dmraid
1617initrd_gen_multipath
1618initrd_gen_blkid
289fbc9b 1619
69b1e935 1620if is_yes "$have_nfs"; then
2df2e995 1621 initrd_gen_nfs
1b481849
ER
1622else
1623 initrd_gen_md
1624 initrd_gen_lvm
2d769917 1625 initrd_gen_bcache
d222b474 1626 initrd_gen_blkid
1b481849 1627 initrd_gen_luks
4828c787 1628 initrd_gen_setrootdev
7c38b114
AF
1629fi
1630
5101a385 1631# additional devs always needed
9b557a09 1632[ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
5101a385 1633
1b481849 1634initrd_gen_stop_udevd
382ce856 1635initrd_gen_stop_mdev
6fadace4 1636initrd_gen_stop_uvesafb
82de999f 1637
4a362aea
ER
1638# resume after killing local processes
1639initrd_gen_tuxonice
1640initrd_gen_suspend
1641
52a92a2a
ER
1642# clean up env
1643add_linuxrc <<-'EOF'
4569a02c 1644if [ ! "$DEBUGINITRD" ]; then
52a92a2a
ER
1645 ifs=$IFS
1646 IFS="
1647 "
1648 for i in $(export -p); do
1649 i=${i#declare -x } # ksh/bash
1650 i=${i#export } # busybox
1651
1652 case "$i" in
1653 *=*)
1654 : ;;
1655 *)
1656 continue ;;
1657 esac
1658
1659 i=${i%%=*}
1660
1661 [ -z "$i" ] && continue
1662
1663 case "$i" in
62028605 1664 ROOT|PATH|HOME|TERM)
52a92a2a
ER
1665 :
1666 ;;
1667 *)
62028605 1668 unset $i
52a92a2a
ER
1669 ;;
1670 esac
1671 done
1672 IFS=$ifs
4569a02c 1673fi
52a92a2a
ER
1674EOF
1675
f8f9e56d 1676if [ "$INITRDFS" = "initramfs" ]; then
4671d086 1677 initrd_gen_initramfs_switchroot
b64f015b 1678else
b64f015b 1679 umount_all
f8f9e56d
AM
1680fi
1681
1b481849
ER
1682initrd_gen_fbsplash
1683initrd_gen_fbcondecor
6c69a2d4 1684
b7114dde 1685debug "Current /linuxrc:\n$(sed -e 's,^,| ,' $DESTDIR/linuxrc)"
2990ac33 1686
d8056591 1687IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
51dc1fe6 1688
5c7359e3 1689IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
02ba8ab7 1690verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
5c7359e3 1691
02ba8ab7 1692verbose "Creating $INITRDFS image $IMAGE"
2ad94d8a 1693case "$INITRDFS" in
4877276e 1694 ext2)
4877276e 1695 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
c091a192
ER
1696 # NOTE: ext2 label is max 16 chars
1697 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
4877276e
ER
1698 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1699
1700 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1701 debug "Mounting ext2 image $IMAGE to $tmpmnt"
5c7359e3 1702 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
4877276e
ER
1703 # We don't need this directory, so let's save space
1704 rm -rf "$tmpmnt"/lost+found
1705
1706 debug "Copy recursively $DESTDIR -> $tmpmnt"
1707 cp -a $DESTDIR/* $tmpmnt
1708 umount "$IMAGE"
1709 rmdir "$tmpmnt"
1710
1711 ;;
1712 rom|romfs)
c091a192 1713 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
4877276e
ER
1714 ;;
1715 cram|cramfs)
1716 mkcramfs "$DESTDIR" "$IMAGE"
1717 ;;
1718 initramfs)
1719 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1720 ;;
1721 *)
93a38d1a 1722 die "Filesystem $INITRDFS not supported by $PROGRAM"
c31050f3 1723esac
bb529f94 1724
755e5cdc 1725CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
25cb53df
ER
1726if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1727 CONFIG_BLK_DEV_RAM_SIZE=4096
3fbd853a 1728 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
25cb53df 1729fi
e3bc44e2 1730
e3bc44e2
ER
1731if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1732 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1733fi
1734
c552503c 1735if ! is_no "$COMPRESS"; then
c552503c 1736 compressor=$(find_compressor "$COMPRESS")
02ba8ab7 1737 verbose "Compressing $target with $compressor"
c552503c
ER
1738
1739 # TODO: the image name (specified from kernel.spec) already contains
1740 # extension, which is .gz most of the time.
97f51b6e
ER
1741 compress_image "$compressor" "$IMAGE" "$target" || {
1742 if [ $compressor != gzip ]; then
1743 warn "Could not compress with $compressor, retrying with gzip"
1744 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1745 else
1746 die "Could not compress image with $compressor"
1747 fi
1748 }
bb529f94 1749else
7d2fc5eb 1750 cp -a "$IMAGE" "$target"
bb529f94 1751fi
5b71959c 1752
7992356a 1753# XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1b481849 1754initrd_gen_bootsplash "$target"
5b71959c 1755
d8056591 1756rm -rf "$DESTDIR" "$IMAGE"
ac085800
ER
1757
1758# vim:ts=4:sw=4:noet:fdm=marker
This page took 0.915856 seconds and 4 git commands to generate.