5 # by Jacek Konieczny <jajcus@pld.org.pl>
7 # based on mkinitrd from RedHat
9 RCSID='$Id: geninitrd,v 2.25 2003/02/19 08:49:26 wiget Exp $'
13 VERSION="`echo "$RCSID"|awk '{print $3}'`"
15 . /etc/rc.d/init.d/functions
18 # INITRDFS is set later (catch obsoleted FS option)
22 # it should be safe to remove scsi_mod from here, but I'm not sure...
23 PRESCSIMODS="-scsi_mod unknown -sd_mod"
24 PREIDEMODS="-ide-probe -ide-probe-mod -ide-disk"
31 modulefile="/etc/modules.conf"
32 raidtab="/etc/raidtab"
38 echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]" 1>&2
39 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" 1>&2
40 echo " [--initrdfs=rom|ext2|cram] [--modules-conf=<modules.conf>]" 1>&2
41 echo " [--with-raidstart] [--without-raidstart]" 1>&2
42 echo " <initrd-image> <kernel-version>" 1>&2
43 echo " (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" 1>&2
49 echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
53 typeset mods module f level depfile first
55 depfile=/lib/modules/$kernel/modules.dep
57 if test -f $depfile ; then
60 echo "Error: no $depfile ! Run depmod and rerun geninitrd." 1>&2
64 # prepend / if no path given, append $modext.gz if not given,
67 module=$(echo "$2" | \
68 awk '/\// {print;next} {print "/" $0}' | \
69 awk '/\./ {print;next} {print $0 "'$modext'.gz"}' |
70 awk '{gsub("/","\\/");print}')
73 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
75 /(.*)/ { gsub(/\\/," "); if (here) print }
79 if [ "$mods" = "" ] ; then
80 module=$(echo "$module" | \
81 awk '{gsub("\'$modext'\.gz$","\'$modext'",$0);print}')
85 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
87 /(.*)/ { gsub(/\\/," "); if (here) print }
90 if [ "$mods" = "" ] ; then
91 if [ "$1" != silent ] ; then
92 echo "$origmodule: module not found in $depfile" 1>&2
94 if ! is_no "$EXIT_IF_MISSING" ; then
97 echo "If $origmodule isn't compiled in kernel then this initrd may not start your system". 1>&2
102 if [ "$level" = "" ] ; then
105 level=$(awk "BEGIN{print $level + 1}")
106 if [ $level -gt 20 ] ; then
107 echo "$origmodule: cycle in $depfile" 1>&2
113 if [ "$first" = "" ] ; then
116 find_depmod $1 $f $level
127 if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
128 if [ -n "$skiperrors" ]; then
132 echo "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)" 1>&2
136 # only need to add each module once
138 tmpFmPath=$(echo $fmPath | awk '{gsub(/\//,"\\/");print}')
139 if echo "$MODULES" | awk '/'"$tmpFmPath"'/ {exit 1}' ; then
140 MODULES="$MODULES $fmPath"
148 if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
150 modName="$(echo $modName | awk '{print(substr($0,2));}')"
154 if [ "$modName" = "pluto" ]; then
158 if [ "$modName" = "fcal" ]; then
163 if [ -n "$skiperrors" ]; then
164 allModulesToFind=`find_depmod silent $modName`
166 allModulesToFind=`find_depmod normal $modName`
167 if [ $? != 0 ] ; then
172 for mod in $allModulesToFind ; do
174 awk '{sub(/^\/lib\/modules\/[^\/]*\//,"");print}')
175 addmodule $mod "$skiperrors"
180 if [ "$#" != "2" ];then
181 echo "usage: inst <file> <destination>"
184 [ -n "$verbose" ] && echo "$1 -> $2"
189 /sbin/e2label $1 2> /dev/null
193 /sbin/tune2fs -l $1 2> /dev/null | awk -F: '/UUID:/ {gsub(" ",""); print $2}'
197 /usr/sbin/xfs_db -x -p xfs_admin -c label -r "$1"|awk -F= '{sub("^\"","", $2); sub("\"$", "", $2); print $2}'
202 /usr/sbin/xfs_db -x -p xfs_admin -c uuid -r "$1"|awk -F= '{print $2}'
206 eval `awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab`
209 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
210 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
211 if [ -n "$rootdev2" ] ; then
216 if [ "$rootdev_found." != "1." ] ; then
219 if [ ! -x /sbin/e2label ] ; then
220 echo "/sbin/e2label is missing" 1>&2
223 get_label="get_label_ext2"
226 if [ ! -x /usr/sbin/xfs_db ] ; then
227 echo "/usr/sbin/xfs_db is missing" 1>&2
230 get_label="get_label_xfs"
233 echo "LABEL on $rootFs in not supported by geninitrd" 1>&2
237 if [ ! -r /proc/partitions ] ; then
238 echo '/proc/partitions is not readable'; 1>&2
241 label=${rootdev#"LABEL="}
242 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
243 if [ -r $dev ] && [ "$label" = "`$get_label $dev`" ] ; then
244 if [ -n "$verbose" ] ; then
245 echo "Using $dev as device for rootfs"
252 if [ "$rootdev_found." != "1." ] ; then
253 echo "geninitrd can't find real device for LABEL=$label" 1>&2
259 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
260 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
261 if [ -n "$rootdev2" ] ; then
266 if [ "$rootdev_found." != "1." ] ; then
269 if [ ! -x /sbin/tune2fs ] ; then
270 echo "/sbin/tune2fs is missing" 1>&2
273 get_uuid="get_uuid_ext2"
276 if [ ! -x /usr/sbin/xfs_db ] ; then
277 echo "/usr/sbin/xfs_db is missing" 1>&2
280 get_label="get_uuid_xfs"
283 echo "UUID on $rootFs in not supported by geninitrd" 1>&2
287 if [ ! -r /proc/partitions ] ; then
288 echo '/proc/partitions is not readable'; 1>&2
291 uuid=${rootdev#"UUID="}
292 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
293 if [ -r $dev ] && [ "$uuid" = "`$get_uuid $dev`" ] ; then
294 if [ -n "$verbose" ] ; then
295 echo "Using $dev as device for rootfs"
302 if [ "$rootdev_found" != 1 ] ; then
303 echo "geninitrd can't find real device for UUID=$uuid" 1>&2
312 find_modules_softraid() {
313 eval `awk -v rootdev="$1" 'BEGIN {
328 if (found == "yes") {
333 if (found == "yes") {
334 if ($1 == "device") {
335 dev_list = dev_list " " $2;
337 if ($1 == "raid-level") {
344 print "raidfound=" found "\nraidlevel=" raidlevel "\ndev_list=\"" dev_list "\"\n";
346 if is_yes "$raidfound" ; then
349 findmodule "raid$raidlevel"
355 echo "raid level $number (in $raidtab) not recognized" 1>&2
359 for device in $dev_list; do
360 find_modules_for $device
364 find_modules_scsi() {
365 for n in $PRESCSIMODS; do
366 if [ "X$n" = "Xunknown" ] ; then
367 if [ ! -f "$modulefile" ]; then
368 modulefile=/etc/conf.modules
370 if [ -f "$modulefile" ]; then
371 scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
372 for n in $scsimodules; do
373 # for now allow scsi modules to come from anywhere. There are some
374 # RAID controllers with drivers in block
385 for n in $PREIDEMODS; do
391 if is_yes "`echo "$1" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
392 find_modules_softraid "$1"
393 elif is_yes "$(echo "$1" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
395 elif is_yes "`echo "$1" | awk '/^\/dev\/(hd|ide|ataraid)/ { print "yes"; }'`" ; then
397 elif is_yes "`echo "$1" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
399 elif is_yes "`echo "$1" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
400 findmodule "cpqarray"
401 elif is_yes "`echo "$1" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
403 elif is_yes "`echo "$1" | awk '/\/dev\/ataraid\// { print "yes"; }'`"; then
405 ataraidmodules="`awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
406 if -n "$ataraidmodules" ; then
407 # FIXME: think about modules compiled in kernel
408 echo "ERROR: ataraid_hostadapter alias not defined in $modulefile !"
409 echo "Please set it and run $0 again."
412 for n in $ataraidmodules; do
415 # check to see if we need to set up a loopback filesystem
416 elif is_yes "`echo "$1" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
417 echo "Sorry, root on loop device isn't supported." 1>&2
419 # TODO: rewrite for bsp and make nfs ready
420 if [ ! -x /sbin/losetup ]; then
421 echo "losetup is missing"
424 key="^# $(echo $1 | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
425 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
426 echo "The root filesystem is on a $1, but there is no magic entry in $fstab" 1>&2
427 echo "for this device. Consult the geninitrd man page for more information" 1>&2
431 line="`awk '/'$key'/ { print $0; }' $fstab`"
432 loopDev="$(echo $line | awk '{print $3}')"
433 loopFs="$(echo $line | awk '{print $4}')"
434 loopFile="$(echo $line | awk '{print $5}')"
436 BASICMODULES="$BASICMODULES -loop"
437 findmodule "-$loopFs"
438 BASICMODULES="$BASICMODULES -${loopFs}"
439 # don't have any clue, how is this supposed to work
440 elif ls -l "$1"|awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'; then
441 if [ ! -f /sbin/initrd-lvm ] ; then
442 echo "ERROR: root on LVM but /sbin/initrd-lvm not found."
443 echo "Please install lvm-initrd package and rerun $0."
446 if [ -n "$PVDEVICES" ] ; then
447 for device in $PVDEVICES; do
448 find_modules_for $device
451 echo "ERROR: Sorry, but searching for PV isn't implemented yet."
452 echo "Use PVDEVICES in /etc/sysconfig/geninitrd to set it."
456 findmodule "-lvm-mod"
461 if [ -r /etc/sysconfig/geninitrd ] ; then
462 . /etc/sysconfig/geninitrd
465 if [ "x" = "x$INITRDFS" ] ; then
466 if [ "x" = "x$FS" ] ; then
470 echo "Warning: FS configuration options is obsoleted. Use INITRDFS instead" 1>&2
475 if [ ! -x /sbin/bsp ] ; then
476 echo "/sbin/bsp is missing !"
479 if [ "`uname -m`" = "ia64" ]; then
484 while [ $# -gt 0 ]; do
487 fstab="`echo $1 | awk -F= '{print $2;}'`"
494 modulefile="`echo $1 | awk -F= '{print $2;}'`"
501 raidtab="`echo $1 | awk -F= '{print $2;}'`"
507 --use-raidstart|--with-raidstart)
514 BASICMODULES="$BASICMODULES `echo $1 | awk -F= '{print $2;}'`"
517 BASICMODULES="$BASICMODULES $2"
521 echo "geninitrd: version $VERSION"
537 PREMODS="$PREMODS `echo $1 | awk -F= '{print $2;}'`"
540 PREMODS="$PREMODS $2"
544 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
545 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
548 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
553 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
563 if [ -z "$target" ]; then
565 elif [ -z "$kernel" ]; then
576 if [ -z "$target" -o -z "$kernel" ]; then
580 pack_version="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d",$1,$2)}'`"
582 if [ "$pack_version" -ge "002005" ] ; then
589 if [ ! -x /sbin/mke2fs ]; then
590 echo "/sbin/mke2fs is missing" 1>&2
595 if [ ! -x /sbin/genromfs ]; then
596 echo "/sbin/genromfs is missing" 1>&2
601 if [ ! -x /sbin/mkcramfs ]; then
602 echo "/sbin/mkcramfs is missing" 1>&2
607 echo "Filesystem $INITRDFS on initrd is not supported" 1>&2
612 if [ -n "$img_vers" ]; then
613 target="$target-$kernel"
616 if [ -z "$force" -a -f "$target" ]; then
617 echo "$target already exists." 1>&2
621 if [ ! -d "/lib/modules/$kernel" ]; then
622 echo "/lib/modules/$kernel is not a directory." 1>&2
626 for n in $PREMODS; do
630 # allow forcing loading SCSI and/or IDE modules
631 if is_yes "$ADDSCSI" ; then
635 if is_yes "$ADDIDE" ; then
641 find_modules_for "$rootdev"
643 findmodule "-$rootFs"
645 for n in $BASICMODULES; do
650 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
651 if [ -n "$verbose" ]; then
652 echo "No modules are needed -- not building initrd image."
657 if [ -n "$verbose" ]; then
658 echo "Using modules: $MODULES"
661 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
662 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
663 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
664 RCFILE="$MNTIMAGE/linuxrc"
666 if [ -f "$MNTIMAGE" ]; then
667 echo "$MNTIMAGE already exists. Remove it and try again" 1>&2
671 if [ -f "$IMAGE" ]; then
672 echo "$IMAGE already exists. Remove it and try again" 1>&2
676 if [ "$INITRDFS" = "ext2" ] ; then
677 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
679 # We have to "echo y |" so that it doesn't complain about $IMAGE not
680 # being a block device
681 echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
684 mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
690 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
693 # We don't need this directory, so let's save space
694 rm -rf "$MNTPOINT"/lost+found
696 for MODULE in $MODULES; do
697 MODULEDIR="`my_dirname "$MODULE"`"
698 mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
699 cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
700 gunzip "$MNTIMAGE/lib/modules/$kernel/$MODULE" 2> /dev/null
703 # mknod'ing the devices instead of copying them works both with and
705 mknod "$MNTIMAGE/dev/console" c 5 1
707 s="$MNTIMAGE/etc/startup"
709 if test -f /sbin/bsp-raidless ; then
710 inst /sbin/bsp-raidless "$RCFILE"
712 inst /sbin/bsp "$RCFILE"
715 echo "# autogenerated startup" > "$s"
718 for MODULE in $MODULES; do
719 MODULE2="`my_dirname "$MODULE"`"
720 NAME2=`basename "$MODULE" .gz`
721 MODULE2=$MODULE2/$NAME2
722 module="`echo $MODULE | awk -F/ '{ $0=$NF } /'$modext'$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
723 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
725 if [ -n "$verbose" ]; then
726 /bin/echo -n "Loading module $module "
727 if [ -n "$options" ] ; then
728 echo "with options $options."
730 echo "without options."
733 echo "$insmod /lib/modules/$kernel/$MODULE2 $options" >> "$s"
736 # TODO: rewrite for bsp
737 #if [ -n "$loopDev" ]; then
738 # if [ ! -d /initrd ]; then
742 # cp -a "$loopDev" "$MNTIMAGE/dev"
743 # cp -a "$rootdev" "$MNTIMAGE/dev"
744 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
745 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
746 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
747 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
750 if is_yes "$USERAIDSTART" && is_yes "$raidfound" ; then
751 [ -n "$verbose" ] && echo "Adding raidstart to initrd"
752 inst "$raidtab" "$MNTIMAGE/etc/raidtab"
753 # don't use raidless version
754 inst /sbin/bsp "$RCFILE"
756 # needed to determine md-version
757 if [ "$rootdev" != /dev/md0 ] ; then
758 mknod $MNTIMAGE/dev/md0 b 9 0
761 for f in $dev_list $rootdev ; do
762 # mkdir in case of devfs name
763 mkdir -p `my_dirname $f`
764 [ -n "$verbose" ] && echo "copying $f"
765 # this works fine with and without devfs
766 cp -HR $f $MNTIMAGE/$f
769 echo "raidstart $rootdev" >> "$s"
772 if is_yes "$uselvm" ; then
773 [ -n "$verbose" ] && echo "Adding LVM support to initrd"
774 inst /sbin/initrd-lvm $MNTIMAGE/bin/lvm
777 echo "mount none /proc proc" >> "$s"
778 echo "mount none /tmp tmpfs" >> "$s"
779 echo "mount none /dev devfs" >> "$s"
780 echo "lvm vgscan -T" >> "$s"
781 echo "lvm vgchange -T -a y" >> "$s"
782 echo "umount /tmp" >> "$s"
783 echo "umount /proc" >> "$s"
785 #echo "umount /devfs" >> "$s"
790 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
797 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
800 mkcramfs "$MNTPOINT" "$IMAGE"
803 echo "Filesystem $INITRDFS not supported by $0";
806 if is_yes "$COMPRESS" ; then
807 gzip -9 < "$IMAGE" > "$target"
809 cp -a "$IMAGE" "$target"
811 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"