]> git.pld-linux.org Git - projects/geninitrd.git/blobdiff - geninitrd
Use kernel ready compression settings for xz.
[projects/geninitrd.git] / geninitrd
index 2ac4d88978e35a8fd01ce0ea827cf4bad8ff1806..f08fdd63d1c9b1c999f0ca75ab26df4a634870ec 100755 (executable)
--- a/geninitrd
+++ b/geninitrd
@@ -7,8 +7,8 @@
 # based on mkinitrd from RedHat Linux
 #
 
-RCSID='$Id$'
-R=${RCSID#* * }; VERSION=${R%% *}
+RCSID='$Revision$ $Date$'
+R=${RCSID#* *}; VERSION=${R%% *}
 PROGRAM=${0##*/}
 
 . /etc/rc.d/init.d/functions
@@ -47,15 +47,16 @@ usage() {
        uname_r=$(uname -r)
        echo "usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
        echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
+       echo "       [--compress=yes|xz|lzma|bzip2|gzip]"
        echo "       [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
-       echo "       [--with-raidstart] [--without-raidstart]"
        echo "       [--with-bootsplash] [--without-bootsplash]"
        echo "       [--with-fbsplash] [--without-fbsplash]"
        echo "       [--with-fbcondecor] [--without-fbcondecor]"
        echo "       [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
        echo "       [--with-suspend] [--without-suspend]"
        echo "       [--with-tuxonice] [--without-tuxonice]"
-       echo "       [--without-dmraid] [--without-multipath]"
+       echo "       [--without-dmraid]"
+       echo "       [--with-multipath=DEVPATH] [--without-multipath]"
        echo "       [--without-blkid] [--without-luks]"
        echo "       <initrd-image> <kernel-version>"
        echo ""
@@ -151,6 +152,7 @@ mount_dev() {
                mknod /dev/console c 5 1
                mknod /dev/null c 1 3
                mknod /dev/zero c 1 5
+               mknod /dev/urandom c 1 9
                mkdir /dev/pts
                mkdir /dev/shm
        EOF
@@ -232,7 +234,7 @@ umount_all() {
 #
 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
 busybox_applet() {
-       local err=0
+       local err=0 applet
 
        if [ -z "$busybox_functions" ]; then
                local tmp=$($busybox 2>&1)
@@ -471,6 +473,7 @@ find_modules_for_devpath() {
                if find_modules_multipath "$devpath"; then
                        return
                fi
+
                # fallback
        fi
 
@@ -572,12 +575,16 @@ EOF
        fi
 
        for firmware in $firmware_files; do
-               if [ ! -f "/lib/firmware/$firmware" ]; then
-                               die "firmware file /lib/firmware/$firmware doesn't exist."
-               else
+               if [ -f "/lib/firmware/$kernel/$firmware" ]; then
+                       FIRMWAREDIR=${firmware%/*}
+                       [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
+                       inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
+               elif [ -f "/lib/firmware/$firmware" ]; then
                        FIRMWAREDIR=${firmware%/*}
                        [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
                        inst /lib/firmware/$firmware /lib/firmware/$firmware
+               else
+                       die "firmware file /lib/firmware/$firmware nor /lib/firmware/$kernel/$firmware found."
                fi
        done
 
@@ -640,6 +647,12 @@ modules_add_linuxrc() {
                if [ -n "$sleep_var" ]; then
                        echo "usleep $sleep_var" | add_linuxrc
                fi
+               if [ "$module" = "scsi_wait_scan" ]; then
+                       if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
+                               echo "rmmod scsi_wait_scan" | add_linuxrc
+                       fi
+               fi
+
        done
 }
 
@@ -745,13 +758,13 @@ initrd_gen_initramfs_switchroot() {
        umount_all
        busybox_applet switch_root
        add_linuxrc <<-'EOF'
-               exec switch_root /newroot $init
+               exec switch_root /newroot $init ${1:+"$@"}
 
                echo "Error! initramfs should not reach this place."
                echo "It probably means you've got old version of busybox, with broken"
                echo "initramfs support. Trying to boot anyway, but won't promise anything."
 
-               exec chroot /newroot $init
+               exec chroot /newroot $init ${1:+"$@"}
 
                echo "Failed to chroot!"
        EOF
@@ -761,10 +774,72 @@ initrd_gen_initramfs_switchroot() {
        ln -s init $DESTDIR/linuxrc
 }
 
+# find if $symbol exists in System.map $mapfile
+sym_exists() {
+       local mapfile="$1"
+       local symbol="$2"
+       if [ ! -f $mapfile ]; then
+               # missing mapfile (not a pld kernel?)
+               return 1
+       fi
+
+       awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
+}
+
+# find best compressor (or forced one) for initrd
+find_compressor() {
+       local mode="$1"
+       # the best compressor list
+       local compressors='xz lzma bzip2 gzip'
+
+       # a specified one, take it
+       if ! is_yes "$mode"; then
+               compressors="$mode"
+       fi
+
+       debug "finding compressor: $compressors (via $mode)"
+       # check for compressor validity
+       local c prog map=/boot/System.map-$kernel
+       for c in $compressors; do
+               case $c in
+               xz)
+                       sym=unxz
+                       prog=/usr/bin/xz
+                       ;;
+               lzma)
+                       sym=unlzma
+                       prog=/usr/bin/xz
+                       ;;
+               bzip2)
+                       sym=bzip2
+                       prog=/usr/bin/bzip2
+                       ;;
+               gzip)
+                       sym=gunzip
+                       prog=/bin/gzip
+                       ;;
+               *)
+                       die "Unknown compressor $c"
+                       ;;
+               esac
+               if sym_exists $map $sym && [ -x $prog ]; then
+                       echo $c
+                       return
+               fi
+       done
+
+       debug "using gzip for compressor (fallback)"
+       echo gzip
+}
+
 if [ -r /etc/sysconfig/geninitrd ]; then
        . /etc/sysconfig/geninitrd
 fi
 
+if [ ! -f /proc/mounts ]; then
+       warn "/proc filesystem not mounted, may cause wrong results or failure."
+fi
+
 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs scsi
 
 while [ $# -gt 0 ]; do
@@ -783,12 +858,6 @@ while [ $# -gt 0 ]; do
                modulefile=$2
                shift
                ;;
-       --use-raidstart|--with-raidstart)
-               USERAIDSTART=yes
-               ;;
-       --without-raidstart)
-               USERAIDSTART=no
-               ;;
        --with-bootsplash)
                BOOT_SPLASH=yes
                ;;
@@ -839,7 +908,10 @@ while [ $# -gt 0 ]; do
                USE_DMRAID=no
                ;;
        --without-multipath)
-               USE_MULTPATH=no
+               USE_MULTIPATH=no
+               ;;
+       --with-multipath=*)
+               USE_MULTIPATH=${1#--with-multipath=}
                ;;
        --without-blkid)
                USE_BLKID=no
@@ -861,6 +933,12 @@ while [ $# -gt 0 ]; do
        -v)
                verbose=-v
                ;;
+       --compress)
+               COMPRESS=$2
+               ;;
+       --compress=*)
+               COMPRESS="${1#--compress=}"
+               ;;
        --nocompress)
                COMPRESS=no
                ;;
@@ -990,10 +1068,6 @@ if [ ! -d "/lib/modules/$kernel" ]; then
        die "/lib/modules/$kernel is not a directory."
 fi
 
-if [ ! -f /proc/mounts ]; then
-       warn "/proc filesystem not mounted, may cause wrong results or failure."
-fi
-
 if [ "$kernel_version" -ge "002005" ]; then
        modext=".ko"
 fi
@@ -1028,6 +1102,12 @@ debug "Using $rootdev as device for rootfs"
 
 find_modules_for_devpath "$rootdev"
 
+# if USE_MULTIPATH is path to device, scan that too
+# this is to bootstrap multipath setup into initrd.
+if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
+       find_modules_multipath $USE_MULTIPATH
+fi
+
 find_module "-$rootFs"
 
 for n in $BASICMODULES; do
@@ -1062,6 +1142,7 @@ modules_install "$MODULES"
 mknod "$DESTDIR/dev/console" c 5 1
 mknod "$DESTDIR/dev/null" c 1 3
 mknod "$DESTDIR/dev/zero" c 1 5
+mknod "$DESTDIR/dev/urandom" c 1 9
 
 inst_exec $busybox /bin/initrd-busybox
 ln -s initrd-busybox $DESTDIR/bin/sh
@@ -1161,7 +1242,7 @@ fi
 
 if is_yes "$have_nfs"; then
        initrd_gen_nfs
-elif is_yes "$USERAIDSTART" && is_yes "$have_md"; then
+elif is_yes "$have_md"; then
        initrd_gen_md
        if is_yes "$have_lvm"; then
                initrd_gen_lvm
@@ -1204,12 +1285,6 @@ IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
 debug "Creating $INITRDFS image $IMAGE"
 case "$INITRDFS" in
   ext2)
-       IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
-       debug   "ext2 image size: $IMAGESIZE ($DESTDIR)"
-       if [ "$IMAGESIZE" -gt 4096 ]; then
-               warn "Your image size is larger than 4096, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
-       fi
-
        dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
        mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
        tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
@@ -1228,11 +1303,6 @@ case "$INITRDFS" in
        ;;
   rom|romfs)
        genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD initrd for kernel $kernel"
-       IMAGESIZE=$(stat -c %s $IMAGE | awk '{print int((($1/1024)+1023)/1024)*1024}')
-       debug "Image size for romfs: ${IMAGESIZE}KiB ($IMAGE)"
-       if [ "$IMAGESIZE" -gt 4096 ]; then
-               warn "Your image size is larger than 4096, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
-       fi
        ;;
   cram|cramfs)
        mkcramfs "$DESTDIR" "$IMAGE"
@@ -1244,18 +1314,42 @@ case "$INITRDFS" in
        die "Filesystem $INITRDFS not supported by $PROGRAM"
 esac
 
-if is_yes "$COMPRESS"; then
+# TODO: figure out this automatically
+CONFIG_BLK_DEV_RAM_SIZE=4096
+
+IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
+debug  "image size: $IMAGESIZE KiB ($DESTDIR)"
+if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
+       warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
+fi
+
+if ! is_no "$COMPRESS"; then
        tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
-       debug "Compressing $target"
-       gzip -9 < "$IMAGE" > "$tmp"
+       compressor=$(find_compressor "$COMPRESS")
+       debug "Compressing $target with $compressor"
+
+       # TODO: the image name (specified from kernel.spec) already contains
+       # extension, which is .gz most of the time.
+       case "$compressor" in
+       xz)
+               # don't use -9 here since kernel won't understand it
+               xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp"
+               ;;
+       lzma)
+               xz --format=lzma -9 < "$IMAGE" > "$tmp"
+               ;;
+       bzip2)
+               bzip2 -9 < "$IMAGE" > "$tmp"
+               ;;
+       gzip)
+               gzip -9 < "$IMAGE" > "$tmp"
+               ;;
+       esac
        mv -f "$tmp" "$target"
 else
        cp -a "$IMAGE" "$target"
 fi
 
-size=$(stat -c %s $target | awk '{print int((($1/1024)+1023)/1024)*1024}')
-debug "Minimum RAM size that could be used for $target is: ramdisk_size=$size"
-
 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
 if is_yes "$BOOT_SPLASH"; then
        initrd_gen_bootsplash "$target"
This page took 0.044421 seconds and 4 git commands to generate.