5 # by Jacek Konieczny <jajcus@pld.org.pl>
7 # based on mkinitrd from RedHat
9 RCSID='$Id: geninitrd,v 2.28 2003/07/17 18:08:24 arekm Exp $'
13 VERSION="`echo "$RCSID"|awk '{print $3}'`"
15 . /etc/rc.d/init.d/functions
18 # INITRDFS is set later (catch obsoleted FS option)
23 # it should be safe to remove scsi_mod from here, but I'm not sure...
24 PRESCSIMODS="-scsi_mod unknown -sd_mod"
25 PREIDEMODS="-ide-probe -ide-probe-mod -ide-disk"
32 modulefile="/etc/modules.conf"
33 raidtab="/etc/raidtab"
39 echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]" 1>&2
40 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" 1>&2
41 echo " [--initrdfs=rom|ext2|cram] [--modules-conf=<modules.conf>]" 1>&2
42 echo " [--with-raidstart] [--without-raidstart] [--with-insmod-static]" 1>&2
43 echo " <initrd-image> <kernel-version>" 1>&2
44 echo " (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" 1>&2
50 echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
54 typeset mods module f level depfile first
56 depfile=/lib/modules/$kernel/modules.dep
58 if [ -f $depfile ] ; then
61 echo "Error: no $depfile ! Run depmod and rerun geninitrd." 1>&2
65 # prepend / if no path given, append $modext.gz if not given,
68 module=$(echo "$2" | \
69 awk '/\// {print;next} {print "/" $0}' | \
70 awk '/\./ {print;next} {print $0 "'$modext'.gz"}' |
71 awk '{gsub("/","\\/");print}')
74 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
76 /(.*)/ { gsub(/\\/," "); if (here) print }
80 if [ "$mods" = "" ] ; then
81 module=$(echo "$module" | \
82 awk '{gsub("\'$modext'\.gz$","\'$modext'",$0);print}')
86 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
88 /(.*)/ { gsub(/\\/," "); if (here) print }
91 if [ "$mods" = "" ] ; then
92 if [ "$1" != silent ] ; then
93 echo "$origmodule: module not found in $depfile" 1>&2
95 if ! is_no "$EXIT_IF_MISSING" ; then
98 echo "If $origmodule isn't compiled in kernel then this initrd may not start your system". 1>&2
103 if [ "$level" = "" ] ; then
106 level=$(awk "BEGIN{print $level + 1}")
107 if [ $level -gt 20 ] ; then
108 echo "$origmodule: cycle in $depfile" 1>&2
114 if [ "$first" = "" ] ; then
117 find_depmod $1 $f $level
128 if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
129 if [ -n "$skiperrors" ]; then
133 echo "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)" 1>&2
137 # only need to add each module once
139 tmpFmPath=$(echo $fmPath | awk '{gsub(/\//,"\\/");print}')
140 if echo "$MODULES" | awk '/'"$tmpFmPath"'/ {exit 1}' ; then
141 MODULES="$MODULES $fmPath"
149 if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
151 modName="$(echo $modName | awk '{print(substr($0,2));}')"
155 if [ "$modName" = "pluto" ]; then
159 if [ "$modName" = "fcal" ]; then
164 if [ -n "$skiperrors" ]; then
165 allModulesToFind=`find_depmod silent $modName`
167 allModulesToFind=`find_depmod normal $modName`
168 if [ $? != 0 ] ; then
173 for mod in $allModulesToFind ; do
175 awk '{sub(/^\/lib\/modules\/[^\/]*\//,"");print}')
176 addmodule $mod "$skiperrors"
181 if [ "$#" != "2" ];then
182 echo "usage: inst <file> <destination>"
185 [ -n "$verbose" ] && echo "$1 -> $2"
190 /sbin/e2label $1 2> /dev/null
194 /sbin/tune2fs -l $1 2> /dev/null | awk -F: '/UUID:/ {gsub(" ",""); print $2}'
198 /usr/sbin/xfs_db -x -p xfs_admin -c label -r "$1"|awk -F= '{sub("^\"","", $2); sub("\"$", "", $2); print $2}'
203 /usr/sbin/xfs_db -x -p xfs_admin -c uuid -r "$1"|awk -F= '{print $2}'
207 eval `awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab`
210 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
211 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
212 if [ -n "$rootdev2" ] ; then
217 if [ "$rootdev_found." != "1." ] ; then
220 if [ ! -x /sbin/e2label ] ; then
221 echo "/sbin/e2label is missing" 1>&2
224 get_label="get_label_ext2"
227 if [ ! -x /usr/sbin/xfs_db ] ; then
228 echo "/usr/sbin/xfs_db is missing" 1>&2
231 get_label="get_label_xfs"
234 echo "LABEL on $rootFs in not supported by geninitrd" 1>&2
238 if [ ! -r /proc/partitions ] ; then
239 echo '/proc/partitions is not readable'; 1>&2
242 label=${rootdev#"LABEL="}
243 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
244 if [ -r $dev ] && [ "$label" = "`$get_label $dev`" ] ; then
245 if [ -n "$verbose" ] ; then
246 echo "Using $dev as device for rootfs"
253 if [ "$rootdev_found." != "1." ] ; then
254 echo "geninitrd can't find real device for LABEL=$label" 1>&2
260 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
261 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
262 if [ -n "$rootdev2" ] ; then
267 if [ "$rootdev_found." != "1." ] ; then
270 if [ ! -x /sbin/tune2fs ] ; then
271 echo "/sbin/tune2fs is missing" 1>&2
274 get_uuid="get_uuid_ext2"
277 if [ ! -x /usr/sbin/xfs_db ] ; then
278 echo "/usr/sbin/xfs_db is missing" 1>&2
281 get_label="get_uuid_xfs"
284 echo "UUID on $rootFs in not supported by geninitrd" 1>&2
288 if [ ! -r /proc/partitions ] ; then
289 echo '/proc/partitions is not readable'; 1>&2
292 uuid=${rootdev#"UUID="}
293 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
294 if [ -r $dev ] && [ "$uuid" = "`$get_uuid $dev`" ] ; then
295 if [ -n "$verbose" ] ; then
296 echo "Using $dev as device for rootfs"
303 if [ "$rootdev_found" != 1 ] ; then
304 echo "geninitrd can't find real device for UUID=$uuid" 1>&2
313 find_modules_softraid() {
314 eval `awk -v rootdev="$1" 'BEGIN {
329 if (found == "yes") {
334 if (found == "yes") {
335 if ($1 == "device") {
336 dev_list = dev_list " " $2;
338 if ($1 == "raid-level") {
345 print "raidfound=" found "\nraidlevel=" raidlevel "\ndev_list=\"" dev_list "\"\n";
347 if is_yes "$raidfound" ; then
350 findmodule "raid$raidlevel"
356 echo "raid level $number (in $raidtab) not recognized" 1>&2
360 for device in $dev_list; do
361 find_modules_for $device
365 find_modules_scsi() {
366 for n in $PRESCSIMODS; do
367 if [ "X$n" = "Xunknown" ] ; then
368 if [ ! -f "$modulefile" ]; then
369 modulefile=/etc/conf.modules
371 if [ -f "$modulefile" ]; then
372 scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
373 for n in $scsimodules; do
374 # for now allow scsi modules to come from anywhere. There are some
375 # RAID controllers with drivers in block
386 for n in $PREIDEMODS; do
392 if is_yes "`echo "$1" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
393 find_modules_softraid "$1"
394 elif is_yes "$(echo "$1" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
396 elif is_yes "`echo "$1" | awk '/^\/dev\/(hd|ide|ataraid)/ { print "yes"; }'`" ; then
398 elif is_yes "`echo "$1" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
400 elif is_yes "`echo "$1" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
401 findmodule "cpqarray"
402 elif is_yes "`echo "$1" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
404 elif is_yes "`echo "$1" | awk '/\/dev\/ataraid\// { print "yes"; }'`"; then
406 ataraidmodules="`awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
407 if -n "$ataraidmodules" ; then
408 # FIXME: think about modules compiled in kernel
409 echo "ERROR: ataraid_hostadapter alias not defined in $modulefile !"
410 echo "Please set it and run $0 again."
413 for n in $ataraidmodules; do
416 # check to see if we need to set up a loopback filesystem
417 elif is_yes "`echo "$1" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
418 echo "Sorry, root on loop device isn't supported." 1>&2
420 # TODO: rewrite for bsp and make nfs ready
421 if [ ! -x /sbin/losetup ]; then
422 echo "losetup is missing"
425 key="^# $(echo $1 | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
426 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
427 echo "The root filesystem is on a $1, but there is no magic entry in $fstab" 1>&2
428 echo "for this device. Consult the geninitrd man page for more information" 1>&2
432 line="`awk '/'$key'/ { print $0; }' $fstab`"
433 loopDev="$(echo $line | awk '{print $3}')"
434 loopFs="$(echo $line | awk '{print $4}')"
435 loopFile="$(echo $line | awk '{print $5}')"
437 BASICMODULES="$BASICMODULES -loop"
438 findmodule "-$loopFs"
439 BASICMODULES="$BASICMODULES -${loopFs}"
440 # don't have any clue, how is this supposed to work
441 elif ls -l "$1"|awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'; then
442 if [ ! -f /sbin/initrd-lvm ] ; then
443 echo "ERROR: root on LVM but /sbin/initrd-lvm not found."
444 echo "Please install lvm-initrd package and rerun $0."
447 if [ -n "$PVDEVICES" ] ; then
448 for device in $PVDEVICES; do
449 find_modules_for $device
452 echo "ERROR: Sorry, but searching for PV isn't implemented yet."
453 echo "Use PVDEVICES in /etc/sysconfig/geninitrd to set it."
457 findmodule "-lvm-mod"
462 if [ -r /etc/sysconfig/geninitrd ] ; then
463 . /etc/sysconfig/geninitrd
466 if [ "x" = "x$INITRDFS" ] ; then
467 if [ "x" = "x$FS" ] ; then
471 echo "Warning: FS configuration options is obsoleted. Use INITRDFS instead" 1>&2
476 if [ ! -x /sbin/bsp ] ; then
477 echo "/sbin/bsp is missing !"
480 if [ "`uname -m`" = "ia64" ]; then
485 while [ $# -gt 0 ]; do
488 fstab="`echo $1 | awk -F= '{print $2;}'`"
495 modulefile="`echo $1 | awk -F= '{print $2;}'`"
502 raidtab="`echo $1 | awk -F= '{print $2;}'`"
508 --use-raidstart|--with-raidstart)
514 --use-insmod-static|--with-insmod-static)
515 USEINSMODSTATIC="yes"
517 --without-insmod-static)
521 BASICMODULES="$BASICMODULES `echo $1 | awk -F= '{print $2;}'`"
524 BASICMODULES="$BASICMODULES $2"
528 echo "geninitrd: version $VERSION"
544 PREMODS="$PREMODS `echo $1 | awk -F= '{print $2;}'`"
547 PREMODS="$PREMODS $2"
551 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
552 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
555 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
560 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
570 if [ -z "$target" ]; then
572 elif [ -z "$kernel" ]; then
583 if [ -z "$target" -o -z "$kernel" ]; then
587 pack_version="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d",$1,$2)}'`"
589 if [ "$pack_version" -ge "002005" ] ; then
594 if is_yes "$USEINSMODSTATIC" ; then
595 insmod="insmod.static"
596 INSMOD="/sbin/insmod.static"
597 if [ "$pack_version" -lt "002005" -a -f /sbin/insmod.static.modutils ] ; then
598 INSMOD="/sbin/insmod.static.modutils"
600 if [ ! -f "$INSMOD" ] ; then
601 echo "insmod.static requested but /sbin/insmod.static not found !" >&2
608 if [ ! -x /sbin/mke2fs ]; then
609 echo "/sbin/mke2fs is missing" 1>&2
614 if [ ! -x /sbin/genromfs ]; then
615 echo "/sbin/genromfs is missing" 1>&2
620 if [ ! -x /sbin/mkcramfs ]; then
621 echo "/sbin/mkcramfs is missing" 1>&2
626 echo "Filesystem $INITRDFS on initrd is not supported" 1>&2
631 if [ -n "$img_vers" ]; then
632 target="$target-$kernel"
635 if [ -z "$force" -a -f "$target" ]; then
636 echo "$target already exists." 1>&2
640 if [ ! -d "/lib/modules/$kernel" ]; then
641 echo "/lib/modules/$kernel is not a directory." 1>&2
645 for n in $PREMODS; do
649 # allow forcing loading SCSI and/or IDE modules
650 if is_yes "$ADDSCSI" ; then
654 if is_yes "$ADDIDE" ; then
660 find_modules_for "$rootdev"
662 findmodule "-$rootFs"
664 for n in $BASICMODULES; do
669 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
670 if [ -n "$verbose" ]; then
671 echo "No modules are needed -- not building initrd image."
676 if [ -n "$verbose" ]; then
677 echo "Using modules: $MODULES"
680 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
681 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
682 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
683 RCFILE="$MNTIMAGE/linuxrc"
685 if [ -f "$MNTIMAGE" ]; then
686 echo "$MNTIMAGE already exists. Remove it and try again" 1>&2
690 if [ -f "$IMAGE" ]; then
691 echo "$IMAGE already exists. Remove it and try again" 1>&2
695 if [ "$INITRDFS" = "ext2" ] ; then
696 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
698 # We have to "echo y |" so that it doesn't complain about $IMAGE not
699 # being a block device
700 echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
703 mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
709 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
712 # We don't need this directory, so let's save space
713 rm -rf "$MNTPOINT"/lost+found
715 for MODULE in $MODULES; do
716 MODULEDIR="`my_dirname "$MODULE"`"
717 mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
718 cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
719 gunzip "$MNTIMAGE/lib/modules/$kernel/$MODULE" 2> /dev/null
722 # mknod'ing the devices instead of copying them works both with and
724 mknod "$MNTIMAGE/dev/console" c 5 1
726 s="$MNTIMAGE/etc/startup"
728 if [ -f /sbin/bsp-raidless ] ; then
729 inst /sbin/bsp-raidless "$RCFILE"
731 inst /sbin/bsp "$RCFILE"
734 if is_yes "$USEINSMODSTATIC" ; then
735 inst "$INSMOD" $MNTIMAGE/bin/insmod.static
738 echo "# autogenerated startup" > "$s"
741 for MODULE in $MODULES; do
742 MODULE2="`my_dirname "$MODULE"`"
743 NAME2=`basename "$MODULE" .gz`
744 MODULE2=$MODULE2/$NAME2
745 module="`echo $MODULE | awk -F/ '{ $0=$NF } /'$modext'$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
746 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
748 if [ -n "$verbose" ]; then
749 /bin/echo -n "Loading module $module "
750 if [ -n "$options" ] ; then
751 echo "with options $options."
753 echo "without options."
756 echo "$insmod /lib/modules/$kernel/$MODULE2 $options" >> "$s"
759 # TODO: rewrite for bsp
760 #if [ -n "$loopDev" ]; then
761 # if [ ! -d /initrd ]; then
765 # cp -a "$loopDev" "$MNTIMAGE/dev"
766 # cp -a "$rootdev" "$MNTIMAGE/dev"
767 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
768 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
769 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
770 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
773 if is_yes "$USERAIDSTART" && is_yes "$raidfound" ; then
774 [ -n "$verbose" ] && echo "Adding raidstart to initrd"
775 inst "$raidtab" "$MNTIMAGE/etc/raidtab"
776 # don't use raidless version
777 inst /sbin/bsp "$RCFILE"
779 # needed to determine md-version
780 if [ "$rootdev" != /dev/md0 ] ; then
781 mknod $MNTIMAGE/dev/md0 b 9 0
784 for f in $dev_list $rootdev ; do
785 # mkdir in case of devfs name
786 mkdir -p `my_dirname $f`
787 [ -n "$verbose" ] && echo "copying $f"
788 # this works fine with and without devfs
789 cp -HR $f $MNTIMAGE/$f
792 echo "raidstart $rootdev" >> "$s"
795 if is_yes "$uselvm" ; then
796 [ -n "$verbose" ] && echo "Adding LVM support to initrd"
797 inst /sbin/initrd-lvm $MNTIMAGE/bin/lvm
800 echo "mount none /proc proc" >> "$s"
801 echo "mount none /tmp tmpfs" >> "$s"
802 echo "mount none /dev devfs" >> "$s"
803 echo "lvm vgscan -T" >> "$s"
804 echo "lvm vgchange -T -a y" >> "$s"
805 echo "umount /tmp" >> "$s"
806 echo "umount /proc" >> "$s"
808 #echo "umount /devfs" >> "$s"
813 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
820 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
823 mkcramfs "$MNTPOINT" "$IMAGE"
826 echo "Filesystem $INITRDFS not supported by $0";
829 if is_yes "$COMPRESS" ; then
830 gzip -9 < "$IMAGE" > "$target"
832 cp -a "$IMAGE" "$target"
834 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"