]> git.ipfire.org Git - thirdparty/dracut.git/blobdiff - mkinitrd-dracut.sh
dracut_mkdir(): create parent directories as needed.
[thirdparty/dracut.git] / mkinitrd-dracut.sh
old mode 100644 (file)
new mode 100755 (executable)
index 59333a7..82d9068
 #!/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) ;;
@@ -106,45 +144,83 @@ while [ $# -gt 0 ]; do
         --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