5 # by Jacek Konieczny <jajcus@pld.org.pl>
7 # based on mkinitrd from RedHat
9 RCSID='$Id: geninitrd,v 2.29 2003/08/07 09:10:07 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)
24 # it should be safe to remove scsi_mod from here, but I'm not sure...
25 PRESCSIMODS="-scsi_mod unknown -sd_mod"
26 PREIDEMODS="-ide-probe -ide-probe-mod -ide-disk"
33 modulefile="/etc/modules.conf"
34 raidtab="/etc/raidtab"
40 echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]" 1>&2
41 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" 1>&2
42 echo " [--initrdfs=rom|ext2|cram] [--modules-conf=<modules.conf>]" 1>&2
43 echo " [--with-raidstart] [--without-raidstart] [--with-insmod-static]" 1>&2
44 echo " [--with-mdadm-static]" 2>&1
45 echo " <initrd-image> <kernel-version>" 1>&2
46 echo " (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" 1>&2
52 echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
56 typeset mods module f level depfile first
58 depfile=/lib/modules/$kernel/modules.dep
60 if [ -f $depfile ] ; then
63 echo "Error: no $depfile ! Run depmod and rerun geninitrd." 1>&2
67 # prepend / if no path given, append $modext.gz if not given,
70 module=$(echo "$2" | \
71 awk '/\// {print;next} {print "/" $0}' | \
72 awk '/\./ {print;next} {print $0 "'$modext'.gz"}' |
73 awk '{gsub("/","\\/");print}')
76 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
78 /(.*)/ { gsub(/\\/," "); if (here) print }
82 if [ "$mods" = "" ] ; then
83 module=$(echo "$module" | \
84 awk '{gsub("\'$modext'\.gz$","\'$modext'",$0);print}')
88 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
90 /(.*)/ { gsub(/\\/," "); if (here) print }
93 if [ "$mods" = "" ] ; then
94 if [ "$1" != silent ] ; then
95 echo "$origmodule: module not found in $depfile" 1>&2
97 if ! is_no "$EXIT_IF_MISSING" ; then
100 echo "If $origmodule isn't compiled in kernel then this initrd may not start your system". 1>&2
105 if [ "$level" = "" ] ; then
108 level=$(awk "BEGIN{print $level + 1}")
109 if [ $level -gt 20 ] ; then
110 echo "$origmodule: cycle in $depfile" 1>&2
116 if [ "$first" = "" ] ; then
119 find_depmod $1 $f $level
130 if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
131 if [ -n "$skiperrors" ]; then
135 echo "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)" 1>&2
139 # only need to add each module once
141 tmpFmPath=$(echo $fmPath | awk '{gsub(/\//,"\\/");print}')
142 if echo "$MODULES" | awk '/'"$tmpFmPath"'/ {exit 1}' ; then
143 MODULES="$MODULES $fmPath"
151 if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
153 modName="$(echo $modName | awk '{print(substr($0,2));}')"
157 if [ "$modName" = "pluto" ]; then
161 if [ "$modName" = "fcal" ]; then
166 if [ -n "$skiperrors" ]; then
167 allModulesToFind=`find_depmod silent $modName`
169 allModulesToFind=`find_depmod normal $modName`
170 if [ $? != 0 ] ; then
175 for mod in $allModulesToFind ; do
177 awk '{sub(/^\/lib\/modules\/[^\/]*\//,"");print}')
178 addmodule $mod "$skiperrors"
183 if [ "$#" != "2" ];then
184 echo "usage: inst <file> <destination>"
187 [ -n "$verbose" ] && echo "$1 -> $2"
192 /sbin/e2label $1 2> /dev/null
196 /sbin/tune2fs -l $1 2> /dev/null | awk -F: '/UUID:/ {gsub(" ",""); print $2}'
200 /usr/sbin/xfs_db -x -p xfs_admin -c label -r "$1"|awk -F= '{sub("^\"","", $2); sub("\"$", "", $2); print $2}'
205 /usr/sbin/xfs_db -x -p xfs_admin -c uuid -r "$1"|awk -F= '{print $2}'
209 eval `awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab`
212 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
213 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
214 if [ -n "$rootdev2" ] ; then
219 if [ "$rootdev_found." != "1." ] ; then
222 if [ ! -x /sbin/e2label ] ; then
223 echo "/sbin/e2label is missing" 1>&2
226 get_label="get_label_ext2"
229 if [ ! -x /usr/sbin/xfs_db ] ; then
230 echo "/usr/sbin/xfs_db is missing" 1>&2
233 get_label="get_label_xfs"
236 echo "LABEL on $rootFs in not supported by geninitrd" 1>&2
240 if [ ! -r /proc/partitions ] ; then
241 echo '/proc/partitions is not readable'; 1>&2
244 label=${rootdev#"LABEL="}
245 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
246 if [ -r $dev ] && [ "$label" = "`$get_label $dev`" ] ; then
247 if [ -n "$verbose" ] ; then
248 echo "Using $dev as device for rootfs"
255 if [ "$rootdev_found." != "1." ] ; then
256 echo "geninitrd can't find real device for LABEL=$label" 1>&2
262 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
263 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
264 if [ -n "$rootdev2" ] ; then
269 if [ "$rootdev_found." != "1." ] ; then
272 if [ ! -x /sbin/tune2fs ] ; then
273 echo "/sbin/tune2fs is missing" 1>&2
276 get_uuid="get_uuid_ext2"
279 if [ ! -x /usr/sbin/xfs_db ] ; then
280 echo "/usr/sbin/xfs_db is missing" 1>&2
283 get_label="get_uuid_xfs"
286 echo "UUID on $rootFs in not supported by geninitrd" 1>&2
290 if [ ! -r /proc/partitions ] ; then
291 echo '/proc/partitions is not readable'; 1>&2
294 uuid=${rootdev#"UUID="}
295 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
296 if [ -r $dev ] && [ "$uuid" = "`$get_uuid $dev`" ] ; then
297 if [ -n "$verbose" ] ; then
298 echo "Using $dev as device for rootfs"
305 if [ "$rootdev_found" != 1 ] ; then
306 echo "geninitrd can't find real device for UUID=$uuid" 1>&2
315 find_modules_softraid() {
316 eval `awk -v rootdev="$1" 'BEGIN {
331 if (found == "yes") {
336 if (found == "yes") {
337 if ($1 == "device") {
338 dev_list = dev_list " " $2;
340 if ($1 == "raid-level") {
347 print "raidfound=" found "\nraidlevel=" raidlevel "\ndev_list=\"" dev_list "\"\n";
349 if is_yes "$raidfound" ; then
352 findmodule "raid$raidlevel"
358 echo "raid level $number (in $raidtab) not recognized" 1>&2
362 for device in $dev_list; do
363 find_modules_for $device
367 find_modules_scsi() {
368 for n in $PRESCSIMODS; do
369 if [ "X$n" = "Xunknown" ] ; then
370 if [ ! -f "$modulefile" ]; then
371 modulefile=/etc/conf.modules
373 if [ -f "$modulefile" ]; then
374 scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
375 for n in $scsimodules; do
376 # for now allow scsi modules to come from anywhere. There are some
377 # RAID controllers with drivers in block
388 for n in $PREIDEMODS; do
394 if is_yes "`echo "$1" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
395 find_modules_softraid "$1"
396 elif is_yes "$(echo "$1" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
398 elif is_yes "`echo "$1" | awk '/^\/dev\/(hd|ide|ataraid)/ { print "yes"; }'`" ; then
400 elif is_yes "`echo "$1" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
402 elif is_yes "`echo "$1" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
403 findmodule "cpqarray"
404 elif is_yes "`echo "$1" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
406 elif is_yes "`echo "$1" | awk '/\/dev\/ataraid\// { print "yes"; }'`"; then
408 ataraidmodules="`awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
409 if -n "$ataraidmodules" ; then
410 # FIXME: think about modules compiled in kernel
411 echo "ERROR: ataraid_hostadapter alias not defined in $modulefile !"
412 echo "Please set it and run $0 again."
415 for n in $ataraidmodules; do
418 # check to see if we need to set up a loopback filesystem
419 elif is_yes "`echo "$1" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
420 echo "Sorry, root on loop device isn't supported." 1>&2
422 # TODO: rewrite for bsp and make nfs ready
423 if [ ! -x /sbin/losetup ]; then
424 echo "losetup is missing"
427 key="^# $(echo $1 | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
428 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
429 echo "The root filesystem is on a $1, but there is no magic entry in $fstab" 1>&2
430 echo "for this device. Consult the geninitrd man page for more information" 1>&2
434 line="`awk '/'$key'/ { print $0; }' $fstab`"
435 loopDev="$(echo $line | awk '{print $3}')"
436 loopFs="$(echo $line | awk '{print $4}')"
437 loopFile="$(echo $line | awk '{print $5}')"
439 BASICMODULES="$BASICMODULES -loop"
440 findmodule "-$loopFs"
441 BASICMODULES="$BASICMODULES -${loopFs}"
442 # don't have any clue, how is this supposed to work
443 elif ls -l "$1"|awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'; then
444 if [ ! -f /sbin/initrd-lvm ] ; then
445 echo "ERROR: root on LVM but /sbin/initrd-lvm not found."
446 echo "Please install lvm-initrd package and rerun $0."
449 if [ -n "$PVDEVICES" ] ; then
450 for device in $PVDEVICES; do
451 find_modules_for $device
454 echo "ERROR: Sorry, but searching for PV isn't implemented yet."
455 echo "Use PVDEVICES in /etc/sysconfig/geninitrd to set it."
459 findmodule "-lvm-mod"
464 if [ -r /etc/sysconfig/geninitrd ] ; then
465 . /etc/sysconfig/geninitrd
468 if [ "x" = "x$INITRDFS" ] ; then
469 if [ "x" = "x$FS" ] ; then
473 echo "Warning: FS configuration options is obsoleted. Use INITRDFS instead" 1>&2
478 if [ ! -x /sbin/bsp ] ; then
479 echo "/sbin/bsp is missing !"
482 if [ "`uname -m`" = "ia64" ]; then
487 while [ $# -gt 0 ]; do
490 fstab="`echo $1 | awk -F= '{print $2;}'`"
497 modulefile="`echo $1 | awk -F= '{print $2;}'`"
504 raidtab="`echo $1 | awk -F= '{print $2;}'`"
510 --use-raidstart|--with-raidstart)
516 --use-mdadm-static|--with-mdadm-static)
519 --use-insmod-static|--with-insmod-static)
520 USEINSMODSTATIC="yes"
522 --without-insmod-static)
526 BASICMODULES="$BASICMODULES `echo $1 | awk -F= '{print $2;}'`"
529 BASICMODULES="$BASICMODULES $2"
533 echo "geninitrd: version $VERSION"
549 PREMODS="$PREMODS `echo $1 | awk -F= '{print $2;}'`"
552 PREMODS="$PREMODS $2"
556 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
557 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
560 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
565 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
575 if [ -z "$target" ]; then
577 elif [ -z "$kernel" ]; then
588 if [ -z "$target" -o -z "$kernel" ]; then
592 pack_version="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d",$1,$2)}'`"
594 if [ "$pack_version" -ge "002005" ] ; then
599 if is_yes "$USEINSMODSTATIC" ; then
600 insmod="insmod.static"
601 INSMOD="/sbin/insmod.static"
602 if [ "$pack_version" -lt "002005" -a -f /sbin/insmod.static.modutils ] ; then
603 INSMOD="/sbin/insmod.static.modutils"
605 if [ ! -f "$INSMOD" ] ; then
606 echo "insmod.static requested but /sbin/insmod.static not found !" >&2
613 if [ ! -x /sbin/mke2fs ]; then
614 echo "/sbin/mke2fs is missing" 1>&2
619 if [ ! -x /sbin/genromfs ]; then
620 echo "/sbin/genromfs is missing" 1>&2
625 if [ ! -x /sbin/mkcramfs ]; then
626 echo "/sbin/mkcramfs is missing" 1>&2
631 echo "Filesystem $INITRDFS on initrd is not supported" 1>&2
636 if [ -n "$img_vers" ]; then
637 target="$target-$kernel"
640 if [ -z "$force" -a -f "$target" ]; then
641 echo "$target already exists." 1>&2
645 if [ ! -d "/lib/modules/$kernel" ]; then
646 echo "/lib/modules/$kernel is not a directory." 1>&2
650 for n in $PREMODS; do
654 # allow forcing loading SCSI and/or IDE modules
655 if is_yes "$ADDSCSI" ; then
659 if is_yes "$ADDIDE" ; then
665 find_modules_for "$rootdev"
667 findmodule "-$rootFs"
669 for n in $BASICMODULES; do
674 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
675 if [ -n "$verbose" ]; then
676 echo "No modules are needed -- not building initrd image."
681 if [ -n "$verbose" ]; then
682 echo "Using modules: $MODULES"
685 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
686 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
687 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
688 RCFILE="$MNTIMAGE/linuxrc"
690 if [ -f "$MNTIMAGE" ]; then
691 echo "$MNTIMAGE already exists. Remove it and try again" 1>&2
695 if [ -f "$IMAGE" ]; then
696 echo "$IMAGE already exists. Remove it and try again" 1>&2
700 if [ "$INITRDFS" = "ext2" ] ; then
701 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
703 # We have to "echo y |" so that it doesn't complain about $IMAGE not
704 # being a block device
705 echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
708 mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
714 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
717 # We don't need this directory, so let's save space
718 rm -rf "$MNTPOINT"/lost+found
720 for MODULE in $MODULES; do
721 MODULEDIR="`my_dirname "$MODULE"`"
722 mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
723 cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
724 gunzip "$MNTIMAGE/lib/modules/$kernel/$MODULE" 2> /dev/null
727 # mknod'ing the devices instead of copying them works both with and
729 mknod "$MNTIMAGE/dev/console" c 5 1
731 s="$MNTIMAGE/etc/startup"
733 if [ -f /sbin/bsp-raidless ] ; then
734 inst /sbin/bsp-raidless "$RCFILE"
736 inst /sbin/bsp "$RCFILE"
739 if is_yes "$USEINSMODSTATIC" ; then
740 inst "$INSMOD" $MNTIMAGE/bin/insmod.static
743 echo "# autogenerated startup" > "$s"
746 for MODULE in $MODULES; do
747 MODULE2="`my_dirname "$MODULE"`"
748 NAME2=`basename "$MODULE" .gz`
749 MODULE2=$MODULE2/$NAME2
750 module="`echo $MODULE | awk -F/ '{ $0=$NF } /'$modext'$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
751 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
753 if [ -n "$verbose" ]; then
754 /bin/echo -n "Loading module $module "
755 if [ -n "$options" ] ; then
756 echo "with options $options."
758 echo "without options."
761 echo "$insmod /lib/modules/$kernel/$MODULE2 $options" >> "$s"
764 # TODO: rewrite for bsp
765 #if [ -n "$loopDev" ]; then
766 # if [ ! -d /initrd ]; then
770 # cp -a "$loopDev" "$MNTIMAGE/dev"
771 # cp -a "$rootdev" "$MNTIMAGE/dev"
772 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
773 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
774 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
775 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
778 if is_yes "$USERAIDSTART" && is_yes "$raidfound" ; then
779 if is_yes "$USEMDADMSTATIC" ; then
780 [ -n "$verbose" ] && echo "Setting up mdadm"
781 inst /sbin/initrd-mdadm "$MNTIMAGE/bin/mdadm"
782 echo "mdadm --assemble $rootdev $dev_list" >> "$s"
784 [ -n "$verbose" ] && echo "Adding raidstart to initrd"
785 inst "$raidtab" "$MNTIMAGE/etc/raidtab"
786 # don't use raidless version
787 inst /sbin/bsp "$RCFILE"
788 echo "raidstart $rootdev" >> "$s"
791 # needed to determine md-version
792 if [ "$rootdev" != /dev/md0 ] ; then
793 mknod $MNTIMAGE/dev/md0 b 9 0
796 for f in $dev_list $rootdev ; do
797 # mkdir in case of devfs name
798 mkdir -p `my_dirname $f`
799 [ -n "$verbose" ] && echo "copying $f"
800 # this works fine with and without devfs
801 cp -HR $f $MNTIMAGE/$f
805 if is_yes "$uselvm" ; then
806 [ -n "$verbose" ] && echo "Adding LVM support to initrd"
807 inst /sbin/initrd-lvm $MNTIMAGE/bin/lvm
810 echo "mount none /proc proc" >> "$s"
811 echo "mount none /tmp tmpfs" >> "$s"
812 echo "mount none /dev devfs" >> "$s"
813 echo "lvm vgscan -T" >> "$s"
814 echo "lvm vgchange -T -a y" >> "$s"
815 echo "umount /tmp" >> "$s"
816 echo "umount /proc" >> "$s"
818 #echo "umount /devfs" >> "$s"
823 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
830 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
833 mkcramfs "$MNTPOINT" "$IMAGE"
836 echo "Filesystem $INITRDFS not supported by $0";
839 if is_yes "$COMPRESS" ; then
840 gzip -9 < "$IMAGE" > "$target"
842 cp -a "$IMAGE" "$target"
844 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"