# of the various mkinitrd implementations out there
#
-# Copyright 2005-2010 Red Hat, Inc. All rights reserved.
+# Copyright 2005-2013 Red Hat, Inc. All rights reserved.
#
# 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
#
# store for logging
-dracut_args="$@"
+dracut_args=( "$@" )
set -o pipefail
# 80x25 linebreak here ^
cat << EOF
-Usage: $0 [OPTION]... <initramfs> <kernel-version>
+Usage: $0 [OPTION]... [<initramfs> [<kernel-version>]]
Version: $DRACUT_VERSION
Creates initial ramdisk images for preloading modules
+ -h, --help Display all options
+
+If a [LIST] has multiple arguments, then you have to put these in quotes.
+
+For example:
+
+ # dracut --add-drivers "module1 module2" ...
+
+EOF
+}
+
+long_usage() {
+ [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
+ if [[ -f $dracutbasedir/dracut-version.sh ]]; then
+ . $dracutbasedir/dracut-version.sh
+ fi
+
+# 80x25 linebreak here ^
+ cat << EOF
+Usage: $0 [OPTION]... [<initramfs> [<kernel-version>]]
+
+Version: $DRACUT_VERSION
+
+Creates initial ramdisk images for preloading modules
+
+ --kver [VERSION] Set kernel version to [VERSION].
-f, --force Overwrite existing initramfs file.
+ -a, --add [LIST] Add a space-separated list of dracut modules.
-m, --modules [LIST] Specify a space-separated list of dracut modules to
call when building the initramfs. Modules are located
in /usr/lib/dracut/modules.d.
-o, --omit [LIST] Omit a space-separated list of dracut modules.
- -a, --add [LIST] Add a space-separated list of dracut modules.
+ --force-add [LIST] Force to add a space-separated list of dracut modules
+ to the default set of modules, when -H is specified.
-d, --drivers [LIST] Specify a space-separated list of kernel modules to
- exclusively include in the initramfs.
- --add-drivers [LIST] Specify a space-separated list of kernel
- modules to add to the initramfs.
+ exclusively include in the initramfs.
+ --add-drivers [LIST] Specify a space-separated list of kernel
+ modules to add to the initramfs.
--omit-drivers [LIST] Specify a space-separated list of kernel
- modules not to add to the initramfs.
+ modules not to add to the initramfs.
--filesystems [LIST] Specify a space-separated list of kernel filesystem
- modules to exclusively include in the generic
- initramfs.
+ modules to exclusively include in the generic
+ initramfs.
-k, --kmoddir [DIR] Specify the directory, where to look for kernel
- modules
+ modules
--fwdir [DIR] Specify additional directories, where to look for
- firmwares, separated by :
+ firmwares, separated by :
--kernel-only Only install kernel drivers and firmware files
--no-kernel Do not install kernel drivers and firmware files
+ --early-microcode Combine early microcode with ramdisk
+ --no-early-microcode Do not combine early microcode with ramdisk
+ --kernel-cmdline [PARAMETERS] Specify default kernel command line parameters
--strip Strip binaries in the initramfs
- --nostrip Do not strip binaries in the initramfs (default)
+ --nostrip Do not strip binaries in the initramfs
+ --hardlink Hardlink files in the initramfs
+ --nohardlink Do not hardlink files in the initramfs
--prefix [DIR] Prefix initramfs files with [DIR]
- --noprefix Do not prefix initramfs files (default)
+ --noprefix Do not prefix initramfs files
--mdadmconf Include local /etc/mdadm.conf
--nomdadmconf Do not include local /etc/mdadm.conf
--lvmconf Include local /etc/lvm/lvm.conf
--nolvmconf Do not include local /etc/lvm/lvm.conf
--fscks [LIST] Add a space-separated list of fsck helpers.
--nofscks Inhibit installation of any fsck helpers.
+ --ro-mnt Mount / and /usr read-only by default.
-h, --help This message
--debug Output debug information of the build process
--profile Output profile information of the build process
1 - only fatal errors
2 - all errors
3 - warnings
- 4 - info (default)
+ 4 - info
5 - debug info (here starts lots of output)
6 - trace info (and even more)
- -v, --verbose Increase verbosity level (default is info(4))
- -q, --quiet Decrease verbosity level (default is info(4))
+ -v, --verbose Increase verbosity level
+ -q, --quiet Decrease verbosity level
-c, --conf [FILE] Specify configuration file to use.
Default: /etc/dracut.conf
--confdir [DIR] Specify configuration directory to use *.conf files
Useful when running dracut from a git checkout.
-H, --hostonly Host-Only mode: Install only what is needed for
booting the local host instead of a generic host.
- --no-hostonly Disables Host-Only mode
+ -N, --no-hostonly Disables Host-Only mode
--fstab Use /etc/fstab to determine the root device.
--add-fstab [FILE] Add file to the initramfs fstab
--mount "[DEV] [MP] [FSTYPE] [FSOPTS]"
Mount device [DEV] on mountpoint [MP] with filesystem
[FSTYPE] and options [FSOPTS] in the initramfs
+ --add-device "[DEV]" Bring up [DEV] in initramfs
-i, --include [SOURCE] [TARGET]
Include the files in the SOURCE directory into the
Target directory in the final initramfs.
--sshkey [SSHKEY] Add ssh key to initramfs (use with ssh-client module)
If [LIST] has multiple arguments, then you have to put these in quotes.
+
For example:
-# dracut --add-drivers "module1 module2" ...
+
+ # dracut --add-drivers "module1 module2" ...
+
EOF
}
# example:
# push stack 1 2 "3 4"
push() {
+ local _i
local __stack=$1; shift
- for i in "$@"; do
- eval ${__stack}'[${#'${__stack}'[@]}]="$i"'
+ for _i in "$@"; do
+ eval ${__stack}'[${#'${__stack}'[@]}]="$_i"'
done
}
pop() {
local __stack=$1; shift
local __resultvar=$1
- local myresult;
+ local _value;
# check for empty stack
eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
- eval myresult='${'${__stack}'[${#'${__stack}'[@]}-1]}'
+ eval _value='${'${__stack}'[${#'${__stack}'[@]}-1]}'
if [[ "$__resultvar" ]]; then
- eval $__resultvar="'$myresult'"
+ eval $__resultvar="'$_value'"
else
- echo "$myresult"
+ printf "%s" "$_value"
fi
eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
return 0
fi
}
-# Little helper function for reading args from the commandline to a stack.
-# it automatically handles -a b and -a=b variants, and returns 1 if
-# we need to shift $3.
-push_arg() {
- # $1 = arg name
- # $2 = arg value
- # $3 = arg parameter
- local rematch='^[^=]*=(.*)$'
- if [[ $2 =~ $rematch ]]; then
- push "$1" "${BASH_REMATCH[1]}"
- else
- push "$1" "$3"
- # There is no way to shift our callers args, so
- # return 1 to indicate they should do it instead.
- return 1
- fi
+dropindirs_sort()
+{
+ local suffix=$1; shift
+ local -a files
+ local f d
+
+ for d in "$@"; do
+ for i in "$d/"*"$suffix"; do
+ if [[ -e "$i" ]]; then
+ printf "%s\n" "${i##*/}"
+ fi
+ done
+ done | sort -Vu | {
+ readarray -t files
+
+ for f in "${files[@]}"; do
+ for d in "$@"; do
+ if [[ -e "$d/$f" ]]; then
+ printf "%s\n" "$d/$f"
+ continue 2
+ fi
+ done
+ done
+ }
}
verbosity_mod_l=0
unset kernel
unset outfile
-while (($# > 0)); do
- case ${1%%=*} in
- -a|--add) push_arg add_dracutmodules_l "$@" || shift;;
- --force-add) push_arg force_add_dracutmodules_l "$@" || shift;;
- --add-drivers) push_arg add_drivers_l "$@" || shift;;
- --omit-drivers) push_arg omit_drivers_l "$@" || shift;;
- -m|--modules) push_arg dracutmodules_l "$@" || shift;;
- -o|--omit) push_arg omit_dracutmodules_l "$@" || shift;;
- -d|--drivers) push_arg drivers_l "$@" || shift;;
- --filesystems) push_arg filesystems_l "$@" || shift;;
- -I|--install) push_arg install_items_l "$@" || shift;;
- --fwdir) push_arg fw_dir_l "$@" || shift;;
- --libdirs) push_arg libdirs_l "$@" || shift;;
- --fscks) push_arg fscks_l "$@" || shift;;
- --add-fstab) push_arg add_fstab_l "$@" || shift;;
- --mount) push_arg fstab_lines "$@" || shift;;
+# Workaround -i, --include taking 2 arguments
+set -- "${@/--include/++include}"
+
+# This prevents any long argument ending with "-i"
+# -i, like --opt-i but I think we can just prevent that
+set -- "${@/%-i/++include}"
+
+TEMP=$(unset POSIXLY_CORRECT; getopt \
+ -o "a:m:o:d:I:k:c:L:fvqlHhMN" \
+ --long kver: \
+ --long add: \
+ --long force-add: \
+ --long add-drivers: \
+ --long omit-drivers: \
+ --long modules: \
+ --long omit: \
+ --long drivers: \
+ --long filesystems: \
+ --long install: \
+ --long fwdir: \
+ --long libdirs: \
+ --long fscks: \
+ --long add-fstab: \
+ --long mount: \
+ --long device: \
+ --long nofscks: \
+ --long ro-mnt \
+ --long kmoddir: \
+ --long conf: \
+ --long confdir: \
+ --long tmpdir: \
+ --long stdlog: \
+ --long compress: \
+ --long prefix: \
+ --long force \
+ --long kernel-only \
+ --long no-kernel \
+ --long kernel-cmdline: \
+ --long strip \
+ --long nostrip \
+ --long hardlink \
+ --long nohardlink \
+ --long noprefix \
+ --long mdadmconf \
+ --long nomdadmconf \
+ --long lvmconf \
+ --long nolvmconf \
+ --long debug \
+ --long profile \
+ --long sshkey: \
+ --long verbose \
+ --long quiet \
+ --long local \
+ --long hostonly \
+ --long host-only \
+ --long no-hostonly \
+ --long no-host-only \
+ --long fstab \
+ --long help \
+ --long bzip2 \
+ --long lzma \
+ --long xz \
+ --long no-compress \
+ --long gzip \
+ --long list-modules \
+ --long show-modules \
+ --long keep \
+ --long printsize \
+ --long regenerate-all \
+ --long noimageifnotneeded \
+ -- "$@")
+
+if (( $? != 0 )); then
+ usage
+ exit 1
+fi
+
+eval set -- "$TEMP"
+
+while :; do
+ case $1 in
+ --kver) kernel="$2"; shift;;
+ -a|--add) push add_dracutmodules_l "$2"; shift;;
+ --force-add) push force_add_dracutmodules_l "$2"; shift;;
+ --add-drivers) push add_drivers_l "$2"; shift;;
+ --omit-drivers) push omit_drivers_l "$2"; shift;;
+ -m|--modules) push dracutmodules_l "$2"; shift;;
+ -o|--omit) push omit_dracutmodules_l "$2"; shift;;
+ -d|--drivers) push drivers_l "$2"; shift;;
+ --filesystems) push filesystems_l "$2"; shift;;
+ -I|--install) push install_items_l "$2"; shift;;
+ --fwdir) push fw_dir_l "$2"; shift;;
+ --libdirs) push libdirs_l "$2"; shift;;
+ --fscks) push fscks_l "$2"; shift;;
+ --add-fstab) push add_fstab_l "$2"; shift;;
+ --mount) push fstab_lines "$2"; shift;;
+ --add-device|--device)
+ push add_device_l "$2"; shift;;
+ --kernel-cmdline) push kernel_cmdline_l "$2"; shift;;
--nofscks) nofscks_l="yes";;
- -k|--kmoddir) read_arg drivers_dir_l "$@" || shift;;
- -c|--conf) read_arg conffile "$@" || shift;;
- --confdir) read_arg confdir "$@" || shift;;
- --tmpdir) read_arg tmpdir_l "$@" || shift;;
- -L|--stdlog) read_arg stdloglvl_l "$@" || shift;;
- --compress) read_arg compress_l "$@" || shift;;
- --prefix) read_arg prefix_l "$@" || shift;;
+ --ro-mnt) ro_mnt_l="yes";;
+ -k|--kmoddir) drivers_dir_l="$2"; shift;;
+ -c|--conf) conffile="$2"; shift;;
+ --confdir) confdir="$2"; shift;;
+ --tmpdir) tmpdir_l="$2"; shift;;
+ -L|--stdlog) stdloglvl_l="$2"; shift;;
+ --compress) compress_l="$2"; shift;;
+ --prefix) prefix_l="$2"; shift;;
-f|--force) force=yes;;
--kernel-only) kernel_only="yes"; no_kernel="no";;
--no-kernel) kernel_only="no"; no_kernel="yes";;
+ --early-microcode) early_microcode="yes";;
+ --no-early-microcode) early_microcode="no";;
--strip) do_strip_l="yes";;
--nostrip) do_strip_l="no";;
+ --hardlink) do_hardlink_l="yes";;
+ --nohardlink) do_hardlink_l="no";;
--noprefix) prefix_l="/";;
--mdadmconf) mdadmconf_l="yes";;
--nomdadmconf) mdadmconf_l="no";;
--nolvmconf) lvmconf_l="no";;
--debug) debug="yes";;
--profile) profile="yes";;
- --sshkey) read_arg sshkey "$@" || shift;;
+ --sshkey) sshkey="$2"; shift;;
-v|--verbose) ((verbosity_mod_l++));;
-q|--quiet) ((verbosity_mod_l--));;
-l|--local)
allowlocal="yes"
- [[ -f "$(readlink -f ${0%/*})/dracut-functions.sh" ]] \
- && dracutbasedir="$(readlink -f ${0%/*})"
+ [[ -f "$(readlink -f "${0%/*}")/dracut-functions.sh" ]] \
+ && dracutbasedir="$(readlink -f "${0%/*}")"
;;
- -H|--hostonly) hostonly_l="yes" ;;
- --no-hostonly) hostonly_l="no" ;;
+ -H|--hostonly|--host-only)
+ hostonly_l="yes" ;;
+ -N|--no-hostonly|--no-host-only)
+ hostonly_l="no" ;;
--fstab) use_fstab_l="yes" ;;
- -h|--help) usage; exit 1 ;;
+ -h|--help) long_usage; exit 1 ;;
-i|--include) push include_src "$2"
- push include_target "$3"
- shift 2;;
+ shift;;
--bzip2) compress_l="bzip2";;
--lzma) compress_l="lzma";;
--xz) compress_l="xz";;
--no-compress) _no_compress_l="cat";;
--gzip) compress_l="gzip";;
- --list-modules)
- do_list="yes";
- ;;
+ --list-modules) do_list="yes";;
-M|--show-modules)
show_modules_l="yes"
;;
--keep) keep="yes";;
--printsize) printsize="yes";;
- -*) printf "\nUnknown option: %s\n\n" "$1" >&2; usage; exit 1;;
+ --regenerate-all) regenerate_all="yes";;
+ --noimageifnotneeded) noimageifnotneeded="yes";;
+
+ --) shift; break;;
+
+ *) # should not even reach this point
+ printf "\n!Unknown option: '%s'\n\n" "$1" >&2; usage; exit 1;;
+ esac
+ shift
+done
+
+# getopt cannot handle multiple arguments, so just handle "-I,--include"
+# the old fashioned way
+
+while (($# > 0)); do
+ case ${1%%=*} in
+ ++include) push include_src "$2"
+ push include_target "$3"
+ shift 2;;
*)
if ! [[ ${outfile+x} ]]; then
outfile=$1
elif ! [[ ${kernel+x} ]]; then
kernel=$1
else
- echo "Unknown argument: $1"
+ printf "\nUnknown arguments: %s\n\n" "$*" >&2
usage; exit 1;
fi
;;
esac
shift
done
+
+if [[ $regenerate_all == "yes" ]]; then
+ ret=0
+ if [[ $kernel ]]; then
+ printf -- "--regenerate-all cannot be called with a kernel version\n" >&2
+ exit 1
+ fi
+
+ if [[ $outfile ]]; then
+ printf -- "--regenerate-all cannot be called with a image file\n" >&2
+ exit 1
+ fi
+
+ ((len=${#dracut_args[@]}))
+ for ((i=0; i < len; i++)); do
+ [[ ${dracut_args[$i]} == "--regenerate-all" ]] && \
+ unset dracut_args[$i]
+ done
+
+ cd /lib/modules
+ for i in *; do
+ [[ -f $i/modules.builtin ]] || continue
+ dracut --kver="$i" "${dracut_args[@]}"
+ ((ret+=$?))
+ done
+ exit $ret
+fi
+
if ! [[ $kernel ]]; then
kernel=$(uname -r)
fi
-[[ $outfile ]] || outfile="/boot/initramfs-$kernel.img"
+
+if ! [[ $outfile ]]; then
+ [[ -f /etc/machine-id ]] && read MACHINE_ID < /etc/machine-id
+
+ if [[ $MACHINE_ID ]] && ( [[ -d /boot/${MACHINE_ID} ]] || [[ -L /boot/${MACHINE_ID} ]] ); then
+ outfile="/boot/${MACHINE_ID}/$kernel/initrd"
+ else
+ outfile="/boot/initramfs-$kernel.img"
+ fi
+fi
for i in /usr/sbin /sbin /usr/bin /bin; do
rl=$i
if [ -L "$i" ]; then
rl=$(readlink -f $i)
fi
- NPATH+=":$rl"
+ if [[ "$NPATH" != "*:$rl*" ]] ; then
+ NPATH+=":$rl"
+ fi
done
export PATH="${NPATH#:}"
+unset LC_MESSAGES
+unset LC_CTYPE
+export LC_ALL=C
+export LANG=C
unset NPATH
unset LD_LIBRARY_PATH
unset GREP_OPTIONS
+export DRACUT_LOG_LEVEL=warning
[[ $debug ]] && {
+ export DRACUT_LOG_LEVEL=debug
export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
set -x
}
# if we were not passed a config file, try the default one
if [[ ! -f $conffile ]]; then
- [[ $allowlocal ]] && conffile="$dracutbasedir/dracut.conf" || \
+ if [[ $allowlocal ]]; then
+ conffile="$dracutbasedir/dracut.conf"
+ else
conffile="/etc/dracut.conf"
+ fi
fi
if [[ ! -d $confdir ]]; then
- [[ $allowlocal ]] && confdir="$dracutbasedir/dracut.conf.d" || \
+ if [[ $allowlocal ]]; then
+ confdir="$dracutbasedir/dracut.conf.d"
+ else
confdir="/etc/dracut.conf.d"
+ fi
fi
# source our config file
[[ -f $conffile ]] && . "$conffile"
# source our config dir
-if [[ $confdir && -d $confdir ]]; then
- for f in "$confdir"/*.conf; do
- [[ -e $f ]] && . "$f"
- done
-fi
+for f in $(dropindirs_sort ".conf" "$confdir" "$dracutbasedir/dracut.conf.d"); do
+ [[ -e $f ]] && . "$f"
+done
# these optins add to the stuff in the config file
if (( ${#add_dracutmodules_l[@]} )); then
[[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
[[ $do_strip_l ]] && do_strip=$do_strip_l
+[[ $do_strip ]] || do_strip=yes
+[[ $do_hardlink_l ]] && do_hardlink=$do_hardlink_l
+[[ $do_hardlink ]] || do_hardlink=yes
[[ $prefix_l ]] && prefix=$prefix_l
[[ $prefix = "/" ]] && unset prefix
[[ $hostonly_l ]] && hostonly=$hostonly_l
[[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware"
[[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
[[ $tmpdir ]] || tmpdir=/var/tmp
-[[ $do_strip ]] || do_strip=no
[[ $compress_l ]] && compress=$compress_l
[[ $show_modules_l ]] && show_modules=$show_modules_l
[[ $nofscks_l ]] && nofscks="yes"
+[[ $ro_mnt_l ]] && ro_mnt="yes"
# eliminate IFS hackery when messing with fw_dir
fw_dir=${fw_dir//:/ }
bzip2) compress="bzip2 -9";;
lzma) compress="lzma -9";;
xz) compress="xz --check=crc32 --lzma2=dict=1MiB";;
- gzip) command -v pigz > /dev/null 2>&1 && compress="pigz -9" || \
- compress="gzip -9";;
+ gzip) compress="gzip -9"; command -v pigz > /dev/null 2>&1 && compress="pigz -9";;
esac
if [[ $_no_compress_l = "cat" ]]; then
compress="cat"
[[ $hostonly != "-h" ]] && unset hostonly
readonly TMPDIR="$tmpdir"
-readonly initdir=$(mktemp --tmpdir="$TMPDIR/" -d -t initramfs.XXXXXX)
+readonly initdir="$(mktemp --tmpdir="$TMPDIR/" -d -t initramfs.XXXXXX)"
[ -d "$initdir" ] || {
- echo "dracut: mktemp --tmpdir=\"$TMPDIR/\" -d -t initramfs.XXXXXXfailed." >&2
+ printf "%s\n" "dracut: mktemp --tmpdir=\"$TMPDIR/\" -d -t initramfs.XXXXXX failed." >&2
exit 1
}
+if [[ $early_microcode = yes ]]; then
+ readonly microcode_dir="$(mktemp --tmpdir="$TMPDIR/" -d -t early_microcode.XXXXXX)"
+ [ -d "$microcode_dir" ] || {
+ printf "%s\n" "dracut: mktemp --tmpdir=\"$TMPDIR/\" -d -t early_microcode.XXXXXX failed." >&2
+ exit 1
+ }
+fi
+# clean up after ourselves no matter how we die.
+trap '
+ ret=$?;
+ [[ $outfile ]] && [[ -f $outfile.$$ ]] && rm -f -- "$outfile.$$";
+ [[ $keep ]] && echo "Not removing $initdir." >&2 || { [[ $initdir ]] && rm -rf -- "$initdir"; };
+ [[ $keep ]] && echo "Not removing $microcode_dir." >&2 || { [[ $microcode_dir ]] && rm -Rf -- "$microcode_dir"; };
+ [[ $_dlogdir ]] && rm -Rf -- "$_dlogdir";
+ exit $ret;
+ ' EXIT
+
+# clean up after ourselves no matter how we die.
+trap 'exit 1;' SIGINT
+
+export DRACUT_KERNEL_LAZY="1"
+export DRACUT_RESOLVE_LAZY="1"
+
if [[ -f $dracutbasedir/dracut-functions.sh ]]; then
. $dracutbasedir/dracut-functions.sh
else
- echo "dracut: Cannot find $dracutbasedir/dracut-functions.sh." >&2
- echo "dracut: Are you running from a git checkout?" >&2
- echo "dracut: Try passing -l as an argument to $0" >&2
+ printf "%s\n" "dracut: Cannot find $dracutbasedir/dracut-functions.sh." >&2
+ printf "%s\n" "dracut: Are you running from a git checkout?" >&2
+ printf "%s\n" "dracut: Try passing -l as an argument to $0" >&2
exit 1
fi
+inst /bin/sh
+if ! $DRACUT_INSTALL ${initdir+-D "$initdir"} -R "$initdir/bin/sh" &>/dev/null; then
+ unset DRACUT_RESOLVE_LAZY
+ export DRACUT_RESOLVE_DEPS=1
+fi
+rm -fr -- ${initdir}/*
+
if [[ -f $dracutbasedir/dracut-version.sh ]]; then
. $dracutbasedir/dracut-version.sh
fi
-# Verify bash version, curret minimum is 3.1
-if (( ${BASH_VERSINFO[0]} < 3 ||
- ( ${BASH_VERSINFO[0]} == 3 && ${BASH_VERSINFO[1]} < 1 ) )); then
- dfatal 'You need at least Bash 3.1 to use dracut, sorry.'
+# Verify bash version, current minimum is 3.1
+if (( BASH_VERSINFO[0] < 4 )); then
+ dfatal 'You need at least Bash 4 to use dracut, sorry.'
exit 1
fi
fi
omit_drivers=${omit_drivers/-/_}
+if (( ${#kernel_cmdline_l[@]} )); then
+ while pop kernel_cmdline_l val; do
+ kernel_cmdline+=" $val "
+ done
+fi
+
omit_drivers_corrected=""
for d in $omit_drivers; do
- strstr " $drivers $add_drivers " " $d " && continue
+ [[ " $drivers $add_drivers " == *\ $d\ * ]] && continue
omit_drivers_corrected+="$d|"
done
omit_drivers="${omit_drivers_corrected%|}"
unset omit_drivers_corrected
-
-ddebug "Executing $0 $dracut_args"
+# prepare args for logging
+for ((i=0; i < ${#dracut_args[@]}; i++)); do
+ [[ "${dracut_args[$i]}" == *\ * ]] && \
+ dracut_args[$i]="\"${dracut_args[$i]}\""
+ #" keep vim happy
+done
+dinfo "Executing: $0 ${dracut_args[@]}"
[[ $do_list = yes ]] && {
for mod in $dracutbasedir/modules.d/*; do
[[ -d $mod ]] || continue;
[[ -e $mod/install || -e $mod/installkernel || \
-e $mod/module-setup.sh ]] || continue
- echo ${mod##*/??}
+ printf "%s\n" "${mod##*/??}"
done
exit 0
}
abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
-[[ -f $srcmods/modules.dep ]] || {
- dfatal "$srcmods/modules.dep is missing. Did you run depmod?"
- exit 1
-}
+if [[ -d $srcmods ]]; then
+ [[ -f $srcmods/modules.dep ]] || {
+ dwarn "$srcmods/modules.dep is missing. Did you run depmod?"
+ }
+fi
if [[ -f $outfile && ! $force ]]; then
dfatal "Will not override existing initramfs ($outfile) without --force"
[[ $outdir ]] || outdir="/"
if [[ ! -d "$outdir" ]]; then
- dfatal "Can't write $outfile: Directory $outdir does not exist."
+ dfatal "Can't write to $outdir: Directory $outdir does not exist or is not accessible."
exit 1
elif [[ ! -w "$outdir" ]]; then
- dfatal "No permission to write $outdir."
+ dfatal "No permission to write to $outdir."
exit 1
elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
dfatal "No permission to write $outfile."
exit 1
fi
-# clean up after ourselves no matter how we die.
-trap 'ret=$?;[[ $keep ]] && echo "Not removing $initdir." >&2 || rm -rf "$initdir";exit $ret;' EXIT
-# clean up after ourselves no matter how we die.
-trap 'exit 1;' SIGINT
-
# Need to be able to have non-root users read stuff (rpcbind etc)
chmod 755 "$initdir"
+if [[ $hostonly ]]; then
+ for i in /sys /proc /run /dev; do
+ if ! findmnt --target "$i" &>/dev/null; then
+ dwarning "Turning off host-only mode: '$i' is not mounted!"
+ unset hostonly
+ fi
+ done
+ if ! [[ -d /run/udev/data ]]; then
+ dwarning "Turning off host-only mode: udev database not found!"
+ unset hostonly
+ fi
+fi
+
+declare -A host_fs_types
+
for line in "${fstab_lines[@]}"; do
set -- $line
#dev mp fs fsopts
push host_devs "$1"
- push host_fs_types "$1|$3"
+ host_fs_types["$1"]="$3"
done
for f in $add_fstab; do
- [ -e $f ] || continue
+ [[ -e $f ]] || continue
while read dev rest; do
- push host_devs $dev
- done < $f
+ push host_devs "$dev"
+ done < "$f"
+done
+
+for dev in $add_device; do
+ push host_devs "$dev"
done
+if (( ${#add_device_l[@]} )); then
+ while pop add_device_l val; do
+ add_device+=" $val "
+ push host_devs "$val"
+ done
+fi
+
if [[ $hostonly ]]; then
# in hostonly mode, determine all devices, which have to be accessed
# and examine them for filesystem types
- push host_mp \
+ for mp in \
"/" \
"/etc" \
- "/usr" \
- "/usr/bin" \
- "/usr/sbin" \
- "/usr/lib" \
- "/usr/lib64" \
- "/boot"
-
- for mp in "${host_mp[@]}"; do
+ "/bin" \
+ "/sbin" \
+ "/lib" \
+ "/lib64" \
+ "/boot";
+ do
+ mp=$(readlink -f "$mp")
mountpoint "$mp" >/dev/null 2>&1 || continue
- push host_devs $(readlink -f "/dev/block/$(find_block_device "$mp")")
+ _dev="$(readlink -f "/dev/block/$(find_block_device "$mp")")"
+ [[ "$_mp" == "/" ]] && root_dev="$_dev"
+ push host_devs "$_dev"
done
+
+ if [[ -f /proc/swaps ]] && [[ -f /etc/fstab ]]; then
+ while read dev type rest; do
+ [[ -b $dev ]] || continue
+ [[ "$type" == "partition" ]] || continue
+
+ while read _d _m _t _o _r; do
+ [[ "$_d" == \#* ]] && continue
+ [[ $_d ]] || continue
+ [[ $_t != "swap" ]] || [[ $_m != "swap" ]] && continue
+ [[ "$_o" == *noauto* ]] && continue
+ [[ "$_d" == UUID\=* ]] && _d="/dev/disk/by-uuid/${_d#UUID=}"
+ [[ "$_d" == LABEL\=* ]] && _d="/dev/disk/by-label/$_d#LABEL=}"
+ [[ "$_d" -ef "$dev" ]] || continue
+
+ if [[ -f /etc/crypttab ]]; then
+ while read _mapper _a _p _o; do
+ [[ $_mapper = \#* ]] && continue
+ [[ "$_d" -ef /dev/mapper/"$_mapper" ]] || continue
+ [[ "$_o" ]] || _o="$_p"
+ # skip mkswap swap
+ [[ $_o == *swap* ]] && continue 2
+ done < /etc/crypttab
+ fi
+
+ push host_devs "$(readlink -f "$dev")"
+ break
+ done < /etc/fstab
+ done < /proc/swaps
+ fi
fi
-_get_fs_type() (
+_get_fs_type() {
[[ $1 ]] || return
- if [[ -b $1 ]] && get_fs_env $1; then
- echo "$(readlink -f $1)|$ID_FS_TYPE"
+ if [[ -b /dev/block/$1 ]] && ID_FS_TYPE=$(get_fs_env "/dev/block/$1"); then
+ host_fs_types["$(readlink -f "/dev/block/$1")"]="$ID_FS_TYPE"
return 1
fi
- if [[ -b /dev/block/$1 ]] && get_fs_env /dev/block/$1; then
- echo "$(readlink -f /dev/block/$1)|$ID_FS_TYPE"
+ if [[ -b $1 ]] && ID_FS_TYPE=$(get_fs_env "$1"); then
+ host_fs_types["$(readlink -f "$1")"]="$ID_FS_TYPE"
return 1
fi
- if fstype=$(find_dev_fstype $1); then
- echo "$1|$fstype"
+ if fstype=$(find_dev_fstype "$1"); then
+ host_fs_types["$1"]="$fstype"
return 1
fi
return 1
-)
-
-for dev in "${host_devs[@]}"; do
- unset fs_type
- for fstype in $(_get_fs_type $dev) \
- $(check_block_and_slaves _get_fs_type $(get_maj_min $dev)); do
- if ! strstr " ${host_fs_types[*]} " " $fstype ";then
- push host_fs_types "$fstype"
- fi
- done
+}
+
+for dev in ${host_devs[@]}; do
+ _get_fs_type "$dev"
+ check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
done
[[ -d $udevdir ]] \
- || udevdir=$(pkg-config udev --variable=udevdir 2>/dev/null)
+ || udevdir="$(pkg-config udev --variable=udevdir 2>/dev/null)"
if ! [[ -d "$udevdir" ]]; then
[[ -d /lib/udev ]] && udevdir=/lib/udev
[[ -d /usr/lib/udev ]] && udevdir=/usr/lib/udev
[[ -d $systemdutildir ]] \
|| systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
-[[ -d $systemdsystemunitdir ]] \
- || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
if ! [[ -d "$systemdutildir" ]]; then
[[ -d /lib/systemd ]] && systemdutildir=/lib/systemd
[[ -d /usr/lib/systemd ]] && systemdutildir=/usr/lib/systemd
fi
+
+[[ -d $systemdsystemunitdir ]] \
+ || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
+
[[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
-export initdir dracutbasedir dracutmodules drivers \
+[[ -d $systemdsystemconfdir ]] \
+ || systemdsystemconfdir=$(pkg-config systemd --variable=systemdsystemconfdir 2>/dev/null)
+
+[[ -d "$systemdsystemconfdir" ]] || systemdsystemconfdir=/etc/systemd/system
+
+export initdir dracutbasedir dracutmodules \
fw_dir drivers_dir debug no_kernel kernel_only \
- add_drivers omit_drivers mdadmconf lvmconf filesystems \
- use_fstab fstab_lines libdirs fscks nofscks \
+ omit_drivers mdadmconf lvmconf root_dev \
+ use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
debug host_fs_types host_devs sshkey add_fstab \
- DRACUT_VERSION udevdir systemdutildir systemdsystemunitdir
+ DRACUT_VERSION udevdir prefix filesystems drivers \
+ systemdutildir systemdsystemunitdir systemdsystemconfdir
# Create some directory structure first
[[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
if [[ $prefix ]]; then
for d in bin etc lib sbin tmp usr var $libdirs; do
- strstr "$d" "/" && continue
+ [[ "$d" == */* ]] && continue
ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
done
fi
if [[ $kernel_only != yes ]]; then
- for d in usr/bin usr/sbin bin etc lib sbin tmp usr var var/log var/run var/lock $libdirs; do
+ for d in usr/bin usr/sbin bin etc lib sbin tmp usr var $libdirs; do
[[ -e "${initdir}${prefix}/$d" ]] && continue
if [ -L "/$d" ]; then
inst_symlink "/$d" "${prefix}/$d"
fi
done
- ln -sfn /run "$initdir/var/run"
- ln -sfn /run/lock "$initdir/var/lock"
+ ln -sfn ../run "$initdir/var/run"
+ ln -sfn ../run/lock "$initdir/var/lock"
+ ln -sfn ../run/log "$initdir/var/log"
else
for d in lib "$libdir"; do
[[ -e "${initdir}${prefix}/$d" ]] && continue
for_each_module_dir check_module
for_each_module_dir check_mount
+[[ "$mods_to_load " == *01fips\ * ]] && export DRACUT_FIPS_MODE=1
+
_isize=0 #initramfs size
modules_loaded=" "
# source our modules.
for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
_d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
- if strstr "$mods_to_load" " $_d_mod "; then
- [[ $show_modules = yes ]] && echo "$_d_mod" || \
+ if [[ "$mods_to_load" == *\ $_d_mod\ * ]]; then
+ if [[ $show_modules = yes ]]; then
+ printf "%s\n" "$_d_mod"
+ else
dinfo "*** Including module: $_d_mod ***"
- if [[ $kernel_only = yes ]]; then
- module_installkernel $_d_mod || {
+ fi
+ if [[ $kernel_only == yes ]]; then
+ module_installkernel "$_d_mod" || {
dfatal "installkernel failed in module $_d_mod"
exit 1
}
else
- module_install $_d_mod
+ module_install "$_d_mod"
if [[ $no_kernel != yes ]]; then
- module_installkernel $_d_mod || {
+ module_installkernel "$_d_mod" || {
dfatal "installkernel failed in module $_d_mod"
exit 1
}
#print the module install size
if [ -n "$printsize" ]; then
_isize_new=$(du -sk ${initdir}|cut -f1)
- _isize_delta=$(($_isize_new - $_isize))
- echo "$_d_mod install size: ${_isize_delta}k"
+ _isize_delta=$((_isize_new - _isize))
+ printf "%s\n" "$_d_mod install size: ${_isize_delta}k"
_isize=$_isize_new
fi
fi
for i in $modules_loaded; do
mkdir -p $initdir/lib/dracut
- echo "$i" >> $initdir/lib/dracut/modules.txt
+ printf "%s\n" "$i" >> $initdir/lib/dracut/modules.txt
done
dinfo "*** Including modules done ***"
## final stuff that has to happen
+if [[ $no_kernel != yes ]]; then
-dinfo "*** Installing kernel module dependencies and firmware ***"
-dracut_kernel_post
-dinfo "*** Installing kernel module dependencies and firmware done ***"
+ if [[ $drivers ]]; then
+ hostonly='' instmods $drivers
+ fi
+
+ if [[ $add_drivers ]]; then
+ hostonly='' instmods -c $add_drivers
+ fi
+ if [[ $filesystems ]]; then
+ hostonly='' instmods -c $filesystems
+ fi
+
+ dinfo "*** Installing kernel module dependencies and firmware ***"
+ dracut_kernel_post
+ dinfo "*** Installing kernel module dependencies and firmware done ***"
+
+ if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
+ if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] && \
+ [[ -f ${initdir}/lib/modules/$kernel/modules.dep && ! -s ${initdir}/lib/modules/$kernel/modules.dep ]]; then
+ for i in ${initdir}/etc/cmdline.d/*.conf; do
+ # We need no initramfs image and do not generate one.
+ [[ $i == "${initdir}/etc/cmdline.d/*.conf" ]] && exit 0
+ done
+ fi
+ fi
+fi
+
+if [[ $kernel_only != yes ]]; then
+ (( ${#install_items[@]} > 0 )) && dracut_install ${install_items[@]}
+
+ [[ $kernel_cmdline ]] && printf "%s\n" "$kernel_cmdline" >> "${initdir}/etc/cmdline.d/01-default.conf"
+
+ while pop fstab_lines line; do
+ printf "%s\n" "$line 0 0" >> "${initdir}/etc/fstab"
+ done
+
+ for f in $add_fstab; do
+ cat "$f" >> "${initdir}/etc/fstab"
+ done
+
+ if [ -d ${initdir}/$systemdutildir ]; then
+ mkdir -p ${initdir}/etc/conf.d
+ {
+ printf "%s\n" "systemdutildir=\"$systemdutildir\""
+ printf "%s\n" "systemdsystemunitdir=\"$systemdsystemunitdir\""
+ printf "%s\n" "systemdsystemconfdir=\"$systemdsystemconfdir\""
+ } > ${initdir}/etc/conf.d/systemd.conf
+ fi
+
+ if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
+ dinfo "*** Resolving executable dependencies ***"
+ find "$initdir" -type f \
+ '(' -perm -0100 -or -perm -0010 -or -perm -0001 ')' \
+ -not -path '*.ko' -print0 \
+ | xargs -r -0 $DRACUT_INSTALL ${initdir+-D "$initdir"} -R ${DRACUT_FIPS_MODE+-H} --
+ dinfo "*** Resolving executable dependencies done***"
+ fi
+fi
while pop include_src src && pop include_target tgt; do
if [[ $src && $tgt ]]; then
mkdir -m 0755 -p "$s"
chmod --reference="$i" "$s"
fi
- cp -a -t "$s" "$i"/*
+ cp --reflink=auto --sparse=auto -fa -t "$s" "$i"/*
else
- cp -a -t "$s" "$i"
+ cp --reflink=auto --sparse=auto -fa -t "$s" "$i"
fi
done
fi
done
if [[ $kernel_only != yes ]]; then
- for item in $install_items; do
- dracut_install "$item"
- done
- unset item
-
- while pop fstab_lines line; do
- echo "$line 0 0" >> "${initdir}/etc/fstab"
- done
-
- for f in $add_fstab; do
- cat $f >> "${initdir}/etc/fstab"
- done
-
# make sure that library links are correct and up to date
for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
[[ -f $f ]] && inst_simple "$f"
fi
fi
-if (($maxloglvl >= 5)); then
- ddebug "Listing sizes of included files:"
- du -c "$initdir" | sort -n | ddebug
+PRELINK_BIN="$(command -v prelink)"
+if [[ $UID = 0 ]] && [[ $PRELINK_BIN ]]; then
+ if [[ $DRACUT_FIPS_MODE ]]; then
+ dinfo "*** Installing prelink files ***"
+ dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf /etc/prelink.cache
+ else
+ dinfo "*** Pre-linking files ***"
+ dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf
+ chroot "$initdir" "$PRELINK_BIN" -a
+ rm -f -- "$initdir/$PRELINK_BIN"
+ rm -fr -- "$initdir"/etc/prelink.*
+ dinfo "*** Pre-linking files done ***"
+ fi
+fi
+
+if [[ $do_hardlink = yes ]] && command -v hardlink >/dev/null; then
+ dinfo "*** Hardlinking files ***"
+ hardlink "$initdir" 2>&1
+ dinfo "*** Hardlinking files done ***"
fi
# strip binaries
if [[ $do_strip = yes ]] ; then
for p in strip xargs find; do
if ! type -P $p >/dev/null; then
- derror "Could not find '$p'. You should run $0 with '--nostrip'."
+ dinfo "Could not find '$p'. Not stripping the initramfs."
do_strip=no
fi
done
fi
if [[ $do_strip = yes ]] ; then
- find "$initdir" -type f \
- \( -perm -0100 -or -perm -0010 -or -perm -0001 \
- -or -path '*/lib/modules/*.ko' \) -print0 \
- | xargs -0 strip -g 2>/dev/null
-fi
+ dinfo "*** Stripping files ***"
+ if [[ $DRACUT_FIPS_MODE ]]; then
+ find "$initdir" -type f \
+ -executable -not -path '*/lib/modules/*.ko' -print0 \
+ | while read -r -d $'\0' f; do
+ if ! [[ -e "${f%/*}/.${f##*/}.hmac" ]] \
+ && ! [[ -e "/lib/hmaccalc/${f##*/}.hmac" ]] \
+ && ! [[ -e "/lib64/hmaccalc/${f##*/}.hmac" ]] \
+ && ! [[ -e "/lib/fipscheck/${f##*/}.hmac" ]] \
+ && ! [[ -e "/lib64/fipscheck/${f##*/}.hmac" ]]; then
+ printf "%s\000" "$f";
+ fi
+ done | xargs -r -0 strip -g 2>/dev/null
+ else
+ find "$initdir" -type f \
+ -executable -not -path '*/lib/modules/*.ko' -print0 \
+ | xargs -r -0 strip -g 2>/dev/null
+ fi
-type hardlink &>/dev/null && {
- hardlink "$initdir" 2>&1
-}
+ # strip kernel modules, but do not touch signed modules
+ find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
+ | while read -r -d $'\0' f; do
+ SIG=$(tail -c 28 "$f")
+ [[ $SIG == '~Module signature appended~' ]] || { printf "%s\000" "$f"; }
+ done | xargs -r -0 strip -g
-if strstr "$modules_loaded" " fips " && command -v prelink >/dev/null; then
- for dir in "$initdir/bin" \
- "$initdir/sbin" \
- "$initdir/usr/bin" \
- "$initdir/usr/sbin"; do
- [[ -L "$dir" ]] && continue
- for i in "$dir"/*; do
- [[ -x $i ]] && prelink -u $i &>/dev/null
+ dinfo "*** Stripping files done ***"
+fi
+if [[ $early_microcode = yes ]]; then
+ dinfo "*** Generating early-microcode cpio image ***"
+ ucode_dir=(amd-ucode intel-ucode)
+ ucode_dest=(AuthenticAMD.bin GenuineIntel.bin)
+ _dest_dir="$microcode_dir/d/kernel/x86/microcode"
+ _dest_idx="0 1"
+ mkdir -p $_dest_dir
+ if [[ $hostonly ]]; then
+ [[ $(get_cpu_vendor) == "AMD" ]] && _dest_idx="0"
+ [[ $(get_cpu_vendor) == "Intel" ]] && _dest_idx="1"
+ fi
+ for idx in $_dest_idx; do
+ _fw=${ucode_dir[$idx]}
+ for _fwdir in $fw_dir; do
+ if [[ -d $_fwdir && -d $_fwdir/$_fw ]]; then
+ _src="*"
+ dinfo "*** Constructing ${ucode_dest[$idx]} ****"
+ if [[ $hostonly ]]; then
+ _src=$(get_ucode_file)
+ fi
+ cat $_fwdir/$_fw/$_src > $_dest_dir/${ucode_dest[$idx]}
+ fi
done
done
+ (cd "$microcode_dir/d"; find . | cpio -o -H newc --quiet >../ucode.cpio)
fi
-if ! ( cd "$initdir"; find . |cpio -R 0:0 -H newc -o --quiet| \
- $compress > "$outfile"; ); then
- dfatal "dracut: creation of $outfile failed"
+rm -f -- "$outfile"
+dinfo "*** Creating image file ***"
+if [[ $early_microcode = yes ]]; then
+ # The microcode blob is _before_ the initramfs blob, not after
+ mv $microcode_dir/ucode.cpio $outfile.$$
+fi
+if ! ( umask 077; cd "$initdir"; find . |cpio -R 0:0 -H newc -o --quiet| \
+ $compress >> "$outfile.$$"; ); then
+ dfatal "dracut: creation of $outfile.$$ failed"
exit 1
fi
+mv -- "$outfile.$$" "$outfile"
+dinfo "*** Creating image file done ***"
-dinfo "Wrote $outfile:"
-dinfo "$(ls -l "$outfile")"
+if (( maxloglvl >= 5 )); then
+ lsinitrd "$outfile"| ddebug
+fi
exit 0