#! /bin/sh # Copyright (C) 2003, 2004 Alexandre Oliva # Add the modules in a driver disk to the set available to the # anaconda loader in Fedora Core install images. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to the # Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # The first argument must be the name of the directory containing: # modules.cgz, a gzipped cpio file in crc format containing the # modules named e.g. 2.6.5-1.358/i586/*.ko. Other files typically # found in driver disks, such as modinfo, modules.dep, modules.pcimap, # pcitable, may also be present in the directory, and their contents # will be merged with those in the built-in modules list. # The remaining arguments name .iso or .img files that contain the # modules directory to be updated. The supported file names are: # - initrd*.img: a gzipped initrd filesystem image. # - bootdisk.img: an uncompressed vfat filesystem containing initrd.img. # - *.iso: an ISO filesystem, that must contain isolinux/initrd.img # and, optionally, images/pxeboot/initrd.img and # dosutils/autoboot/initrd.img (assumed to be the same as # isolinux/initrd.img), images/bootdisk.img, images/boot.iso and # images/rescuecd.iso. # If the second argument is a .iso filename, the files listed above # will be extracted from it into the current directory. Then, the # modules directory will be updated in them (which in turn extracts # initrd-bootdisk.img from bootdisk.img), and finally the .iso image # will be reconstructed with the updated files. # No file is modified in-place; the `.new' suffix is appended to the # basename of the original file, and the new files are always created # in the current directory. For convenience, the script also creates # xdelta files between the original and the modified binaries, if the # XDELTA environment variable is set to xdelta. # For example, run as root: # ./add-modules /path/to/driver-disk FC2-i386-disc1.iso # This will create not only FC2-i386-disc1.iso.new, but also # initrd.img.new, boot.iso.new. In case you have a rescue cd, just # add rescuecd.iso to the command line, and you'll get # rescuecd.iso.new. # Note that it *must* be run as root, because it has to loopback-mount # filesystems. case $# in 0) echo usage: `basename $0` modules-dir '[disc1.iso] [initrd.img] [rescuecd.iso] [boot.iso]' ... >&2 exit 1 ;; esac : ${XDELTA=:} set -e moddir=$1 if test ! -d "$moddir" || test ! -f "$moddir"/modules.cgz; then echo $moddir does not exist >&2 exit 1 fi shift case $1 in *.iso) file=$1 if isoinfo -R -J -i "$file" -x /images/rescuecd.iso > rescuecd.iso.new && test -s rescuecd.iso.new; then ln rescuecd.iso.new rescuecd.iso rm rescuecd.iso.new set fnord rescuecd.iso ${1+"$@"}; shift else rm -f rescuecd.iso.new fi if isoinfo -R -J -i "$file" -x /images/boot.iso > boot.iso.new && test -s boot.iso.new; then ln boot.iso.new boot.iso rm boot.iso.new set fnord boot.iso ${1+"$@"}; shift else rm -f boot.iso.new fi if isoinfo -R -J -i "$file" -x /images/bootdisk.img > bootdisk.img.new && test -s bootdisk.img.new; then ln bootdisk.img.new bootdisk.img rm bootdisk.img.new set fnord bootdisk.img ${1+"$@"}; shift else rm -f bootdisk.img.new fi if isoinfo -R -J -i "$file" -x /isolinux/initrd.img > initrd.img.new && test -s initrd.img.new; then ln initrd.img.new initrd.img rm initrd.img.new set fnord initrd.img ${1+"$@"}; shift else rm -f initrd.img.new fi ;; esac : ${INITRDSIZE=7000} MNT=${TMPDIR-/tmp}/mnt.$$ mkdir $MNT $MNT2 trap "umount -d $MNT/mount || :; rm -rf $MNT || :; echo failed >&2; exit 1" 0 1 2 15 while test $# != 0; do base=`basename "$1"` file=$base.new case $base in initrd*.img) gunzip < "$1" > "$file".unzip mkdir $MNT/mount $MNT/explode mount -o loop "$file".unzip $MNT/mount rsync -av --delete $MNT/mount/ $MNT/explode/ umount -d $MNT/mount echo "updating initrd:modules/modules.cgz" >&2 mkdir $MNT/drivers zcat $MNT/explode/modules/modules.cgz | (cd $MNT/drivers && cpio -i --make-directories) zcat "$moddir"/modules.cgz | (cd $MNT/drivers && cpio -i --make-directories) (cd $MNT/drivers && find * | cpio -o -H crc) | gzip -9 > $MNT/explode/modules/modules.cgz rm -rf $MNT/drivers if test -f "$moddir"/modinfo && test -f $MNT/explode/modules/module-info; then dirinfover=`sed 1q "$moddir"/modinfo` && mntinfover=`sed 1q $MNT/explode/modules/module-info` && if test "x$dirinfover" = "x$mntinfover"; then echo "updating initrd:modules/module-info from modinfo" >&2 sed 1d "$moddir"/modinfo >> $MNT/explode/modules/module-info else echo "module info files have different versions, not merging" >&2 fi fi for f in modules.dep modules.pcimap pcitable; do if test -f "$moddir"/$f && test -f $MNT/explode/modules/$f; then echo "updating initrd:modules/$f from $f" >&2 cat "$moddir"/$f >> $MNT/explode/modules/$f fi done dd if=/dev/zero of="$file".unzip.new bs=1k count=$INITRDSIZE mke2fs -F -i 1024 "$file".unzip.new $INITRDSIZE tune2fs -c 0 -i 0 "$file".unzip.new mount -o loop "$file".unzip.new $MNT/mount rsync -av $MNT/explode/ $MNT/mount/ umount -d $MNT/mount rmdir $MNT/mount rm -rf $MNT/explode gzip -9 < "$file".unzip.new > "$file" rm -f "$file".unzip "$file".unzip.new ${XDELTA} delta -9 "$1" "$file" "$file".xdelta || : ;; # there's no bootdisk.img in FC2 # bootdisk.img) # if test -f "$file" && test -f initrd-bootdisk.img.new; then # mount -o loop "$file" $MNT # cp initrd-bootdisk.img.new $MNT/initrd.img # umount -d $MNT # ${XDELTA} delta -9 "$1" "$file" "$file".xdelta || : # else # cp "$1" "$file" # mount -o loop,ro "$file" $MNT # cp $MNT/initrd.img initrd-bootdisk.img # umount -d $MNT # shift # set fnord initrd-bootdisk.img $1 ${1+"$@"} # fi # ;; *.iso) if test ! -f initrd.img.new; then echo cannot process "$1" before initrd.img, skipping >&2 continue fi mkdir $MNT/explode $MNT/mount mount -o loop,ro "$1" $MNT/mount rsync -av --delete $MNT/mount/ $MNT/explode/ --exclude=TRANS.TBL umount -d $MNT/mount cp initrd.img.new $MNT/explode/isolinux/initrd.img if test -f $MNT/explode/images/pxeboot/initrd.img; then ln -f $MNT/explode/isolinux/initrd.img \ $MNT/explode/images/pxeboot/initrd.img fi if test -f $MNT/explode/dosutils/autoboot/initrd.img; then ln -f $MNT/explode/isolinux/initrd.img \ $MNT/explode/dosutils/autoboot/initrd.img fi if test -f $MNT/explode/images/boot.iso && test -f boot.iso.new; then cp boot.iso.new $MNT/explode/images/boot.iso fi if test -f $MNT/explode/images/bootdisk.img && test -f bootdisk.img.new; then cp bootdisk.img.new $MNT/explode/images/bootdisk.img fi mkisofs -o "$file" -b isolinux/isolinux.bin -c isolinux/boot.cat \ -no-emul-boot -boot-load-size 4 -boot-info-table -R -J -v -T \ $MNT/explode rm -rf $MNT/explode rmdir $MNT/mount if test -x /usr/lib/anaconda-runtime/implantisomd5; then /usr/lib/anaconda-runtime/implantisomd5 "$file" else echo missing anaconda-runtime, not adding md5 hash to $file >&2 fi ${XDELTA} delta -9 "$1" "$file" "$file".xdelta || : esac shift done rmdir $MNT trap : 0 1 2 15 exit 0