# 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
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 ""
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
#
# 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)
if find_modules_multipath "$devpath"; then
return
fi
+
# fallback
fi
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
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
}
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
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
modulefile=$2
shift
;;
- --use-raidstart|--with-raidstart)
- USERAIDSTART=yes
- ;;
- --without-raidstart)
- USERAIDSTART=no
- ;;
--with-bootsplash)
BOOT_SPLASH=yes
;;
USE_DMRAID=no
;;
--without-multipath)
- USE_MULTPATH=no
+ USE_MULTIPATH=no
+ ;;
+ --with-multipath=*)
+ USE_MULTIPATH=${1#--with-multipath=}
;;
--without-blkid)
USE_BLKID=no
-v)
verbose=-v
;;
+ --compress)
+ COMPRESS=$2
+ ;;
+ --compress=*)
+ COMPRESS="${1#--compress=}"
+ ;;
--nocompress)
COMPRESS=no
;;
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
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
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
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
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
;;
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"
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"