7 # based on mkinitrd from RedHat Linux
10 GENINITRD_RCSID='$Revision$ $Date:: $'
11 R=${GENINITRD_RCSID#* *}; VERSION=${R%% *}
14 . /etc/rc.d/init.d/functions
15 . /lib/geninitrd/functions
16 . /etc/sysconfig/system
18 # list of geninitrd modules which need setup routine after commandline args parsing
31 # device node for rootfs from fstab
41 # is /tmp mounted on tmpfs
44 # are /dev nodes already created from /proc/devices info?
48 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
49 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
50 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
51 echo " [--nostrip ] [--strip PATH/strip] [--strip=PATH/strip]"
52 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
53 echo " [--with-bootsplash] [--without-bootsplash]"
54 echo " [--with-fbsplash] [--without-fbsplash]"
55 echo " [--with-fbcondecor] [--without-fbcondecor]"
56 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
57 echo " [--with-suspend] [--without-suspend]"
58 echo " [--with-tuxonice] [--without-tuxonice]"
59 echo " [--without-dmraid]"
60 echo " [--with-multipath=DEVPATH] [--without-multipath]"
61 echo " [--without-blkid] [--without-luks]"
62 echo " <initrd-image> <kernel-version>"
66 local kdir kver dir=${target:-/boot}
67 for kdir in /lib/modules/*; do
68 [ -d $kdir ] || continue
70 echo " $0 -f --initrdfs=initramfs $dir/initrd-$kver.gz $kver $verbose"
83 [ -n "$verbose" ] && msg "$*" >&3
87 [ x"$verbose" = x"-v -v" ] && msg "$*" >&3
90 # aborts program abnormally
97 # find program from specified paths
100 local paths="$initrd_dir /bin /sbin /usr/bin /usr/sbin"
102 debug "find_tool: checking $x"
105 verbose "find_tool: found $x"
111 debug "find_tool: checking $p/$b"
112 if [ -x "$p/$b" ]; then
114 verbose "find_tool: found $p/$b"
120 debug "find_tool: did not find any of: $n"
124 # loads geninitrd modules
125 geninitrd_load_mods() {
128 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
129 die "$mod geninitrd module can't be loaded"
131 . /lib/geninitrd/mod-$mod.sh
133 GENINITRD_MODS="$GENINITRD_MODS $mod"
137 # setup geninitrd modules
138 geninitrd_setup_mods() {
141 for mod in $GENINITRD_MODS; do
142 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
143 debug "# $rcsid (mod-$mod)"
145 # some mods want init
146 if type setup_mod_$mod > /dev/null; then
152 # append text to /linuxrc
153 # takes STDIN as input
158 # generate code to mount /dev on tmpfs and create initial nodes
159 # can be called multiple times. /dev is cleaned up (umounted) automatically at
162 # we already generated tmpfs code; return
163 if is_yes "$dev_mounted"; then
169 busybox_applet mount mknod mkdir
172 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
173 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
174 mknod -m 600 /dev/console c 5 1
175 mknod -m 666 /dev/null c 1 3
176 mknod -m 666 /dev/zero c 1 5
177 mknod -m 666 /dev/random c 1 8
178 mknod -m 600 /dev/snapshot c 10 231
179 mknod -m 666 /dev/urandom c 1 9
180 mknod -m 666 /dev/ptmx c 5 2
181 mknod -m 644 /dev/kmsg c 1 11
188 # generate code to mount /proc on initrd
189 # can be called multiple times
191 if is_yes "$proc_mounted"; then
196 if [ "$INITRDFS" = "initramfs" ]; then
197 # /proc is mounted with initramfs 2.6.22.14 kernel
198 # XXX: remove when it is clear why proc was already mounted
199 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
201 echo "mount -t proc none /proc" | add_linuxrc
205 # generate code to mount /sys on initrd
206 # can be called multiple times
208 if is_yes "$sys_mounted"; then
213 echo "mount -t sysfs none /sys" | add_linuxrc
216 # generate code to mount /tmp on initrd
217 # can be called multiple times
219 if [ "$INITRDFS" = "initramfs" ]; then
220 # initramfs is read-write filesystem, no need for tmpfs
224 if is_yes "$tmp_mounted"; then
229 echo "mount -t tmpfs none /tmp" | add_linuxrc
232 # generate code to mount /run on initrd
233 # can be called multiple times
235 if is_yes "$run_mounted"; then
240 echo "mount -t tmpfs run /run" | add_linuxrc
243 # unmount all mountpoints mounted by geninitrd
244 # try to move pseudo filesystems to newroot if possible
248 : Last shell before umounting all and giving control over to real init.
252 if is_yes "$run_mounted"; then
254 mount --bind /run /newroot/run
259 if is_yes "$dev_mounted"; then
261 mount --bind /dev /newroot/dev
266 if is_yes "$sys_mounted"; then
268 mount --bind /sys /newroot/sys
273 if is_yes "$proc_mounted"; then
275 mount --bind /proc /newroot/proc
280 if is_yes "$tmp_mounted"; then
281 echo 'umount /tmp' | add_linuxrc
286 # Checks if busybox has support for APPLET(s)
287 # Exits from geninitrd if the support is not present.
289 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
293 if [ -z "$busybox_functions" ]; then
294 local tmp=$($busybox 2>&1)
296 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
297 if [[ "$tmp" = *applet\ not\ found* ]]; then
299 ln -s $busybox $t/busybox
300 local tmp=$($t/busybox 2>&1)
304 busybox_functions=$(echo "$tmp" | \
305 sed -ne '/Currently defined functions:/,$p' | \
306 xargs | sed -e 's,.*Currently defined functions: ,,'
312 eval have='$'busybox_have_$applet
313 if [ -z "$have" ]; then
314 have=$(echo "$busybox_functions" | grep -Ec "( |^)$applet(,|$)")
315 if [ "$have" = 0 ]; then
316 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
319 eval busybox_have_$applet=$have
322 if [ $err = 1 ]; then
327 # Extract the .config file from a kernel image
328 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
330 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
331 if [ -n "$kofile" ]; then
332 /lib/geninitrd/extract-ikconfig $kofile
336 # see if config available as separate file
337 if [ -f /boot/config-$kernel ]; then
338 cat /boot/config-$kernel
342 # finally try vmlinuz itself
343 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
351 module=${module%$modext*}
355 # Finds module dependencies
359 # Outputs full path to module and it's dependencies
364 # if module is prefixed with dash, we should ignore errors if the module
366 if [ ${module#-} != $module ]; then
371 # This works when user has module-init-tools installed even on 2.4 kernels
373 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
376 if [ $skiperrors = 1 ]; then
381 if ! is_no "$EXIT_IF_MISSING"; then
382 die "$module: module not found for $kernel kernel"
385 warn "$module: module not found for $kernel kernel"
386 warn "If $module isn't compiled in kernel then this initrd may not start your system."
392 while read insmod modpath options; do
393 if [ "$insmod" = "insmod" ]; then
395 # XXX: find a away to autodetect
396 smodule=$(basename_module $modpath)
399 find_depmod "-crct10dif"
402 find_depmod "-crc32c-intel"
403 find_depmod "-crc32c"
405 virtio_blk|virtio_scsi)
406 find_depmod "-virtio_pci"
407 find_depmod "-virtio_mmio"
420 # no firmware support in 2.4 kernels
421 if [ "$kernel_version_long" -lt "002005048" ]; then
424 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
429 local mod depmod module=$1
431 depmod=$(find_depmod $module) || exit 1
432 for mod in $depmod; do
433 mod=${mod#/lib/modules/$kernel/}
435 # add each module only once
437 for m in $MODULES; do
438 [ $m = $mod ] && have=1
440 if [ $have = 0 ]; then
441 MODULES="$MODULES $mod"
446 # install a file to temporary mount image.
447 # it will operate recursively (copying directories)
448 # and will symlink destinations if source is symlink.
450 if [ $# -lt 2 ]; then
451 die 'Usage: inst <file> [<file>] <destination>'
454 local src i=0 c=$(($# - 1))
455 while [ $i -lt $c ]; do
462 local parentDir=$(dirname $DESTDIR$dest)
463 if [ ! -d "$parentDir" ]; then
464 verbose "+ mkdir -p $parentDir"
467 verbose "+ cp $* $DESTDIR$dest"
468 cp -HR "$@" "$DESTDIR$dest"
473 die 'Usage: inst_d <destination> <destination>'
476 install -d "$DESTDIR$dir"
480 # install executable and it's shared libraries
482 if [ $# -lt 2 ]; then
483 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
485 local src i=0 c=$(($# - 1))
486 while [ $i -lt $c ]; do
499 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
503 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
505 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
507 inst_exec $lib /$_lib
512 # hack for uclibc linked binaries requiring this fixed path
513 # XXX: shouldn't rpath be used here instead so th
514 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
515 local lib=$DESTDIR/$_lib/libc.so.0
516 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
517 local libdir=$(cd $(dirname "$lib"); pwd)
518 if [ ! -e $DESTDIR$libdir ]; then
519 libdir=$(dirname "$libdir")
521 verbose "+ ln -s /$_lib $DESTDIR$libdir"
522 ln -s /$_lib $DESTDIR$libdir
527 # output modules.conf / modprobe.conf
529 echo "$modprobe_conf_cache"
532 # return options for MODULE
533 # @param $1 module name
536 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
541 # defaults to modprobe -c if not told otherwise, this means include statements
543 cache_modprobe_conf() {
544 if [ "$kernel_version" -lt "002005" ]; then
545 modulefile=/etc/modules.conf
546 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
547 modulefile=/etc/conf.modules
551 if [ -n "$modulefile" ]; then
552 debug "Using $modulefile for modules config"
553 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
556 debug "Using modprobe -c to get modules config"
557 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
561 # find modules for $devpath
562 find_modules_for_devpath() {
564 if [ -z "$devpath" ]; then
565 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
568 if [[ "$devpath" = /dev/dm-* ]]; then
569 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
570 devpath=$(dm_node "$devpath")
573 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
574 # sanitize things like:
575 # /dev/block/104:2 -> /dev/cciss/c0d0p2
576 devpath=$(readlink -f "$devpath")
579 verbose "Finding modules for device path $devpath"
581 if is_luks "$devpath"; then
582 find_modules_luks "$devpath"
586 if is_nfs "$devpath"; then
587 find_modules_nfs "$devpath"
591 if is_md "$devpath"; then
592 find_modules_md "$devpath"
596 if is_multipath "$devpath"; then
597 if find_modules_multipath "$devpath"; then
604 if is_dmraid "$devpath"; then
605 if find_modules_dmraid "$devpath"; then
611 if is_scsi "$devpath"; then
612 find_modules_scsi "$devpath"
616 if is_ide "$devpath"; then
617 find_modules_ide "$devpath"
621 if [[ "$devpath" == /dev/rd/* ]]; then
627 if [[ "$devpath" == /dev/ida/* ]]; then
628 find_module "cpqarray"
629 rootdev_add=/dev/ida/
633 if [[ "$devpath" == /dev/cciss/* ]]; then
634 rootdev_add=/dev/cciss/
636 # load hpsa for future kernels, cciss for backwards compat
637 if [ "$kernel_version_long" -ge "003000000" ]; then
638 find_module "hpsa" "-cciss"
639 find_modules_scsi "$devpath"
647 if [[ "$devpath" == /dev/ataraid/* ]]; then
649 find_module "ataraid"
650 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
651 if [ -n "$ataraidmodules" ]; then
652 # FIXME: think about modules compiled in kernel
653 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
655 for n in $ataraidmodules; do
658 rootdev_add=/dev/ataraid/
662 # check to see if we need to set up a loopback filesystem
663 if [[ "$devpath" == /dev/loop* ]]; then
664 die "Sorry, root on loop device isn't supported."
665 # TODO: rewrite for bsp and make nfs ready
666 if [ ! -x /sbin/losetup ]; then
667 die "losetup is missing"
669 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
670 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
671 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"
674 line="`awk '/'$key'/ { print $0; }' $fstab`"
675 loopDev="$(echo $line | awk '{print $3}')"
676 loopFs="$(echo $line | awk '{print $4}')"
677 loopFile="$(echo $line | awk '{print $5}')"
679 BASICMODULES="$BASICMODULES -loop"
680 find_module "-$loopFs"
681 BASICMODULES="$BASICMODULES -${loopFs}"
685 if is_lvm "$devpath"; then
686 find_modules_lvm "$devpath"
691 firmware_install_module() {
693 local firmware_files="$2"
695 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
696 # firmware not yet installed
697 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
699 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
701 echo 1 > /sys$DEVPATH/loading
702 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
703 echo 0 > /sys$DEVPATH/loading
706 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
708 # setup firmware loader agent
709 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
712 for firmware in $firmware_files; do
713 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
714 FIRMWAREDIR=${firmware%/*}
715 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
716 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
717 elif [ -f "/lib/firmware/$firmware" ]; then
718 FIRMWAREDIR=${firmware%/*}
719 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
720 inst /lib/firmware/$firmware /lib/firmware/$firmware
722 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
733 for mod in $modules; do
735 inst_d "/lib/modules/$kernel/$MODULEDIR"
736 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
737 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
738 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
739 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
744 modules_add_linuxrc() {
748 # module path without optional compression
752 local module=${modpath##*/}; module=${module%$modext}
753 local options=$(modprobe_options "$module")
754 local genericname=$(echo $module | tr - _)
755 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
756 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
758 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
759 options="scan=sync $options"
762 if [ x"$verbose" = x"-v" ]; then
764 if [ "$options" ]; then
765 s="$s with options [$options]"
767 if [ "$usleep" ]; then
768 s="$s and $usleep usleep"
770 verbose "Loading module [$module]$s"
773 if [ -n "$firmware" ]; then
774 firmware_install_module "$module" "$firmware"
776 for file in $(find_firmware "$module"); do
777 firmware_install_module "$module" "$file"
781 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
782 if [ -n "$usleep" ]; then
783 echo "usleep $usleep" | add_linuxrc
785 if [ "$module" = "scsi_wait_scan" ]; then
786 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
787 echo "rmmod scsi_wait_scan" | add_linuxrc
794 # Generates /dev nodes based on /proc/partitions information.
795 # Needs /proc mounted.
796 # Can be called multiple times.
797 initrd_gen_devices() {
798 if is_yes "$proc_partitions"; then
805 : 'Making device nodes'
806 cat /proc/partitions | (
807 # ignore first two lines: header, empty line
810 while read major minor blocks dev rest; do
813 [ -e $node ] || mknod -m 660 $node b $major $minor
820 initrd_gen_setrootdev() {
821 verbose "Adding rootfs finding based on kernel cmdline root= option support."
823 debug "Current /proc/partitions:\n$(sed -e 's,^,> ,' /proc/partitions)"
825 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
826 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
828 if [ -z "$rootnr" ]; then
829 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
831 if [ -n "$rootnr" ]; then
832 echo "$rootnr" > /proc/sys/kernel/real-root-dev
838 initrd_gen_initramfs_switchroot() {
840 if [ "$rootdev" = "/dev/nfs" ]; then
841 echo "rootfs on NFS root=/dev/nfs"
843 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
846 # parse 'root=xxx' kernel commandline
847 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
849 # from lilo-23.2/readme/README:
850 # root=<device> changes the root device. This overrides settings that may
851 # have been made in the boot image and on the LILO command line. <device> is
852 # either the hexadecimal device number or the full path name of the device,
855 # * The device names are hard-coded in the kernel. Therefore, only the
856 # "standard" names are supported and some less common devices may not be
857 # recognized. In those cases, only numbers can be used.
861 eval "$(busybox awk -v root="$ROOT" '
862 # http://9fans.net/archive/2006/09/261
863 function h2d(str, hstr, res, num, n, digit, i) {
864 hstr = "0123456789abdcef";
866 n = split(tolower(str), digit, "");
868 for (i = 1; i <= n; i++) {
869 num = index(hstr, digit[i]) - 1;
870 res = res + (num * 16 ^ (n - i));
877 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
878 num_pattern = "[0-9a-fA-F]" num_pattern_short;
879 dev_pattern = "[hms][a-z][a-z]([0-9])+";
883 # see if we have /dev/hdX or hdX, we can just take partition name
884 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
886 sub("^/dev/", "", partition);
890 if (root ~ "^" num_pattern_short "$") {
891 # change "303" => "0x0303"
893 } else if (root ~ "^" num_pattern "$") {
894 # change "0303" => "0x0303"
898 maj = h2d(substr(root, 3, 2));
899 min = h2d(substr(root, 5, 2));
903 partition && $4 == partition { maj = $1; min = $2; }
904 $1 == maj && $2 == min { partition = $4; }
907 if (maj >= 0 && min >= 0) {
908 printf("maj=%s; min=%s;\n", maj, min);
911 printf("device=/dev/%s;\n", partition);
916 if [ -z "$device" ]; then
917 if [ "$DEBUGINITRD" ]; then
923 if [ "$device" -a ! -b $device ]; then
924 mknod -m 660 $device b $maj $min
927 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
929 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
931 if [ -z "$init" -o ! -x "/newroot$init" ]; then
939 if [ "$DEBUGINITRD" ]; then
940 echo "Last 20 lines of dmesg:"
946 busybox_applet switch_root
948 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
949 exec switch_root /newroot $init ${1:+"$@"}
951 echo "Error! initramfs should not reach this place."
952 echo "It probably means you've got old version of busybox, with broken"
953 echo "initramfs support. Trying to boot anyway, but won't promise anything."
955 exec chroot /newroot $init ${1:+"$@"}
957 echo "Failed to chroot!"
960 # we need /init being real file, not symlink, otherwise the initramfs will
961 # not be ran by pid 1 which is required for switch_root
962 mv $DESTDIR/linuxrc $DESTDIR/init
963 ln -s init $DESTDIR/linuxrc
966 # find if $symbol exists in System.map $mapfile
970 if [ ! -f $mapfile ]; then
971 # missing mapfile (not a pld kernel?)
975 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
978 # find best compressor (or forced one) for initrd
981 # fastest initrd decompression speed is first
982 local compressors='lzo gzip xz lzma bzip2'
984 # a specified one, take it
985 if ! is_yes "$mode"; then
989 verbose "finding compressor: $compressors (via $mode)"
990 # check for compressor validity
991 local c prog map=/boot/System.map-$kernel
992 for c in $compressors; do
1015 # any existing sym will work
1020 die "Unknown compressor $c"
1023 if sym_exists $map $sym && [ -x $prog ]; then
1029 verbose "using gzip for compressor (fallback)"
1033 # compresses kernel image image
1034 # in function so we could retry with other compressor on failure
1036 local compressor="$1" IMAGE="$2" target="$3" tmp
1037 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1039 case "$compressor" in
1041 # don't use -9 here since kernel won't understand it
1042 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1045 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1048 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1051 gzip -9 < "$IMAGE" > "$tmp" || return $?
1054 lzop -9 < "$IMAGE" > "$tmp" || return $?
1057 cat < "$IMAGE" > "$tmp" || return $?
1061 mv -f "$tmp" "$target"
1064 if [ -r /etc/sysconfig/geninitrd ]; then
1065 . /etc/sysconfig/geninitrd
1068 if [ ! -f /proc/mounts ]; then
1069 warn "/proc filesystem not mounted, may cause wrong results or failure."
1072 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
1074 while [ $# -gt 0 ]; do
1084 modulefile=${1#--modules-conf=}
1093 --without-bootsplash)
1105 --without-fbcondecor)
1114 --with-suspend2 | --with-tuxonice)
1117 --without-suspend2 | --without-tuxonice)
1121 LVMTOOLSVERSION=${1#--lvmversion=}
1123 --lvmtoolsversion=*)
1124 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1126 --lvmtoolsversion|--lvmversion)
1139 --without-multipath)
1143 USE_MULTIPATH=${1#--with-multipath=}
1152 BASICMODULES="$BASICMODULES ${1#--with=}"
1155 BASICMODULES="$BASICMODULES $2"
1159 echo "$PROGRAM: version $VERSION"
1163 if [ x"$verbose" = x"-v" ]; then
1174 COMPRESS="${1#--compress=}"
1183 STRIP="${1#--strip=}"
1196 PREMODS="$PREMODS ${1#--preload=}"
1199 PREMODS="$PREMODS $2"
1203 die "--fs option is obsoleted. Use --initrdfs instead"
1206 INITRDFS=${1#--initrdfs=}
1219 if [ -z "$target" ]; then
1221 elif [ -z "$kernel" ]; then
1233 if [ -z "$target" -o -z "$kernel" ]; then
1239 if [ "$(id -u)" != 0 ]; then
1240 die "You need to be root to generate initrd"
1243 if [ -d /lib64 -a -d /usr/lib64 ]; then
1249 initrd_dir=/usr/$_lib/initrd
1250 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1251 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1253 verbose "# $GENINITRD_RCSID (geninitrd)"
1254 debug "Using _lib: $_lib"
1255 debug "Using initrd_dir: $initrd_dir"
1257 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1259 # we setup mods after parsing command line args
1260 geninitrd_setup_mods
1262 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1263 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1266 if [ -z "$INITRDFS" ]; then
1267 if [ -n "$FS" ]; then
1268 # FS= can came only via /etc/sysconfig/geninitrd likely?
1269 die "FS configuration option is obsoleted. Use INITRDFS instead"
1273 if [ "$kernel_version" -ge "002005" ]; then
1274 INITRDFS="initramfs"
1282 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1285 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1288 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1291 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1292 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1295 die "Filesystem $INITRDFS on initrd is not supported"
1299 if [ -L "$target" ]; then
1300 target=$(readlink -f "$target")
1303 if [ -n "$img_vers" ]; then
1304 target="$target-$kernel"
1307 if [ -z "$force" -a -f "$target" ]; then
1308 die "$target already exists."
1311 if [ ! -d "/lib/modules/$kernel" ]; then
1312 die "/lib/modules/$kernel is not a directory."
1315 if [ "$kernel_version" -ge "002005" ]; then
1321 for n in $PREMODS; do
1325 if [ "$FBMODULE" ]; then
1326 find_module "$FBMODULE"
1329 # autodetect USB keyboards
1332 # allow forcing loading SCSI and/or IDE modules
1333 # XXX: where ADDSCSI cames from? drop?
1334 if is_yes "$ADDSCSI"; then
1338 # autodetect SATA modules
1341 # XXX: where ADDIDE cames from? drop?
1342 if is_yes "$ADDIDE"; then
1346 if is_yes "$USE_SUSPEND"; then
1347 find_modules_suspend
1350 find_root "$fstab" || exit
1351 verbose "Using $rootdev as device for rootfs"
1353 find_modules_for_devpath "$rootdev"
1355 # if USE_MULTIPATH is path to device, scan that too
1356 # this is to bootstrap multipath setup into initrd.
1357 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1358 find_modules_multipath $USE_MULTIPATH
1361 find_module "-$rootFs"
1363 for n in $BASICMODULES; do
1367 if is_yes "$USE_TUXONICE"; then
1371 find_modules_fbsplash
1373 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1374 verbose "No modules are needed -- not building initrd image."
1378 verbose "Building initrd..."
1379 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1380 RCFILE="$DESTDIR/linuxrc"
1382 chmod a+rx "$RCFILE"
1383 ln -s linuxrc $DESTDIR/init
1385 # create dirs that we really need
1386 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1388 modules_install "$MODULES"
1390 # mknod'ing the devices instead of copying them works both with and
1392 mknod -m 600 "$DESTDIR/dev/console" c 5 1
1393 mknod -m 666 "$DESTDIR/dev/null" c 1 3
1394 mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1395 mknod -m 666 "$DESTDIR/dev/random" c 1 8
1396 mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
1398 inst_exec $busybox /bin/busybox
1399 ln -s busybox $DESTDIR/bin/sh
1400 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1401 ln -s busybox $DESTDIR/bin/initrd-busybox
1405 # initrd generated by:
1411 # builtin defaults from geninitrd
1415 add_linuxrc <<-'EOF'
1416 read CMDLINE < /proc/cmdline
1418 for arg in $CMDLINE; do
1419 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
1422 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1423 DEBUGINITRD=${arg##debug*rd=}
1425 if [ "${arg##root=}" != "${arg}" ]; then
1428 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1429 ROOTFSFLAGS=${arg##rootfsflags=}
1431 if [ "${arg##init=}" != "${arg}" ]; then
1436 if [ "$DEBUGINITRD" = "sh" ]; then
1437 # export some vars for subshell debug to work
1438 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFSFLAGS DEBUGINITRD INIT
1439 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1440 export rootnr attrs majmin major minor device
1442 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1445 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1446 add_linuxrc <<-'EOF'
1447 echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1450 add_linuxrc <<-'EOF'
1454 add_linuxrc <<-'EOF'
1462 if [ "$DEBUGINITRD" ]; then
1467 modules_add_linuxrc $MODULES
1469 # TODO: rewrite for busybox
1470 #if [ -n "$loopDev" ]; then
1471 # if [ ! -d /initrd ]; then
1475 # cp -a "$loopDev" "$DESTDIR/dev"
1476 # cp -a "$rootdev" "$DESTDIR/dev"
1477 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1478 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1479 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
1480 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1483 if is_yes "$USE_UDEV"; then
1489 find_modules_uvesafb
1494 initrd_gen_multipath
1497 if is_yes "$have_nfs"; then
1504 initrd_gen_setrootdev
1507 # additional devs always needed
1508 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1510 initrd_gen_stop_udevd
1511 initrd_gen_stop_mdev
1512 initrd_gen_stop_uvesafb
1514 # resume after killing local processes
1519 add_linuxrc <<-'EOF'
1520 if [ ! "$DEBUGINITRD" ]; then
1524 for i in $(export -p); do
1525 i=${i#declare -x } # ksh/bash
1526 i=${i#export } # busybox
1537 [ -z "$i" ] && continue
1540 ROOT|PATH|HOME|TERM)
1552 if [ "$INITRDFS" = "initramfs" ]; then
1553 initrd_gen_initramfs_switchroot
1559 initrd_gen_fbcondecor
1561 debug "Current /linuxrc:\n$(sed -e 's,^,> ,' $DESTDIR/linuxrc)"
1563 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1565 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1566 verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1568 verbose "Creating $INITRDFS image $IMAGE"
1571 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1572 # NOTE: ext2 label is max 16 chars
1573 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1574 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1576 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1577 debug "Mounting ext2 image $IMAGE to $tmpmnt"
1578 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1579 # We don't need this directory, so let's save space
1580 rm -rf "$tmpmnt"/lost+found
1582 debug "Copy recursively $DESTDIR -> $tmpmnt"
1583 cp -a $DESTDIR/* $tmpmnt
1589 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1592 mkcramfs "$DESTDIR" "$IMAGE"
1595 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1598 die "Filesystem $INITRDFS not supported by $PROGRAM"
1601 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1602 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1603 CONFIG_BLK_DEV_RAM_SIZE=4096
1604 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1607 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1608 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1611 if ! is_no "$COMPRESS"; then
1612 compressor=$(find_compressor "$COMPRESS")
1613 verbose "Compressing $target with $compressor"
1615 # TODO: the image name (specified from kernel.spec) already contains
1616 # extension, which is .gz most of the time.
1617 compress_image "$compressor" "$IMAGE" "$target" || {
1618 if [ $compressor != gzip ]; then
1619 warn "Could not compress with $compressor, retrying with gzip"
1620 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1622 die "Could not compress image with $compressor"
1626 cp -a "$IMAGE" "$target"
1629 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1630 initrd_gen_bootsplash "$target"
1632 rm -rf "$DESTDIR" "$IMAGE"
1634 # vim:ts=4:sw=4:noet:fdm=marker