#!/bin/bash --norc
+kver=$(uname -r)
-error() {
- local NONL=""
- if [ "$1" == "-n" ]; then
- NONL="-n"
- shift
- fi
- echo $NONL "$@" > /dev/stderr
-}
+boot_dir="/boot"
+quiet=0
+host_only=0
+force=0
+
+error() { echo "$@" >&2; }
usage () {
- if [ "$1" == "-n" ]; then
- cmd=echo
- else
- cmd=error
- fi
+ [[ $1 = '-n' ]] && cmd=echo || cmd=error
- $cmd "usage: `basename $0` [--version] [--help] [-v] [-f] [--preload <module>]"
+ $cmd "usage: ${0##*/} [--version] [--help] [-v] [-f] [--preload <module>]"
$cmd " [--image-version] [--with=<module>]"
+ $cmd " [--nocompress]"
$cmd " <initrd-image> <kernel-version>"
$cmd ""
- $cmd " (ex: `basename $0` /boot/initramfs-$(uname -r).img $(uname -r))"
+ $cmd " (ex: ${0##*/} /boot/initramfs-$kver.img $kver)"
- if [ "$1" == "-n" ]; then
- exit 0
- else
- exit 1
- fi
+ [[ $1 = '-n' ]] && exit 0
+ exit 1
}
-
-while [ $# -gt 0 ]; do
- case $1 in
- --with-usb*)
- if [ "$1" != "${1##--with-usb=}" ]; then
- usbmodule=${1##--with-usb=}
- else
- usbmodule="usb-storage"
- fi
- basicmodules="$basicmodules $usbmodule"
- unset usbmodule
- ;;
- --with-avail*)
- if [ "$1" != "${1##--with-avail=}" ]; then
- modname=${1##--with-avail=}
- else
- modname=$2
- shift
+# Little helper function for reading args from the commandline.
+# it automatically handles -a b and -a=b variants, and returns 1 if
+# we need to shift $3.
+read_arg() {
+ # $1 = arg name
+ # $2 = arg value
+ # $3 = arg parameter
+ param="$1"
+ local rematch='^[^=]*=(.*)$' result
+ if [[ $2 =~ $rematch ]]; then
+ read "$param" <<< "${BASH_REMATCH[1]}"
+ else
+ for ((i=3; $i <= $#; i++)); do
+ # Only read next arg if it not an arg itself.
+ if [[ ${@:$i:1} = -* ]];then
+ break
fi
+ result="$result ${@:$i:1}"
+ # There is no way to shift our callers args, so
+ # return "no of args" to indicate they should do it instead.
+ done
+ read "$1" <<< "$result"
+ return $(($i - 3))
+ fi
+}
- basicmodules="$basicmodules $modname"
- ;;
- --with*)
- if [ "$1" != "${1##--with=}" ]; then
- modname=${1##--with=}
- else
- modname=$2
- shift
- fi
+# Taken over from SUSE mkinitrd
+default_kernel_images() {
+ local regex kernel_image kernel_version version_version initrd_image
+ local qf='%{NAME}-%{VERSION}-%{RELEASE}\n'
- basicmodules="$basicmodules $modname"
+ case "${DRACUT_ARCH:-$(uname -m)}" in
+ s390|s390x)
+ regex='image'
;;
- --version)
- echo "mkinitrd: dracut compatibility wrapper"
- exit 0
+ ppc|ppc64)
+ regex='vmlinux'
;;
- -v|--verbose)
- dracut_args="${dracut_args} -v"
+ i386|x86_64)
+ regex='vmlinuz'
;;
- -f)
- dracut_args="${dracut_args} -f"
+ arm*)
+ regex='[uz]Image'
;;
- --preload*)
- if [ "$1" != "${1##--preload=}" ]; then
- modname=${1##--preload=}
- else
- modname=$2
- shift
- fi
- basicmodules="$basicmodules $modname"
+ aarch64|riscv64)
+ regex='Image'
;;
- --image-version)
- img_vers=yes
+ *) regex='vmlinu.'
;;
- --rootfs*)
- if [ "$1" != "${1##--rootfs=}" ]; then
- rootfs="${1##--rootfs=}"
- else
- rootfs="$2"
- shift
- fi
- dracut_args="${dracut_args} --filesystems $rootfs"
- ;;
- --builtin*) ;;
+ esac
+
+ # user mode linux
+ if grep -q UML /proc/cpuinfo; then
+ regex='linux'
+ fi
+
+ kernel_images=""
+ initrd_images=""
+ for kernel_image in $(ls $boot_dir \
+ | sed -ne "\|^$regex\(-[0-9.]\+-[0-9]\+-[a-z0-9]\+$\)\?|p" \
+ | grep -v kdump$ ) ; 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_dir/$kernel_image" ] && continue
+ [ "${kernel_image%%.gz}" != "$kernel_image" ] && continue
+ kernel_version=$(/usr/bin/get_kernel_version \
+ $boot_dir/$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_dir/$kernel_image"
+ initrd_images="$initrd_images $boot_dir/$initrd_image"
+ fi
+ done
+ for kernel_image in $kernel_images;do
+ kernels="$kernels ${kernel_image#*-}"
+ done
+ for initrd_image in $initrd_images;do
+ targets="$targets $initrd_image"
+ done
+ host_only=1
+ force=1
+}
+
+while (($# > 0)); do
+ case ${1%%=*} in
+ --with-usb) read_arg usbmodule "$@" || shift $?
+ basicmodules="$basicmodules ${usbmodule:-usb-storage}"
+ unset usbmodule;;
+ --with-avail) read_arg modname "$@" || shift $?
+ basicmodules="$basicmodules $modname";;
+ --with) read_arg modname "$@" || shift $?
+ basicmodules="$basicmodules $modname";;
+ --version)
+ echo "mkinitrd: dracut compatibility wrapper"
+ exit 0;;
+ -v|--verbose) dracut_args="${dracut_args} -v";;
+ -f|--force) force=1;;
+ --preload) read_arg modname "$@" || shift $?
+ basicmodules="$basicmodules $modname";;
+ --image-version) img_vers=yes;;
+ --rootfs|-d) read_arg rootfs "$@" || shift $?
+ dracut_args="${dracut_args} --filesystems $rootfs";;
+ --nocompress) dracut_args="$dracut_args --no-compress";;
+ --help) usage -n;;
+ --builtin) ;;
--without*) ;;
--without-usb) ;;
--fstab*) ;;
- --nocompress) dracut_args="$dracut_args --no-compress";;
--ifneeded) ;;
--omit-scsi-modules) ;;
--omit-ide-modules) ;;
--allow-missing) ;;
--net-dev*) ;;
--noresume) ;;
- --rootdev*) ;;
- --thawdev*) ;;
- --rootopts*) ;;
- --root*) ;;
- --loopdev*) ;;
- --loopfs*) ;;
- --loopopts*) ;;
- --looppath*) ;;
- --dsdt*) ;;
+ --rootdev*) ;;
+ --thawdev*) ;;
+ --rootopts*) ;;
+ --root*) ;;
+ --loopdev*) ;;
+ --loopfs*) ;;
+ --loopopts*) ;;
+ --looppath*) ;;
+ --dsdt*) ;;
--bootchart) ;;
- --help)
- usage -n
- ;;
- *)
- if [ -z "$target" ]; then
- target=$1
- elif [ -z "$kernel" ]; then
- kernel=$1
+ -s) ;;
+ --quiet|-q) quiet=1;;
+ -b) read_arg boot_dir "$@" || shift $?
+ if [ ! -d $boot_dir ];then
+ error "Boot directory $boot_dir does not exist"
+ exit 1
+ fi
+ ;;
+ -k) # Would be nice to get a list of images here
+ read_arg kernel_images "$@" || shift $?
+ for kernel_image in $kernel_images;do
+ kernels="$kernels ${kernel_image#*-}"
+ done
+ host_only=1
+ force=1
+ ;;
+ -i) read_arg initrd_images "$@" || shift $?
+ for initrd_image in $initrd_images;do
+ targets="$targets $boot_dir/$initrd_image"
+ done
+ ;;
+ *) if [[ ! $targets ]]; then
+ targets=$1
+ elif [[ ! $kernels ]]; then
+ kernels=$1
else
- usage
- fi
- ;;
+ usage
+ fi;;
esac
-
shift
done
-if [ -z "$target" -o -z "$kernel" ]; then
- usage
-fi
+[[ $targets && $kernels ]] || default_kernel_images
+[[ $targets && $kernels ]] || (error "No kernel found in $boot_dir" && usage)
+
+# We can have several targets/kernels, transform the list to an array
+targets=( $targets )
+[[ $kernels ]] && kernels=( $kernels )
-if [ -n "$img_vers" ]; then
- target="$target-$kernel"
-fi
+[[ $host_only == 1 ]] && dracut_args="${dracut_args} -H"
+[[ $force == 1 ]] && dracut_args="${dracut_args} -f"
-if [ -n "$basicmodules" ]; then
- dracut -H $dracut_args --add-drivers "$basicmodules" "$target" "$kernel"
-else
- dracut -H $dracut_args "$target" "$kernel"
-fi
+echo "Creating: target|kernel|dracut args|basicmodules "
+for ((i=0 ; $i<${#targets[@]} ; i++)); do
-# vim:ts=8:sw=4:sts=4:et
+ if [[ $img_vers ]];then
+ target="${targets[$i]}-${kernels[$i]}"
+ else
+ target="${targets[$i]}"
+ fi
+ kernel="${kernels[$i]}"
+
+ # Duplicate code: No way found how to redirect output based on $quiet
+ if [[ $quiet == 1 ]];then
+ echo "$target|$kernel|$dracut_args|$basicmodules"
+ if [[ $basicmodules ]]; then
+ dracut $dracut_args --add-drivers "$basicmodules" "$target" \
+ "$kernel" &>/dev/null
+ else
+ dracut $dracut_args "$target" "$kernel" &>/dev/null
+ fi
+ else
+ if [[ $basicmodules ]]; then
+ dracut $dracut_args --add-drivers "$basicmodules" "$target" \
+ "$kernel"
+ else
+ dracut $dracut_args "$target" "$kernel"
+ fi
+ fi
+done