| #!/bin/sh |
| # |
| # $Id$ |
| # initrd builder for network booting |
| |
| # Utility function to determine whether or not a filesystem is usable for |
| # loopback mounts. Lifted verbatim from Erik Troan's mkinitrd script. |
| # |
| is_good_fs() { |
| local parttype= tmpname= |
| local dir=$1 |
| [[ -d $dir ]] || return 1 |
| [[ -w $dir ]] || return 1 |
| [[ $dir == */ ]] && dir=${dir%/} |
| parttype=$(awk "{if (\$2 == \""$dir"\") print \$3 }" /proc/mounts) |
| |
| while tmpname=${dir%/*} && [[ -z $parttype ]];do |
| [[ -z $tmpname ]] && tmpname=/ |
| parttype=$(awk "{if (\$2 == \""$tmpname"\") print \$3 }" /proc/mounts) |
| dir=$tmpname |
| done |
| |
| case $parttype in |
| nfs|tmpfs) return 1;; |
| *) return 0; |
| esac |
| } |
| |
| # Find a suitable temporary directory (i.e. not tmpfs or nfs) |
| if is_good_fs $TMPDIR; then |
| tmpdir=$TMPDIR |
| elif is_good_fs /tmp; then |
| tmpdir=/tmp |
| elif is_good_fs /var/tmp; then |
| tmpdir=/var/tmp |
| elif is_good_fs /root/tmp; then |
| tmpdir=/root/tmp |
| else |
| echo "Cannot use a tmp directory" >&2 |
| exit 1 |
| fi |
| |
| # Default settings (some can be overridden by command-line options) |
| include_modules=include-modules |
| initrd_skel=/usr/lib/mkinitrd-net/initrd-skel |
| kernel_ver=`uname -r` |
| use_sudo=y |
| keep=n |
| output_dir=/var/lib/tftpboot |
| make_link=y |
| quiet= |
| |
| # No need to use sudo if we are root |
| if [ $UID -eq 0 ]; then |
| use_sudo=n |
| fi |
| |
| USAGE="Usage: $0 [-k|--kernel <kernel_ver>] [-n|--nolink] [-q|--quiet] [-l|--local] [--nosudo] [--keep] [--help] module_list ..." |
| |
| # Parse command-line options |
| while [ $# -gt 0 ]; do |
| case "$1" in |
| -l|--local) |
| shift |
| use_local=y ;; |
| -k|--kernel) |
| shift |
| kernel_ver=$1 |
| shift ;; |
| --nosudo) shift ; use_sudo=n ;; |
| --keep) shift ; keep=y ;; |
| --n|--nolink) |
| shift ; make_link=n ;; |
| -q|--quiet) shift ; quiet=-q ;; |
| --help) shift ; do_help=y ;; |
| --) shift ; break ;; |
| -*) echo "${0}: ${1}: invalid option" >&2 |
| echo $USAGE >& 2 |
| exit 2 ;; |
| *) break ;; |
| esac |
| done |
| |
| # Build list of requested modules |
| modules="$*" |
| requested_modules="$modules" |
| modules="$modules nfs" # Always require nfs for nfs mount |
| modules="$modules af_packet" # Always require af_packet for udhcpc |
| |
| # --help => Print help message |
| if [ "$do_help" == "y" ]; then |
| echo $USAGE |
| echo " -k, --kernel Specify kernel version" |
| echo " -n, --nolink Do not create a matching symbolic link" |
| echo " -l, --local Run locally from CVS (for developers only)" |
| echo " --nosudo Do not use sudo (i.e. must run as root instead)" |
| echo " --keep Keep temporary files instead of deleting them" |
| exit 0; |
| fi |
| |
| # --local => we are running directly from CVS, rather than |
| # from an installed copy, so use local files and directories |
| if [ "$use_local" == "y" ]; then |
| include_modules=./include-modules |
| initrd_skel=initrd-skel |
| output_dir=tftpboot |
| fi |
| |
| # If use_sudo is set, check that sudo exists |
| sudo=/usr/bin/sudo |
| if [ "$use_sudo" == "y" ]; then |
| if [ ! -x $sudo ]; then |
| use_sudo=n |
| echo "WARNING: --nosudo not specified but $sudo not found" |
| fi |
| fi |
| if [ "$use_sudo" == "n" ]; then |
| sudo= |
| fi |
| |
| # Create temporary working files |
| initrd=`mktemp -d ${tmpdir}/initrd.XXXXXX` |
| initrdimg=`mktemp ${tmpdir}/initrd.img.XXXXXX` |
| initrdmnt=`mktemp -d ${tmpdir}/initrd.mnt.XXXXXX` |
| |
| # Copy skeleton into temporary area |
| cp -a $initrd_skel/* $initrd/ |
| mkdir -p $initrd/lib/modules/$kernel_ver |
| $include_modules $quiet -k $kernel_ver -d $initrd/lib/modules/$kernel_ver $modules > $initrd/bin/insert-modules || exit 1 |
| chmod 755 $initrd/bin/insert-modules |
| |
| # Create empty ext2fs image file |
| dd if=/dev/zero bs=1k of=$initrdimg count=$((`du -sk $initrd | cut -f1` * 7 / 6)) 2> /dev/null |
| /sbin/mke2fs -q -F $initrdimg 2> /dev/null |
| |
| # Mount image file, copy files on, create /dev entries, display free space, umount |
| $sudo mount -o loop $initrdimg $initrdmnt |
| cp -a $initrd/* $initrdmnt/ |
| $sudo mknod $initrdmnt/dev/console c 5 1 |
| $sudo mknod $initrdmnt/dev/null c 1 3 |
| $sudo mknod $initrdmnt/dev/ram b 1 1 |
| $sudo mknod $initrdmnt/dev/systty c 4 0 |
| for i in 1 2 3 4; do $sudo mknod $initrdmnt/dev/tty$i c 4 $i; done |
| if [ "$quiet" == "n" ]; then |
| df -h $initrdmnt |
| fi |
| $sudo umount $initrdmnt |
| |
| # Create output file |
| initrd_suffix=`echo $requested_modules | tr " " .` |
| gzip -9 -n -c $initrdimg > $output_dir/initrd-$initrd_suffix.$kernel_ver.img |
| |
| # Create symlink |
| if [ "$make_link" == "y" ]; then |
| link=$output_dir/initrd-$initrd_suffix.img |
| [ -L $link ] && rm -f $link |
| ln -s initrd-$initrd_suffix.$kernel_ver.img $link |
| fi |
| |
| # Remove temporary files |
| if [ "$keep" == "n" ]; then |
| rm -rf $initrd |
| rm -f $initrdimg |
| rmdir $initrdmnt |
| fi |