5 # by Jacek Konieczny <jajcus@pld.org.pl>
7 # based on mkinitrd from RedHat
9 RCSID='$Id: geninitrd,v 2.24 2002/11/27 17:56:24 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"
36 echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]" 1>&2
37 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" 1>&2
38 echo " [--initrdfs=rom|ext2|cram] [--modules-conf=<modules.conf>]" 1>&2
39 echo " [--with-raidstart] [--without-raidstart]" 1>&2
40 echo " <initrd-image> <kernel-version>" 1>&2
41 echo " (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" 1>&2
47 echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
51 typeset mods module f level depfile first
53 depfile=/lib/modules/$kernel/modules.dep
55 if test -f $depfile ; then
58 echo "Error: no $depfile ! Run depmod and rerun geninitrd." 1>&2
62 # prepend / if no path given, append .o.gz if not given,
65 module=$(echo "$2" | \
66 awk '/\// {print;next} {print "/" $0}' | \
67 awk '/\./ {print;next} {print $0 ".o.gz"}' |
68 awk '{gsub("/","\\/");print}')
71 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
73 /(.*)/ { gsub(/\\/," "); if (here) print }
77 if [ "$mods" = "" ] ; then
78 module=$(echo "$module" | \
79 awk '{gsub("\.o\.gz$","\.o",$0);print}')
83 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
85 /(.*)/ { gsub(/\\/," "); if (here) print }
88 if [ "$mods" = "" ] ; then
89 if [ "$1" != silent ] ; then
90 echo "$origmodule: module not found in $depfile" 1>&2
92 if ! is_no "$EXIT_IF_MISSING" ; then
95 echo "If $origmodule isn't compiled in kernel then this initrd may not start your system". 1>&2
100 if [ "$level" = "" ] ; then
103 level=$(awk "BEGIN{print $level + 1}")
104 if [ $level -gt 20 ] ; then
105 echo "$origmodule: cycle in $depfile" 1>&2
111 if [ "$first" = "" ] ; then
114 find_depmod $1 $f $level
125 if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
126 if [ -n "$skiperrors" ]; then
130 echo "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)" 1>&2
134 # only need to add each module once
136 tmpFmPath=$(echo $fmPath | awk '{gsub(/\//,"\\/");print}')
137 if echo "$MODULES" | awk '/'"$tmpFmPath"'/ {exit 1}' ; then
138 MODULES="$MODULES $fmPath"
146 if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
148 modName="$(echo $modName | awk '{print(substr($0,2));}')"
152 if [ "$modName" = "pluto" ]; then
156 if [ "$modName" = "fcal" ]; then
161 if [ -n "$skiperrors" ]; then
162 allModulesToFind=`find_depmod silent $modName`
164 allModulesToFind=`find_depmod normal $modName`
165 if [ $? != 0 ] ; then
170 for mod in $allModulesToFind ; do
172 awk '{sub(/^\/lib\/modules\/[^\/]*\//,"");print}')
173 addmodule $mod "$skiperrors"
178 if [ "$#" != "2" ];then
179 echo "usage: inst <file> <destination>"
182 [ -n "$verbose" ] && echo "$1 -> $2"
187 /sbin/e2label $1 2> /dev/null
191 /sbin/tune2fs -l $1 2> /dev/null | awk -F: '/UUID:/ {gsub(" ",""); print $2}'
195 /usr/sbin/xfs_db -x -p xfs_admin -c label -r "$1"|awk -F= '{sub("^\"","", $2); sub("\"$", "", $2); print $2}'
200 /usr/sbin/xfs_db -x -p xfs_admin -c uuid -r "$1"|awk -F= '{print $2}'
204 eval `awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab`
207 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
208 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
209 if [ -n "$rootdev2" ] ; then
214 if [ "$rootdev_found." != "1." ] ; then
217 if [ ! -x /sbin/e2label ] ; then
218 echo "/sbin/e2label is missing" 1>&2
221 get_label="get_label_ext2"
224 if [ ! -x /usr/sbin/xfs_db ] ; then
225 echo "/usr/sbin/xfs_db is missing" 1>&2
228 get_label="get_label_xfs"
231 echo "LABEL on $rootFs in not supported by geninitrd" 1>&2
235 if [ ! -r /proc/partitions ] ; then
236 echo '/proc/partitions is not readable'; 1>&2
239 label=${rootdev#"LABEL="}
240 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
241 if [ -r $dev ] && [ "$label" = "`$get_label $dev`" ] ; then
242 if [ -n "$verbose" ] ; then
243 echo "Using $dev as device for rootfs"
250 if [ "$rootdev_found." != "1." ] ; then
251 echo "geninitrd can't find real device for LABEL=$label" 1>&2
257 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
258 rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
259 if [ -n "$rootdev2" ] ; then
264 if [ "$rootdev_found." != "1." ] ; then
267 if [ ! -x /sbin/tune2fs ] ; then
268 echo "/sbin/tune2fs is missing" 1>&2
271 get_uuid="get_uuid_ext2"
274 if [ ! -x /usr/sbin/xfs_db ] ; then
275 echo "/usr/sbin/xfs_db is missing" 1>&2
278 get_label="get_uuid_xfs"
281 echo "UUID on $rootFs in not supported by geninitrd" 1>&2
285 if [ ! -r /proc/partitions ] ; then
286 echo '/proc/partitions is not readable'; 1>&2
289 uuid=${rootdev#"UUID="}
290 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
291 if [ -r $dev ] && [ "$uuid" = "`$get_uuid $dev`" ] ; then
292 if [ -n "$verbose" ] ; then
293 echo "Using $dev as device for rootfs"
300 if [ "$rootdev_found" != 1 ] ; then
301 echo "geninitrd can't find real device for UUID=$uuid" 1>&2
310 find_modules_softraid() {
311 eval `awk -v rootdev="$1" 'BEGIN {
326 if (found == "yes") {
331 if (found == "yes") {
332 if ($1 == "device") {
333 dev_list = dev_list " " $2;
335 if ($1 == "raid-level") {
342 print "raidfound=" found "\nraidlevel=" raidlevel "\ndev_list=\"" dev_list "\"\n";
344 if is_yes "$raidfound" ; then
347 findmodule "raid$raidlevel"
353 echo "raid level $number (in $raidtab) not recognized" 1>&2
357 for device in $dev_list; do
358 find_modules_for $device
362 find_modules_scsi() {
363 for n in $PRESCSIMODS; do
364 if [ "X$n" = "Xunknown" ] ; then
365 if [ ! -f "$modulefile" ]; then
366 modulefile=/etc/conf.modules
368 if [ -f "$modulefile" ]; then
369 scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
370 for n in $scsimodules; do
371 # for now allow scsi modules to come from anywhere. There are some
372 # RAID controllers with drivers in block
383 for n in $PREIDEMODS; do
389 if is_yes "`echo "$1" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
390 find_modules_softraid "$1"
391 elif is_yes "$(echo "$1" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
393 elif is_yes "`echo "$1" | awk '/^\/dev\/(hd|ide|ataraid)/ { print "yes"; }'`" ; then
395 elif is_yes "`echo "$1" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
397 elif is_yes "`echo "$1" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
398 findmodule "cpqarray"
399 elif is_yes "`echo "$1" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
401 elif is_yes "`echo "$1" | awk '/\/dev\/ataraid\// { print "yes"; }'`"; then
403 ataraidmodules="`awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
404 if -n "$ataraidmodules" ; then
405 # FIXME: think about modules compiled in kernel
406 echo "ERROR: ataraid_hostadapter alias not defined in $modulefile !"
407 echo "Please set it and run $0 again."
410 for n in $ataraidmodules; do
413 # check to see if we need to set up a loopback filesystem
414 elif is_yes "`echo "$1" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
415 echo "Sorry, root on loop device isn't supported." 1>&2
417 # TODO: rewrite for bsp and make nfs ready
418 if [ ! -x /sbin/losetup ]; then
419 echo "losetup is missing"
422 key="^# $(echo $1 | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
423 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
424 echo "The root filesystem is on a $1, but there is no magic entry in $fstab" 1>&2
425 echo "for this device. Consult the geninitrd man page for more information" 1>&2
429 line="`awk '/'$key'/ { print $0; }' $fstab`"
430 loopDev="$(echo $line | awk '{print $3}')"
431 loopFs="$(echo $line | awk '{print $4}')"
432 loopFile="$(echo $line | awk '{print $5}')"
434 BASICMODULES="$BASICMODULES -loop"
435 findmodule "-$loopFs"
436 BASICMODULES="$BASICMODULES -${loopFs}"
437 # don't have any clue, how is this supposed to work
438 elif ls -l "$1"|awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'; then
439 if [ ! -f /sbin/initrd-lvm ] ; then
440 echo "ERROR: root on LVM but /sbin/initrd-lvm not found."
441 echo "Please install lvm-initrd package and rerun $0."
444 if [ -n "$PVDEVICES" ] ; then
445 for device in $PVDEVICES; do
446 find_modules_for $device
449 echo "ERROR: Sorry, but searching for PV isn't implemented yet."
450 echo "Use PVDEVICES in /etc/sysconfig/geninitrd to set it."
454 findmodule "-lvm-mod"
459 if [ -r /etc/sysconfig/geninitrd ] ; then
460 . /etc/sysconfig/geninitrd
463 if [ "x" = "x$INITRDFS" ] ; then
464 if [ "x" = "x$FS" ] ; then
468 echo "Warning: FS configuration options is obsoleted. Use INITRDFS instead" 1>&2
473 if [ ! -x /sbin/bsp ] ; then
474 echo "/sbin/bsp is missing !"
477 if [ "`uname -m`" = "ia64" ]; then
482 while [ $# -gt 0 ]; do
485 fstab="`echo $1 | awk -F= '{print $2;}'`"
492 modulefile="`echo $1 | awk -F= '{print $2;}'`"
499 raidtab="`echo $1 | awk -F= '{print $2;}'`"
505 --use-raidstart|--with-raidstart)
512 BASICMODULES="$BASICMODULES `echo $1 | awk -F= '{print $2;}'`"
515 BASICMODULES="$BASICMODULES $2"
519 echo "geninitrd: version $VERSION"
535 PREMODS="$PREMODS `echo $1 | awk -F= '{print $2;}'`"
538 PREMODS="$PREMODS $2"
542 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
543 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
546 echo "Warning: --fs option is obsoleted. Use --initrdfs instead" 1>&2
551 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
561 if [ -z "$target" ]; then
563 elif [ -z "$kernel" ]; then
574 if [ -z "$target" -o -z "$kernel" ]; then
580 if [ ! -x /sbin/mke2fs ]; then
581 echo "/sbin/mke2fs is missing" 1>&2
586 if [ ! -x /sbin/genromfs ]; then
587 echo "/sbin/genromfs is missing" 1>&2
592 if [ ! -x /sbin/mkcramfs ]; then
593 echo "/sbin/mkcramfs is missing" 1>&2
598 echo "Filesystem $INITRDFS on initrd is not supported" 1>&2
603 if [ -n "$img_vers" ]; then
604 target="$target-$kernel"
607 if [ -z "$force" -a -f "$target" ]; then
608 echo "$target already exists." 1>&2
612 if [ ! -d "/lib/modules/$kernel" ]; then
613 echo "/lib/modules/$kernel is not a directory." 1>&2
617 for n in $PREMODS; do
621 # allow forcing loading SCSI and/or IDE modules
622 if is_yes "$ADDSCSI" ; then
626 if is_yes "$ADDIDE" ; then
632 find_modules_for "$rootdev"
634 findmodule "-$rootFs"
636 for n in $BASICMODULES; do
641 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
642 if [ -n "$verbose" ]; then
643 echo "No modules are needed -- not building initrd image."
648 if [ -n "$verbose" ]; then
649 echo "Using modules: $MODULES"
652 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
653 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
654 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
655 RCFILE="$MNTIMAGE/linuxrc"
657 if [ -f "$MNTIMAGE" ]; then
658 echo "$MNTIMAGE already exists. Remove it and try again" 1>&2
662 if [ -f "$IMAGE" ]; then
663 echo "$IMAGE already exists. Remove it and try again" 1>&2
667 if [ "$INITRDFS" = "ext2" ] ; then
668 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
670 # We have to "echo y |" so that it doesn't complain about $IMAGE not
671 # being a block device
672 echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
675 mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
681 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
684 # We don't need this directory, so let's save space
685 rm -rf "$MNTPOINT"/lost+found
687 for MODULE in $MODULES; do
688 MODULEDIR="`my_dirname "$MODULE"`"
689 mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
690 cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
691 gunzip "$MNTIMAGE/lib/modules/$kernel/$MODULE" 2> /dev/null
694 # mknod'ing the devices instead of copying them works both with and
696 mknod "$MNTIMAGE/dev/console" c 5 1
698 s="$MNTIMAGE/etc/startup"
700 if test -f /sbin/bsp-raidless ; then
701 inst /sbin/bsp-raidless "$RCFILE"
703 inst /sbin/bsp "$RCFILE"
706 echo "# autogenerated startup" > "$s"
709 for MODULE in $MODULES; do
710 MODULE2="`my_dirname "$MODULE"`"
711 NAME2=`basename "$MODULE" .gz`
712 MODULE2=$MODULE2/$NAME2
713 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
714 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
716 if [ -n "$verbose" ]; then
717 /bin/echo -n "Loading module $module "
718 if [ -n "$options" ] ; then
719 echo "with options $options."
721 echo "without options."
724 echo "insmod /lib/modules/$kernel/$MODULE2 $options" >> "$s"
727 # TODO: rewrite for bsp
728 #if [ -n "$loopDev" ]; then
729 # if [ ! -d /initrd ]; then
733 # cp -a "$loopDev" "$MNTIMAGE/dev"
734 # cp -a "$rootdev" "$MNTIMAGE/dev"
735 # echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
736 # echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
737 # echo "echo Setting up loopback device $rootdev" >> $RCFILE
738 # echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
741 if is_yes "$USERAIDSTART" && is_yes "$raidfound" ; then
742 [ -n "$verbose" ] && echo "Adding raidstart to initrd"
743 inst "$raidtab" "$MNTIMAGE/etc/raidtab"
744 # don't use raidless version
745 inst /sbin/bsp "$RCFILE"
747 # needed to determine md-version
748 if [ "$rootdev" != /dev/md0 ] ; then
749 mknod $MNTIMAGE/dev/md0 b 9 0
752 for f in $dev_list $rootdev ; do
753 # mkdir in case of devfs name
754 mkdir -p `my_dirname $f`
755 [ -n "$verbose" ] && echo "copying $f"
756 # this works fine with and without devfs
757 cp -HR $f $MNTIMAGE/$f
760 echo "raidstart $rootdev" >> "$s"
763 if is_yes "$uselvm" ; then
764 [ -n "$verbose" ] && echo "Adding LVM support to initrd"
765 inst /sbin/initrd-lvm $MNTIMAGE/bin/lvm
768 echo "mount none /proc proc" >> "$s"
769 echo "mount none /tmp tmpfs" >> "$s"
770 echo "mount none /dev devfs" >> "$s"
771 echo "lvm vgscan -T" >> "$s"
772 echo "lvm vgchange -T -a y" >> "$s"
773 echo "umount /tmp" >> "$s"
774 echo "umount /proc" >> "$s"
775 echo "umount /devfs" >> "$s"
780 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
787 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
790 mkcramfs "$MNTPOINT" "$IMAGE"
793 echo "Filesystem $INITRDFS not supported by $0";
796 if is_yes "$COMPRESS" ; then
797 gzip -9 < "$IMAGE" > "$target"
799 cp -a "$IMAGE" "$target"
801 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"