File cadameb-mkinitrd of Package cadameb

#! /bin/bash

# mkinitrd - create the initramfs images
# usage: see below usage() or call with -h
#
# Copyright (C) 1999-2006 SuSE Linux Products GmbH, Nuernberg, Germany
#
# 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
# of the License, 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; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
# USA.

# This file is kept in the following git repository:
#
# git://git.opensuse.org/projects/mkinitrd.git
#

declare -a cmd_option
declare cmd_option_name cmd_option_desc cmd_option_param cmd_param_desc cmd_param_name

read_options_eval() {
    [ "$#" = 0 ] && return
    for p in "$@"; do
	echo -en "$p~"
    done
}

read_options() {
        egrep -h '%param_' $INITRD_PATH/setup/*.sh | sed 's/^.*_\(.\): \(.*\)$/ tmp_option=\$(read_options_eval \1 \2); [ \"$tmp_option\" ] \&\& cmd_option[\${#cmd_option[@]}]=\"\$tmp_option\"/' > $tmp_dir/$$.params
	. $tmp_dir/$$.params
	rm -f $tmp_dir/$$.params
}

parse_option() {
    OLDIFS="$IFS"
    IFS="~"
    set -- $1
    cmd_option_name="$1"
    cmd_option_desc="$2"
    shift
    shift
    cmd_option_param="$*"
    IFS="$OLDIFS"
}

next_param() {
    OLDIFS="$IFS"
    IFS="~"
    set -- $cmd_option_param
    cmd_param_desc="$1"
    cmd_param_name="$2"
    shift
    shift
    cmd_option_param="$*"
    IFS="$OLDIFS"
    [ "$cmd_param_name" ]
}

cmd_docmd() {
    for i in "${cmd_option[@]}"; do
	if [ "${i%%~*}" = "$1" ]; then
	    parse_option "$i"
	    return 0
	fi
    done
    return 1
}

cmd_getopts() {
    for i in "${cmd_option[@]}"; do
	parse_option "$i"
	echo -n $cmd_option_name
	next_param && echo -n :
    done
}

beautify() {
    if [ "$nroff" ]; then
	nroff -man | grep -v removeme
    else
	cat
    fi
}

[ -x /usr/bin/nroff ] && nroff=1

usage() {

(

if [ "$nroff" ]; then
    cat <<EOF
.TH removeme
.SH MKINITRD
EOF
fi

    cat<<EOF
Create initial ramdisk images that contain all kernel modules needed in the early boot process, before the root file system becomes available. This usually includes SCSI and/or RAID modules, a file system module for the root file system, or a network interface driver module for dhcp.

mkinitrd [options]

EOF

    for i in "${cmd_option[@]}"; do
	parse_option "$i"
	if [ "$nroff" ]; then
	    echo ".TP"
	    echo -n ".B -$cmd_option_name"
	    next_param && echo -n " $cmd_param_desc"
	    echo
	else
	    echo -n "	-$cmd_option_name	"
	    if next_param; then
		echo -n "$cmd_param_desc	"
	    else
		echo -n "	"
	    fi
	fi
	echo "$cmd_option_desc"
    done

) | beautify
    exit
}

default_kernel_images() {
    local regex kernel_image kernel_version version_version initrd_image
    local qf='%{NAME}-%{VERSION}-%{RELEASE}\n'

    case "$(uname -m)" in
	s390|s390x)
	    regex='image'
	    ;;
	ppc|ppc64)
	    regex='vmlinux'
	    ;;
	*)  regex='vmlinu.'
	    ;;
    esac

    # user mode linux
    if grep -q UML /proc/cpuinfo; then
	    regex='linux'
    fi

    kernel_images=""
    initrd_images=""
    for kernel_image in $(ls /boot \
	    | sed -ne "\|^$regex\(-[0-9.]\+-[0-9]\+-[a-z0-9]\+$\)\?|p") ; do

	# Note that we cannot check the RPM database here -- this
	# script is itself called from within the binary kernel
	# packages, and rpm does not allow recursive calls.

	[ -L "/boot/$kernel_image" ] && continue
	[ "${kernel_image%%.gz}" != "$kernel_image" ] && continue
	kernel_version=$(/sbin/get_kernel_version \
			 /boot/$kernel_image 2> /dev/null)
	initrd_image=$(echo $kernel_image | sed -e "s|${regex}|initrd|")
	if [ "$kernel_image" != "$initrd_image" -a \
	     -n "$kernel_version" -a \
	     -d "/lib/modules/$kernel_version" ]; then
		kernel_images="$kernel_images /boot/$kernel_image"
		initrd_images="$initrd_images /boot/$initrd_image"
	fi
    done
}

# You can specify the root device via the environment variable rootdev (e.g.
# "rootdev=/dev/hda mkinitrd").

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# general configurable parameters

kernel_images=
initrd_images=
modules=
modules_set=
domu_modules=
domu_modules_set=
feature_list=
boot_dir=
splash=offbydefault
use_static_binaries=ignored
acpi_dsdt=
use_selinux=
sysmap=
journaldev=
build_day=20081202
build_cmdline="$*"
scan_pci_bus=
create_monster_initrd=
verbose=
INITRD_PATH=/lib/mkinitrd

# read the sysconfig configs
if [ -e "/etc/sysconfig/initrd" ]; then
    . /etc/sysconfig/initrd
fi

read_options
while getopts $( cmd_getopts ) a ; do
    case $a in
	h)  usage
	    exit 0
	    ;;
	*)  if cmd_docmd $a; then
		next_param && eval "$cmd_param_name='$OPTARG'"
		eval param_$a=1
	    else
		exit 1
	    fi
	    ;;
    esac
done
shift $(( $OPTIND - 1 ))

mkinit_name="mkinitramfs"

if [ -n "$1" ]; then
    root_dir=${1%/}  # strip trailing slash
else
    root_dir=
fi

if [ -n "$boot_dir" ]; then
    boot_dir="${boot_dir#/}"
    boot_dir="/${boot_dir%/}"
else
    boot_dir="/boot"
fi
if [ ! -d "$boot_dir" ]; then
    echo "$boot_dir is not a directory" >&2
    exit 1
fi

if [ -n "$tmp_dir" ]; then
    tmp_dir="/${tmp_dir#/}"  # make sure it is an absolute path
else
    tmp_dir=/dev/shm
fi
if [ ! -d "$tmp_dir" ]; then
    echo "$tmp_dir is not a directory" >&2
    exit 1
fi

# Check if the -k and -i settings are valid.
if [ $(set -- $kernel_images ; echo $#) -ne \
     $(set -- $initrd_images ; echo $#) ]; then
    echo "You have to specify -k and -i, or none of both. The -k" \
         "and -i options must each contain the same number of items." >&2
    exit 1
fi

# Mount /usr, required for ldd and other tools to create the initrd tree
mounted_usr=
if [ ! -x /usr/bin/ldd ]; then
  mounted_usr=/usr
  if ! mount -n -v /usr ; then
    echo "/usr/bin/ldd not available and mount /usr failed." \
         "mkinitrd does not work without it." >&2
    exit 1
  fi
fi

# Mount /proc if not already done so
mounted_proc=
if [ ! -e /proc/mounts ]; then
  mounted_proc=/proc
  mount -n -t proc proc $mounted_proc
fi

# And /sys likewise
mounted_sys=
if [ ! -d /sys/devices ] ; then
    mounted_sys=/sys
    mount -n -t sysfs none /sys
fi

if [ -z "$kernel_images" -o -z "$initrd_images" ]; then
    default_kernel_images
fi

initrd_insmod=/sbin/insmod
initrd_modprobe=/sbin/modprobe

# maximum initrd size
image_blocks=40960
image_inodes=2048

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# should be nothing to change below...

PATH=/sbin:/usr/sbin:$PATH

# Fixup old installations
unset CDPATH

work_dir=$(mktemp -qd $tmp_dir/${mkinit_name}.XXXXXX)
if [ $? -ne 0 ]; then
	echo "$0: Can't create temp dir, exiting." >&2
	exit 1
fi

umount_proc() {
    [ "$mounted_proc" ] && umount -n $mounted_proc
    mounted_proc=
    [ "$mounted_sys" ] && umount -n $mounted_sys
    mounted_sys=
    [ "$mounted_usr" ] && umount -v -n $mounted_usr
    mounted_usr=
}

cleanup() {
    rm -f $tmp_initrd $tmp_initrd.gz
    [ -d "$tmp_mnt" ] && rm -rf "$tmp_mnt"
    initrd_bins=()
}

cleanup_finish() {
    umount_proc
    [ -d "$work_dir" ] && rm -rf $work_dir
}

handle_terminate() {
    echo "(received signal)

Interrupted, cleaning up." >&2
    cleanup
    cleanup_finish
    exit 255
}

trap handle_terminate 1 2 3 15

error() {
    touch "$work_dir/error"
    oops "$@"
}

oops() {
    echo "$2" >&2
    cleanup
    exit_code=$1
    exit $1
}

##################################################

# saves an environment variable in the config file of the current script
# usage: save_var <variable name> [default value]
save_var() {
	# sysconfig options override dynamically generated options
	if [ -e "/etc/sysconfig/initrd" ]; then
		local override="$(cat /etc/sysconfig/initrd | egrep \"^$1=\")"
		if [ "$override" ]; then
			eval $override
		fi
	fi
	# only overwrite variables if not defined previously (e.g. by the kernel commandline)
	if [ "$(eval echo \$$1)" ]; then
		echo "[ \"\$$1\" ] || $1='$(eval echo \$$1)'" >> config/$curscript
	elif [ "$2" ]; then
		echo "[ \"\$$1\" ] || $1='$2'" >> config/$curscript
	fi
}

verbose() {
	if [ "$verbose" ] ; then
	    echo -e "$@"
	fi
}

# creates an initrd image using small modules called "setup scripts"
# the actual creation of the initrd is contained within these scripts
mkinitrd_kernel() {
	local kernel_image=$1 initrd_image=$2
	shebang=/bin/bash
	oldpwd="$(pwd)"
	
	for setupfile in $INITRD_PATH/setup/*.sh; do
		[ -d "$tmp_mnt" ] && cd "$tmp_mnt" # process setup files in the initrd root dir
		if [ ! -d "$setupfile" ]; then
		    curscript="${setupfile##*-}"
#		    echo "[$curscript] $blockdev"
		    source $setupfile
		    [ $? -ne 0 ] && oops 1 "Script $setupfile failed!"
		fi
	done
	cd "$oldpwd"
}

###################################################################

# working directories
tmp_initrd=$work_dir/initrd
tmp_initrd_small=${tmp_initrd}_small

###################################################################

exit_code=0

initrd_images=( $initrd_images )
kernel_images=( $kernel_images )

scripts_mtime=$( stat -c "%X" "$INITRD_PATH/scripts" )
setup_mtime=$( stat -c "%X" "$INITRD_PATH/setup" )
boot_mtime=$( stat -c "%X" "$INITRD_PATH/boot" )
if [ "$scripts_mtime" -gt "$setup_mtime" ] || [ "$scripts_mtime" -gt "$boot_mtime" ] ; then
    /sbin/mkinitrd_setup
fi

#boot_modules="$modules"
#echo -e "User-defined Module list:\t$boot_modules ($domu_modules)"
for ((i=0 ; $i<${#kernel_images[@]} ; i++)); do
    ( # start in a subshell so the different mkinitrd build processes
      # don't interfere
    echo
#    modules="$boot_modules"
    kernel_image=${kernel_images[$i]}
    [ ${kernel_image:0:1} != '/' ] \
    	&& kernel_image=$boot_dir/$kernel_image

    initrd_image=${initrd_images[$i]}
    [ ${initrd_image:0:1} != '/' ] \
    	&& initrd_image=$boot_dir/$initrd_image

    mkinitrd_kernel $kernel_image $initrd_image
    [ $? -eq 0 ] || exit 1

    # If the current $kernel_image has a symlink without "-<version>" (e.g.
    # "vmlinuz") pointing to it, and if the name is /boot/initrd-<version> (i.e.
    # without any suffix or prefix), create an "initrd" symlink for the
    # corresponding $initrd_image.
    if [ $exit_code -eq 0 -a "$(readlink ${kernel_image%%-*})" = \
	 "${kernel_image#$boot_dir/}" -a \
         "${initrd_image#$boot_dir/initrd-}" = \
         "${kernel_image#$boot_dir/vmlinu[xz]-}" ]; then
	rm -f $root_dir/$boot_dir/initrd
	ln -s "${initrd_image#$boot_dir/}" $root_dir/$boot_dir/initrd
    fi
    cleanup
    )
    exit_code=$?
    [ -e "$work_dir/error" ] && break
done

cleanup_finish

if [ "$exit_code" -eq 0 ] && [ -x /sbin/update-bootloader ] ; then
    /sbin/update-bootloader --refresh
fi

exit $exit_code