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