From 794b2d2c753489635b922457a5ccb06669f37268 Mon Sep 17 00:00:00 2001
From: Harald Hoyer <harald@redhat.com>
Date: Thu, 23 Jul 2015 10:35:06 +0200
Subject: [PATCH] Use dracut-install to install kernel modules
dracut-install can now install kernel modules and their corresponding
firmware files.
---
Makefile | 1 +
dracut-init.sh | 178 +------
dracut.sh | 8 +-
install/dracut-install.c | 536 +++++++++++++++++++--
modules.d/50drm/module-setup.sh | 63 +--
modules.d/90crypt/module-setup.sh | 4 +-
modules.d/90dm/module-setup.sh | 3 +-
modules.d/90kernel-modules/module-setup.sh | 53 +-
modules.d/90kernel-network-modules/module-setup.sh | 45 +-
modules.d/90multipath/module-setup.sh | 39 +-
modules.d/95iscsi/module-setup.sh | 41 +-
modules.d/95nfs/module-setup.sh | 2 +-
12 files changed, 580 insertions(+), 393 deletions(-)
diff --git a/Makefile b/Makefile
index 8281f90..0a1ae6c 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ install/util.o: install/util.c install/util.h install/macro.h install/log.h
install/strv.o: install/strv.c install/strv.h install/util.h install/macro.h install/log.h
install/dracut-install: $(DRACUT_INSTALL_OBJECTS)
+ $(CC) $(LDFLAGS) -o $@ $(DRACUT_INSTALL_OBJECTS) $(LDLIBS) -lkmod
dracut-install: install/dracut-install
ln -fs $< $@
diff --git a/dracut-init.sh b/dracut-init.sh
index a8b78ce..e26d97a 100644
--- a/dracut-init.sh
+++ b/dracut-init.sh
@@ -218,6 +218,13 @@ dracut_install() {
inst_multiple "$@"
}
+dracut_instmods() {
+ [[ $no_kernel = yes ]] && return
+ $DRACUT_INSTALL \
+ ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@"
+ (($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@" || :
+}
+
inst_library() {
local _hostonly_install
if [[ "$1" == "-H" ]]; then
@@ -847,11 +854,6 @@ install_kmod_with_fw() {
[[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
&& return 0
- if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -e "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}" ]]; then
- read ret < "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
- return $ret
- fi
-
if [[ $omit_drivers ]]; then
local _kmod=${1##*/}
_kmod=${_kmod%.ko*}
@@ -876,9 +878,6 @@ install_kmod_with_fw() {
inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
ret=$?
- [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
- [[ -d "$DRACUT_KERNEL_LAZY_HASHDIR" ]] && \
- echo $ret > "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
(($ret != 0)) && return $ret
local _modname=${1##*/} _fwdir _found _fw
@@ -925,51 +924,6 @@ dracut_kernel_post() {
local _moddirname=${srcmods%%/lib/modules/*}
local _pid
- if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" ]]; then
- xargs -r modprobe -a ${_moddirname:+-d ${_moddirname}/} \
- --ignore-install --show-depends --set-version $kernel \
- < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" 2>/dev/null \
- | sort -u \
- | while read _cmd _modpath _options || [ -n "$_cmd" ]; do
- [[ $_cmd = insmod ]] || continue
- echo "$_modpath"
- done > "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
-
- (
- if [[ $DRACUT_INSTALL ]] && [[ -z $_moddirname ]]; then
- xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
- else
- while read _modpath || [ -n "$_modpath" ]; do
- local _destpath=$_modpath
- [[ $_moddirname ]] && _destpath=${_destpath##$_moddirname/}
- _destpath=${_destpath##*/lib/modules/$kernel/}
- inst_simple "$_modpath" "/lib/modules/$kernel/${_destpath}" || exit $?
- done < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
- fi
- ) &
- _pid=$(jobs -p | while read a || [ -n "$a" ]; do printf ":$a";done)
- _pid=${_pid##*:}
-
- if [[ $DRACUT_INSTALL ]]; then
- xargs -r modinfo -k $kernel -F firmware < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep" \
- | while read line || [ -n "$line" ]; do
- for _fwdir in $fw_dir; do
- echo $_fwdir/$line;
- done;
- done | xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a -o
- else
- for _fw in $(xargs -r modinfo -k $kernel -F firmware < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"); do
- for _fwdir in $fw_dir; do
- [[ -d $_fwdir && -f $_fwdir/$_fw ]] || continue
- inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
- break
- done
- done
- fi
-
- wait $_pid
- fi
-
for _f in modules.builtin.bin modules.builtin modules.order; do
[[ $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f"
done
@@ -981,7 +935,6 @@ dracut_kernel_post() {
exit 1
fi
- [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && rm -fr -- "$DRACUT_KERNEL_LAZY_HASHDIR"
}
[[ "$kernel_current" ]] || export kernel_current=$(uname -r)
@@ -1038,113 +991,32 @@ find_kernel_modules () {
find_kernel_modules_by_path drivers
}
-# instmods [-c [-s]] <kernel module> [<kernel module> ... ]
-# instmods [-c [-s]] <kernel subsystem>
-# install kernel modules along with all their dependencies.
-# <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
instmods() {
+ # instmods [-c [-s]] <kernel module> [<kernel module> ... ]
+ # instmods [-c [-s]] <kernel subsystem>
+ # install kernel modules along with all their dependencies.
+ # <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
+ # -c check
+ # -s silent
+ local _optional="-o"
+ local _silent
+ local _ret
[[ $no_kernel = yes ]] && return
- # called [sub]functions inherit _fderr
- local _fderr=9
- local _check=no
- local _silent=no
if [[ $1 = '-c' ]]; then
- _check=yes
+ _optional=""
shift
fi
-
if [[ $1 = '-s' ]]; then
- _silent=yes
+ _silent=1
shift
fi
-
- function inst1mod() {
- local _ret=0 _mod="$1"
- case $_mod in
- =*)
- ( [[ "$_mpargs" ]] && echo $_mpargs
- find_kernel_modules_by_path "${_mod#=}" ) \
- | instmods
- ((_ret+=$?))
- ;;
- --*) _mpargs+=" $_mod" ;;
- *)
- _mod=${_mod##*/}
- # Check for aliased modules
- _modalias=$(modinfo -k $kernel -F filename $_mod 2> /dev/null)
- _modalias=${_modalias%.ko*}
- if [[ $_modalias ]] && [ "${_modalias##*/}" != "${_mod%.ko*}" ] ; then
- _mod=${_modalias##*/}
- fi
-
- # if we are already installed, skip this module and go on
- # to the next one.
- if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
- [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}" ]]; then
- read _ret <"$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}"
- return $_ret
- fi
-
- _mod=${_mod/-/_}
- if [[ $omit_drivers ]] && [[ "$_mod" =~ $omit_drivers ]]; then
- dinfo "Omitting driver ${_mod##$srcmods}"
- return 0
- fi
-
- # If we are building a host-specific initramfs and this
- # module is not already loaded, move on to the next one.
- [[ $hostonly ]] \
- && ! module_is_host_only "$_mod" \
- && return 0
-
- if [[ "$_check" = "yes" ]] || ! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
- # We use '-d' option in modprobe only if modules prefix path
- # differs from default '/'. This allows us to use dracut with
- # old version of modprobe which doesn't have '-d' option.
- local _moddirname=${srcmods%%/lib/modules/*}
- [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
-
- # ok, load the module, all its dependencies, and any firmware
- # it may require
- for_each_kmod_dep install_kmod_with_fw $_mod \
- --set-version $kernel ${_moddirname} $_mpargs
- ((_ret+=$?))
- else
- [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
- echo ${_mod%.ko*} >> "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist"
- fi
- ;;
- esac
- return $_ret
- }
-
- function instmods_1() {
- local _mod _mpargs
- if (($# == 0)); then # filenames from stdin
- while read _mod || [ -n "$_mod" ]; do
- inst1mod "${_mod%.ko*}" || {
- if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
- dfatal "Failed to install module $_mod"
- fi
- }
- done
- fi
- while (($# > 0)); do # filenames as arguments
- inst1mod ${1%.ko*} || {
- if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
- dfatal "Failed to install module $1"
- fi
- }
- shift
- done
- return 0
- }
-
- local _ret _filter_not_found='FATAL: Module .* not found.'
- # Capture all stderr from modprobe to _fderr. We could use {var}>...
- # redirections, but that would make dracut require bash4 at least.
- eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \
- | while read line || [ -n "$line" ]; do [[ "$line" =~ $_filter_not_found ]] || echo $line;done | derror
+ if (($# == 0)); then
+ read -r -d '' -a args
+ set -- "${args[@]}"
+ fi
+ $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${_optional:+-o} ${_silent:+--silent} ${srcmods:+--kerneldir "$srcmods"} -m "$@"
_ret=$?
+ (($_ret != 0)) && [[ -z "$_silent" ]] && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${_optional:+-o} ${_silent:+--silent} ${srcmods:+--kerneldir "$srcmods"} -m "$@" || :
+ [[ "$optional" ]] && return 0
return $_ret
}
diff --git a/dracut.sh b/dracut.sh
index 37ae350..f6d0439 100755
--- a/dracut.sh
+++ b/dracut.sh
@@ -733,7 +733,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
[[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
[[ $lvmconf_l ]] && lvmconf=$lvmconf_l
[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
-[[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware /lib/firmware/$kernel"
+[[ $fw_dir ]] || fw_dir="/lib/firmware/updates:/lib/firmware:/lib/firmware/$kernel"
[[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
[[ $tmpdir ]] || tmpdir=/var/tmp
[[ $INITRD_COMPRESS ]] && compress=$INITRD_COMPRESS
@@ -750,6 +750,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
[[ $kernel_image_l ]] && kernel_image="$kernel_image_l"
# eliminate IFS hackery when messing with fw_dir
+export DRACUT_FIRMWARE_PATH=${fw_dir// /:}
fw_dir=${fw_dir//:/ }
# check for logfile and try to create one if it doesn't exist
@@ -839,7 +840,6 @@ trap '
# clean up after ourselves no matter how we die.
trap 'exit 1;' SIGINT
-export DRACUT_KERNEL_LAZY="1"
export DRACUT_RESOLVE_LAZY="1"
if [[ $print_cmdline ]]; then
@@ -1436,9 +1436,9 @@ if [[ $no_kernel != yes ]]; then
hostonly='' instmods -c $filesystems
fi
- dinfo "*** Installing kernel module dependencies and firmware ***"
+ dinfo "*** Installing kernel module dependencies ***"
dracut_kernel_post
- dinfo "*** Installing kernel module dependencies and firmware done ***"
+ dinfo "*** Installing kernel module dependencies done ***"
if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] && \
diff --git a/install/dracut-install.c b/install/dracut-install.c
index 3b48ba8..a20e06c 100644
--- a/install/dracut-install.c
+++ b/install/dracut-install.c
@@ -22,7 +22,7 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
-
+#undef _FILE_OFFSET_BITS
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -38,6 +38,9 @@
#include <sys/wait.h>
#include <unistd.h>
#include <sys/ioctl.h>
+#include <libkmod.h>
+#include <fts.h>
+#include <regex.h>
#include "log.h"
#include "hashmap.h"
@@ -48,16 +51,31 @@ static bool arg_hmac = false;
static bool arg_createdir = false;
static int arg_loglevel = -1;
static bool arg_optional = false;
+static bool arg_silent = false;
static bool arg_all = false;
+static bool arg_module = false;
static bool arg_resolvelazy = false;
static bool arg_resolvedeps = false;
static bool arg_hostonly = false;
static char *destrootdir = NULL;
+static char *kerneldir = NULL;
+static char **firmwaredirs = NULL;
+static char **pathdirs;
static char *logdir = NULL;
static char *logfile = NULL;
FILE *logfile_f = NULL;
static Hashmap *items = NULL;
static Hashmap *items_failed = NULL;
+static regex_t mod_filter_path;
+static regex_t mod_filter_nopath;
+static regex_t mod_filter_symbol;
+static regex_t mod_filter_nosymbol;
+static regex_t mod_filter_noname;
+static bool arg_mod_filter_path = false;
+static bool arg_mod_filter_nopath = false;
+static bool arg_mod_filter_symbol = false;
+static bool arg_mod_filter_nosymbol = false;
+static bool arg_mod_filter_noname = false;
static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst);
@@ -516,6 +534,18 @@ void dracut_log_cp(const char *path)
log_error("Could not append '%s' to logfile '%s': %m", path, logfile);
}
+static bool check_hashmap(Hashmap *hm, const char *item)
+{
+ char *existing;
+ existing = hashmap_get(hm, item);
+ if (existing) {
+ if (strcmp(existing, item) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst)
{
struct stat sb, db;
@@ -524,26 +554,17 @@ static int dracut_install(const char *src, const char *dst, bool isdir, bool res
int ret;
bool src_exists = true;
char *i = NULL;
- char *existing;
log_debug("dracut_install('%s', '%s')", src, dst);
- existing = hashmap_get(items_failed, src);
- if (existing) {
- if (strcmp(existing, src) == 0) {
- log_debug("hash hit items_failed for '%s'", src);
- return 1;
- }
+ if (check_hashmap(items_failed, src)) {
+ log_debug("hash hit items_failed for '%s'", src);
+ return 1;
}
- if (hashdst) {
- existing = hashmap_get(items, dst);
- if (existing) {
- if (strcmp(existing, dst) == 0) {
- log_debug("hash hit items for '%s'", dst);
- return 0;
- }
- }
+ if (hashdst && check_hashmap(items, dst)) {
+ log_debug("hash hit items for '%s'", dst);
+ return 0;
}
if (lstat(src, &sb) < 0) {
@@ -678,7 +699,7 @@ static int dracut_install(const char *src, const char *dst, bool isdir, bool res
log_debug("dracut_install ret = %d", ret);
log_info("cp '%s' '%s'", src, fulldstpath);
- if (arg_hostonly)
+ if (arg_hostonly && !arg_module)
mark_hostonly(dst);
ret += cp(src, fulldstpath);
@@ -751,6 +772,9 @@ static int parse_argv(int argc, char *argv[])
enum {
ARG_VERSION = 0x100,
+ ARG_SILENT,
+ ARG_KERNELDIR,
+ ARG_FIRMWAREDIRS,
ARG_DEBUG
};
@@ -765,13 +789,22 @@ static int parse_argv(int argc, char *argv[])
{"optional", no_argument, NULL, 'o'},
{"hostonly", no_argument, NULL, 'H'},
{"all", no_argument, NULL, 'a'},
+ {"module", no_argument, NULL, 'm'},
{"fips", no_argument, NULL, 'f'},
{"destrootdir", required_argument, NULL, 'D'},
{"logdir", required_argument, NULL, 'L'},
+ {"mod-filter-path", required_argument, NULL, 'p'},
+ {"mod-filter-nopath", required_argument, NULL, 'P'},
+ {"mod-filter-symbol", required_argument, NULL, 's'},
+ {"mod-filter-nosymbol", required_argument, NULL, 'S'},
+ {"mod-filter-noname", required_argument, NULL, 'N'},
+ {"silent", no_argument, NULL, ARG_SILENT},
+ {"kerneldir", required_argument, NULL, ARG_KERNELDIR},
+ {"firmwaredirs", required_argument, NULL, ARG_FIRMWAREDIRS},
{NULL, 0, NULL, 0}
};
- while ((c = getopt_long(argc, argv, "adfhlL:oD:HR", options, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "madfhlL:oD:HRp:P:s:S:N:", options, NULL)) != -1) {
switch (c) {
case ARG_VERSION:
puts(PROGRAM_VERSION_STRING);
@@ -782,6 +815,9 @@ static int parse_argv(int argc, char *argv[])
case ARG_DEBUG:
arg_loglevel = LOG_DEBUG;
break;
+ case ARG_SILENT:
+ arg_silent = true;
+ break;
case 'v':
arg_loglevel = LOG_INFO;
break;
@@ -797,12 +833,56 @@ static int parse_argv(int argc, char *argv[])
case 'a':
arg_all = true;
break;
+ case 'm':
+ arg_module = true;
+ break;
case 'D':
destrootdir = strdup(optarg);
break;
+ case 'p':
+ if (regcomp(&mod_filter_path, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
+ log_error("Module path filter %s is not a regular expression", optarg);
+ exit(EXIT_FAILURE);
+ }
+ arg_mod_filter_path = true;
+ break;
+ case 'P':
+ if (regcomp(&mod_filter_nopath, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
+ log_error("Module path filter %s is not a regular expression", optarg);
+ exit(EXIT_FAILURE);
+ }
+ arg_mod_filter_nopath = true;
+ break;
+ case 's':
+ if (regcomp(&mod_filter_symbol, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
+ log_error("Module symbol filter %s is not a regular expression", optarg);
+ exit(EXIT_FAILURE);
+ }
+ arg_mod_filter_symbol = true;
+ break;
+ case 'S':
+ if (regcomp(&mod_filter_nosymbol, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
+ log_error("Module symbol filter %s is not a regular expression", optarg);
+ exit(EXIT_FAILURE);
+ }
+ arg_mod_filter_nosymbol = true;
+ break;
+ case 'N':
+ if (regcomp(&mod_filter_noname, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
+ log_error("Module symbol filter %s is not a regular expression", optarg);
+ exit(EXIT_FAILURE);
+ }
+ arg_mod_filter_noname = true;
+ break;
case 'L':
logdir = strdup(optarg);
break;
+ case ARG_KERNELDIR:
+ kerneldir = strdup(optarg);
+ break;
+ case ARG_FIRMWAREDIRS:
+ firmwaredirs = strv_split(optarg, ":");
+ break;
case 'f':
arg_hmac = true;
break;
@@ -817,6 +897,22 @@ static int parse_argv(int argc, char *argv[])
}
}
+ if (arg_module) {
+ if (!firmwaredirs) {
+ char *path = NULL;
+
+ path = getenv("DRACUT_FIRMWARE_PATH");
+
+ if (path == NULL) {
+ log_error("Environment variable DRACUT_FIRMWARE_PATH is not set");
+ exit(EXIT_FAILURE);
+ }
+
+ log_debug("DRACUT_FIRMWARE_PATH=%s", path);
+
+ firmwaredirs = strv_split(path, ":");
+ }
+ }
if (!optind || optind == argc) {
log_error("No SOURCE argument given");
usage(EXIT_FAILURE);
@@ -858,24 +954,11 @@ static int resolve_lazy(int argc, char **argv)
static char **find_binary(const char *src)
{
- char *path = NULL;
- _cleanup_strv_free_ char **p = NULL;
char **ret = NULL;
char **q;
char *newsrc = NULL;
- path = getenv("PATH");
-
- if (path == NULL) {
- log_error("PATH is not set");
- exit(EXIT_FAILURE);
- }
-
- log_debug("PATH=%s", path);
-
- p = strv_split(path, ":");
-
- STRV_FOREACH(q, p) {
+ STRV_FOREACH(q, pathdirs) {
struct stat sb;
int r;
@@ -976,10 +1059,381 @@ static int install_all(int argc, char **argv)
return r;
}
+static int install_firmware(struct kmod_module *mod)
+{
+ struct kmod_list *l, *list = NULL;
+ int ret;
+
+ char **q;
+
+ ret = kmod_module_get_info(mod, &list);
+ if (ret < 0) {
+ log_error("could not get modinfo from '%s': %s\n",
+ kmod_module_get_name(mod), strerror(-ret));
+ return ret;
+ }
+ kmod_list_foreach(l, list) {
+ const char *key = kmod_module_info_get_key(l);
+ const char *value = NULL;
+ char *fwpath = NULL;
+
+ if (!streq("firmware", key))
+ continue;
+
+ value = kmod_module_info_get_value(l);
+ log_debug("Firmware %s", value);
+ ret = -1;
+ STRV_FOREACH(q, firmwaredirs) {
+ struct stat sb;
+ int r;
+
+ r = asprintf(&fwpath, "%s/%s", *q, value);
+ if (r < 0) {
+ log_error("Out of memory!");
+ exit(EXIT_FAILURE);
+ }
+
+ if (stat(fwpath, &sb) != 0) {
+ log_debug("stat(%s) != 0", fwpath);
+ free(fwpath);
+ fwpath = NULL;
+ continue;
+ }
+
+ ret = dracut_install(fwpath, fwpath, false, false, true);
+ if (ret == 0)
+ log_debug("dracut_install '%s' OK", fwpath);
+ }
+
+ if (ret != 0) {
+ log_info("Possible missing firmware %s for kernel module %s", value, kmod_module_get_name(mod));
+ }
+ }
+ return 0;
+}
+
+static bool check_module_symbols(struct kmod_module *mod)
+{
+ struct kmod_list *itr, *deplist = NULL;
+
+ if (!arg_mod_filter_symbol && !arg_mod_filter_nosymbol)
+ return true;
+
+ if (kmod_module_get_dependency_symbols(mod, &deplist) < 0) {
+ log_debug("kmod_module_get_dependency_symbols failed");
+ if (arg_mod_filter_symbol)
+ return false;
+ return true;
+ }
+
+ if (arg_mod_filter_nosymbol) {
+ kmod_list_foreach(itr, deplist) {
+ const char *symbol = kmod_module_symbol_get_symbol(itr);
+ // log_debug("Checking symbol %s", symbol);
+ if (regexec(&mod_filter_nosymbol, symbol, 0, NULL, 0) == 0) {
+ kmod_module_dependency_symbols_free_list(deplist);
+ log_debug("Module %s: symbol %s matched exclusion filter", kmod_module_get_name(mod), symbol);
+ return false;
+ }
+ }
+ }
+
+ if (arg_mod_filter_symbol) {
+ kmod_list_foreach(itr, deplist) {
+ const char *symbol = kmod_module_dependency_symbol_get_symbol(itr);
+ // log_debug("Checking symbol %s", symbol);
+ if (regexec(&mod_filter_symbol, symbol, 0, NULL, 0) == 0) {
+ kmod_module_dependency_symbols_free_list(deplist);
+ log_debug("Module %s: symbol %s matched inclusion filter", kmod_module_get_name(mod), symbol);
+ return true;
+ }
+ }
+ kmod_module_dependency_symbols_free_list(deplist);
+ return false;
+ }
+
+ kmod_module_dependency_symbols_free_list(deplist);
+ return true;
+}
+
+
+static bool check_module_path(const char *path)
+{
+ if (arg_mod_filter_nopath && (regexec(&mod_filter_nopath, path, 0, NULL, 0) == 0)) {
+ log_debug("Path %s matched exclusion filter", path);
+ return false;
+ }
+
+ if (arg_mod_filter_path && (regexec(&mod_filter_path, path, 0, NULL, 0) != 0)) {
+ log_debug("Path %s matched inclusion filter", path);
+ return false;
+ }
+ return true;
+}
+
+static int install_module(struct kmod_module *mod)
+{
+ int ret = 0;
+ int state;
+ struct kmod_list *itr, *modlist = NULL;
+ const char *path = NULL;
+ const char *name = NULL;
+ state = kmod_module_get_initstate(mod);
+
+ name = kmod_module_get_name(mod);
+ if (arg_mod_filter_noname && (regexec(&mod_filter_noname, name, 0, NULL, 0) == 0))
+ return 0;
+
+ if (arg_hostonly && (state != KMOD_MODULE_BUILTIN) && (state != KMOD_MODULE_LIVE)) {
+ log_debug("dracut_install '%s' not hostonly", name);
+ return 0;
+ }
+
+ path = kmod_module_get_path(mod);
+ if (!path)
+ return -ENOENT;
+
+ if (check_hashmap(items_failed, path))
+ return 1;
+
+ if (check_hashmap(items, path))
+ return 0;
+
+ if (!check_module_path(path) || !check_module_symbols(mod)) {
+ log_debug("No symbol or patch match for '%s'", path);
+ return 0;
+ }
+
+ log_debug("dracut_install '%s'", path);
+ ret = dracut_install(path, path, false, false, true);
+ if (ret == 0) {
+ log_debug("dracut_install '%s' OK", kmod_module_get_name(mod));
+ } else if (!arg_optional) {
+ if (!arg_silent)
+ log_error("dracut_install '%s' ERROR", kmod_module_get_name(mod));
+ return ret;
+ }
+ install_firmware(mod);
+
+ modlist = kmod_module_get_dependencies(mod);
+ kmod_list_foreach(itr, modlist) {
+ mod = kmod_module_get_module(itr);
+ path = kmod_module_get_path(mod);
+ name = kmod_module_get_name(mod);
+ if (arg_mod_filter_noname && (regexec(&mod_filter_noname, name, 0, NULL, 0) == 0)) {
+ kmod_module_unref(mod);
+ continue;
+ }
+ ret = dracut_install(path, path, false, false, true);
+ if (ret == 0) {
+ log_debug("dracut_install '%s' OK", kmod_module_get_name(mod));
+ install_firmware(mod);
+ } else {
+ log_error("dracut_install '%s' ERROR", kmod_module_get_name(mod));
+ }
+ kmod_module_unref(mod);
+ }
+ kmod_module_unref_list(modlist);
+
+ return ret;
+}
+
+static int install_modules(int argc, char **argv)
+{
+ struct kmod_ctx *ctx = NULL;
+ struct kmod_list *itr, *modlist = NULL;
+ struct kmod_module *mod = NULL, *mod_o = NULL;
+
+ const char *modname = NULL;
+ int i;
+
+ ctx = kmod_new(kerneldir, NULL);
+
+ for (i = 0; i < argc; i++) {
+ int r = 0;
+ int ret = 0;
+ log_debug("Handle module '%s'", argv[i]);
+
+ if (argv[i][0] == '/') {
+ r = kmod_module_new_from_path(ctx, argv[i], &mod_o);
+ if (r < 0) {
+ log_debug("Failed to lookup modules path '%s': %m", argv[i]);
+ if (!arg_optional)
+ return -ENOENT;
+ continue;
+ }
+ /* Check, if we have to load another module with that name instead */
+ modname = kmod_module_get_name(mod_o);
+ if (!modname) {
+ if (!arg_optional) {
+ if (!arg_silent)
+ log_error("Failed to get name for module '%s'", argv[i]);
+ return -ENOENT;
+ }
+ log_info("Failed to get name for module '%s'", argv[i]);
+ continue;
+ }
+ r = kmod_module_new_from_lookup(ctx, modname, &modlist);
+ kmod_module_unref(mod_o);
+ if (r < 0) {
+ if (!arg_optional) {
+ if (!arg_silent)
+ log_error("3 Failed to lookup alias '%s': %d", modname, r);
+ return -ENOENT;
+ }
+ log_info("3 Failed to lookup alias '%s': %d", modname, r);
+ continue;
+ }
+ if (!modlist) {
+ if (!arg_optional) {
+ if (!arg_silent)
+ log_error("Failed to find module '%s' %s", modname, argv[i]);
+ return -ENOENT;
+ }
+ log_info("Failed to find module '%s' %s", modname, argv[i]);
+ continue;
+ }
+ kmod_list_foreach(itr, modlist) {
+ mod = kmod_module_get_module(itr);
+ ret = install_module(mod);
+ }
+ kmod_module_unref_list(modlist);
+ modlist = 0;
+ } else if (argv[i][0] == '=') {
+ char *path1, *path2, *path3;
+ FTS *fts;
+ log_debug("Handling =%s", &argv[i][1]);
+ /* FIXME and add more paths*/
+ {
+ int r;
+ r = asprintf(&path2, "%s/kernel/%s", kerneldir, &argv[i][1]);
+ if (r < 0) {
+ log_error("Out of memory!");
+ exit(EXIT_FAILURE);
+ }
+
+ r = asprintf(&path1, "%s/extra/%s", kerneldir, &argv[i][1]);
+ if (r < 0) {
+ log_error("Out of memory!");
+ exit(EXIT_FAILURE);
+ }
+
+ r = asprintf(&path3, "%s/updates/%s", kerneldir, &argv[i][1]);
+ if (r < 0) {
+ log_error("Out of memory!");
+ exit(EXIT_FAILURE);
+ }
+
+ char *paths[] = { path1, path2, path3, NULL };
+ fts = fts_open(paths, FTS_COMFOLLOW|FTS_NOCHDIR|FTS_NOSTAT|FTS_LOGICAL, NULL);
+ }
+ for (FTSENT *ftsent = fts_read(fts); ftsent != NULL; ftsent = fts_read(fts)) {
+ if((ftsent->fts_info == FTS_D) && !check_module_path(ftsent->fts_accpath)) {
+ fts_set(fts, ftsent, FTS_SKIP);
+ log_debug("Skipping %s", ftsent->fts_accpath);
+ continue;
+ }
+ if((ftsent->fts_info != FTS_F) && (ftsent->fts_info != FTS_SL)) {
+ log_debug("Ignoring %s", ftsent->fts_accpath);
+ continue;
+ }
+ log_debug("Handling %s", ftsent->fts_accpath);
+ r = kmod_module_new_from_path(ctx, ftsent->fts_accpath, &mod_o);
+ if (r < 0) {
+ log_debug("Failed to lookup modules path '%s': %m", ftsent->fts_accpath);
+ continue;
+ }
+#if 1
+ /* Check, if we have to load another module with that name instead */
+ modname = kmod_module_get_name(mod_o);
+ if (!modname) {
+ log_error("Failed to get name for module '%s'", ftsent->fts_accpath);
+ continue;
+ }
+ r = kmod_module_new_from_lookup(ctx, modname, &modlist);
+ kmod_module_unref(mod_o);
+ if (r < 0) {
+ log_error("2 Failed to lookup alias '%s': %m", modname);
+ kmod_module_unref_list(modlist);
+ continue;
+ }
+ if (!modlist) {
+ log_error("Failed to find module '%s' %s", modname, ftsent->fts_accpath);
+ kmod_module_unref_list(modlist);
+ continue;
+ }
+ kmod_list_foreach(itr, modlist) {
+ mod = kmod_module_get_module(itr);
+ ret = install_module(mod);
+ kmod_module_unref(mod);
+ }
+ kmod_module_unref_list(modlist);
+ modlist = 0;
+#else
+ ret = install_module(mod_o);
+ kmod_module_unref(mod_o);
+#endif
+
+ }
+ if (errno) {
+ log_error("FTS ERROR: %m");
+ }
+ fts_close(fts);
+ free(path1); path1 = NULL;
+ free(path2); path2 = NULL;
+ free(path3); path3 = NULL;
+ } else {
+ char *modname = argv[i];
+ if (endswith(modname, ".ko")) {
+ int len = strlen(modname);
+ modname[len-3]=0;
+ }
+ if (endswith(modname, ".ko.xz") || endswith(modname, ".ko.gz")) {
+ int len = strlen(modname);
+ modname[len-6]=0;
+ }
+ r = kmod_module_new_from_lookup(ctx, modname, &modlist);
+ if (r < 0) {
+ if (!arg_optional) {
+ if (!arg_silent)
+ log_error("Failed to lookup alias '%s': %m", modname);
+ return -ENOENT;
+ }
+ log_info("Failed to lookup alias '%s': %m", modname);
+ continue;
+ }
+ if (!modlist) {
+ if (!arg_optional) {
+ if (!arg_silent)
+ log_error("Failed to find module '%s'", modname);
+ return -ENOENT;
+ }
+ log_info("Failed to find module '%s'", modname);
+ continue;
+ }
+ kmod_list_foreach(itr, modlist) {
+ mod = kmod_module_get_module(itr);
+ ret = install_module(mod);
+ kmod_module_unref(mod);
+ }
+ kmod_module_unref_list(modlist);
+ modlist = 0;
+ }
+
+ if ((ret != 0) && (!arg_optional)) {
+ if (!arg_silent)
+ log_error("ERROR: installing '%s'", argv[i]);
+ return EXIT_FAILURE;
+ }
+ }
+ return EXIT_SUCCESS;
+}
+
int main(int argc, char **argv)
{
int r;
char *i;
+ char *path = NULL;
r = parse_argv(argc, argv);
if (r <= 0)
@@ -993,6 +1447,17 @@ int main(int argc, char **argv)
log_open();
+ path = getenv("PATH");
+
+ if (path == NULL) {
+ log_error("PATH is not set");
+ exit(EXIT_FAILURE);
+ }
+
+ log_debug("PATH=%s", path);
+
+ pathdirs = strv_split(path, ":");
+
umask(0022);
if (destrootdir == NULL || strlen(destrootdir) == 0) {
@@ -1059,7 +1524,9 @@ int main(int argc, char **argv)
}
}
- if (arg_resolvelazy) {
+ if (arg_module) {
+ r = install_modules(argc - optind, &argv[optind]);
+ } else if (arg_resolvelazy) {
r = resolve_lazy(argc - optind, &argv[optind]);
} else if (arg_all || (argc - optind > 2) || ((argc - optind) == 1)) {
r = install_all(argc - optind, &argv[optind]);
@@ -1085,6 +1552,7 @@ int main(int argc, char **argv)
hashmap_free(items_failed);
free(destrootdir);
-
+ strv_free(firmwaredirs);
+ strv_free(pathdirs);
return r;
}
diff --git a/modules.d/50drm/module-setup.sh b/modules.d/50drm/module-setup.sh
index 55a214e..e0b2959 100755
--- a/modules.d/50drm/module-setup.sh
+++ b/modules.d/50drm/module-setup.sh
@@ -15,40 +15,6 @@ installkernel() {
local _modname
# Include KMS capable drm drivers
- drm_module_filter() {
- local _drm_drivers='drm_crtc_init'
- local _ret
- # subfunctions inherit following FDs
- local _merge=8 _side2=9
- function nmf1() {
- local _fname _fcont
- while read _fname || [ -n "$_fname" ]; do
- case "$_fname" in
- *.ko) _fcont="$(< $_fname)" ;;
- *.ko.gz) _fcont="$(gzip -dc $_fname)" ;;
- *.ko.xz) _fcont="$(xz -dc $_fname)" ;;
- esac
- [[ $_fcont =~ $_drm_drivers
- && ! $_fcont =~ iw_handler_get_spy ]] \
- && echo "$_fname"
- done
- }
- function rotor() {
- local _f1 _f2
- while read _f1 || [ -n "$_f1" ]; do
- echo "$_f1"
- if read _f2; then
- echo "$_f2" 1>&${_side2}
- fi
- done | nmf1 1>&${_merge}
- }
- # Use two parallel streams to filter alternating modules.
- set +x
- eval "( ( rotor ) ${_side2}>&1 | nmf1 ) ${_merge}>&1"
- [[ $debug ]] && set -x
- return 0
- }
-
if [[ "$(uname -p)" == arm* ]]; then
# arm specific modules needed by drm
instmods \
@@ -62,20 +28,19 @@ installkernel() {
instmods amdkfd hyperv_fb
- for _modname in $(find_kernel_modules_by_path drivers/gpu/drm \
- | drm_module_filter) ; do
- # if the hardware is present, include module even if it is not currently loaded,
- # as we could e.g. be in the installer; nokmsboot boot parameter will disable
- # loading of the driver if needed
- if [[ $hostonly ]] && modinfo -F alias $_modname | sed -e 's,\?,\.,g' -e 's,\*,\.\*,g' \
- | grep -qxf - /sys/bus/{pci/devices,soc/devices/soc?}/*/modalias 2>/dev/null; then
- hostonly='' instmods $_modname
- # if radeon.ko is installed, we want amdkfd also
- if strstr "$_modname" radeon.ko; then
- hostonly='' instmods amdkfd
+ # if the hardware is present, include module even if it is not currently loaded,
+ # as we could e.g. be in the installer; nokmsboot boot parameter will disable
+ # loading of the driver if needed
+ if [[ $hostonly ]]; then
+ for i in /sys/bus/{pci/devices,soc/devices/soc?}/*/modalias; do
+ [[ -e $i ]] || continue
+ if hostonly="" dracut_instmods -s "drm_crtc_init" $(<$i) 2>/dev/null; then
+ if strstr $(modinfo -F filename $(<$i) 2>/dev/null) radeon.ko; then
+ hostonly='' instmods amdkfd
+ fi
fi
- continue
- fi
- instmods $_modname
- done
+ done
+ else
+ dracut_instmods -s "drm_crtc_init" "=drivers/gpu/drm"
+ fi
}
diff --git a/modules.d/90crypt/module-setup.sh b/modules.d/90crypt/module-setup.sh
index 5d964f4..6c377ef 100755
--- a/modules.d/90crypt/module-setup.sh
+++ b/modules.d/90crypt/module-setup.sh
@@ -24,8 +24,10 @@ depends() {
# called by dracut
installkernel() {
- instmods dm_crypt =crypto
hostonly="" instmods drbg
+ arch=$(arch)
+ [[ $arch == x86_64 ]] && arch=x86
+ instmods dm_crypt =crypto =drivers/crypto =arch/$arch/crypto
}
# called by dracut
diff --git a/modules.d/90dm/module-setup.sh b/modules.d/90dm/module-setup.sh
index 419e8b1..2b8e39f 100755
--- a/modules.d/90dm/module-setup.sh
+++ b/modules.d/90dm/module-setup.sh
@@ -13,8 +13,7 @@ depends() {
# called by dracut
installkernel() {
- instmods =drivers/md
- instmods dm_mod dm-cache dm-cache-mq dm-cache-cleaner
+ instmods =drivers/md dm_mod dm-cache dm-cache-mq dm-cache-cleaner
}
# called by dracut
diff --git a/modules.d/90kernel-modules/module-setup.sh b/modules.d/90kernel-modules/module-setup.sh
index 300adc7..e97d598 100755
--- a/modules.d/90kernel-modules/module-setup.sh
+++ b/modules.d/90kernel-modules/module-setup.sh
@@ -2,54 +2,25 @@
# called by dracut
installkernel() {
- if [[ -z $drivers ]]; then
- block_module_filter() {
- local _blockfuncs='ahci_platform_get_resources|ata_scsi_ioctl|scsi_add_host|blk_cleanup_queue|register_mtd_blktrans|scsi_esp_register|register_virtio_device|usb_stor_disconnect|mmc_add_host|sdhci_add_host'
- # subfunctions inherit following FDs
- local _merge=8 _side2=9
- function bmf1() {
- local _f
- while read _f || [ -n "$_f" ]; do case "$_f" in
- *.ko) [[ $(< $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
- *.ko.gz) [[ $(gzip -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
- *.ko.xz) [[ $(xz -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
- esac
- done
- return 0
- }
- function rotor() {
- local _f1 _f2
- while read _f1 || [ -n "$_f1" ]; do
- echo "$_f1"
- if read _f2; then
- echo "$_f2" 1>&${_side2}
- fi
- done | bmf1 1>&${_merge}
- return 0
- }
- # Use two parallel streams to filter alternating modules.
- set +x
- eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"
- [[ $debug ]] && set -x
- return 0
- }
+ local _blockfuncs='ahci_platform_get_resources|ata_scsi_ioctl|scsi_add_host|blk_cleanup_queue|register_mtd_blktrans|scsi_esp_register|register_virtio_device|usb_stor_disconnect|mmc_add_host|sdhci_add_host|scsi_add_host_with_dma'
+ if [[ -z $drivers ]]; then
hostonly='' instmods \
sr_mod sd_mod scsi_dh ata_piix hid_generic unix \
- ehci-hcd ehci-pci ehci-platform \
+ ehci-hcd ehci-pci \
ohci-hcd ohci-pci \
uhci-hcd \
xhci-hcd xhci-pci xhci-plat-hcd \
+ ehci-platform
+
+ instmods \
"=drivers/hid" \
"=drivers/input/serio" \
"=drivers/input/keyboard" \
- "=drivers/usb/storage"
-
- instmods \
yenta_socket scsi_dh_rdac scsi_dh_emc scsi_dh_alua \
atkbd i8042 usbhid firewire-ohci pcmcia hv-vmbus \
virtio virtio_blk virtio_ring virtio_pci virtio_scsi \
- "=drivers/pcmcia" =ide
+ "=drivers/pcmcia" =ide "=drivers/usb/storage"
if [[ "$(uname -p)" == arm* ]]; then
# arm specific modules
@@ -62,20 +33,16 @@ installkernel() {
${NULL}
fi
-
- find_kernel_modules | block_module_filter | instmods
+ dracut_instmods -s "${_blockfuncs}" "=drivers"
# if not on hostonly mode, install all known filesystems,
# if the required list is not set via the filesystems variable
if ! [[ $hostonly ]]; then
if [[ -z $filesystems ]]; then
- silent_omit_drivers="kernel/fs/nfs|kernel/fs/nfsd|kernel/fs/lockd" \
- instmods '=fs'
+ dracut_instmods -P ".*/(kernel/fs/nfs|kernel/fs/nfsd|kernel/fs/lockd)/.*" '=fs'
fi
else
- for i in "${host_fs_types[@]}"; do
- hostonly='' instmods $i
- done
+ hostonly='' instmods "${host_fs_types[@]}"
fi
fi
:
diff --git a/modules.d/90kernel-network-modules/module-setup.sh b/modules.d/90kernel-network-modules/module-setup.sh
index 18d7d96..c004ff8 100755
--- a/modules.d/90kernel-network-modules/module-setup.sh
+++ b/modules.d/90kernel-network-modules/module-setup.sh
@@ -14,47 +14,14 @@ depends() {
installkernel() {
# Include wired net drivers, excluding wireless
local _arch=$(uname -m)
+ local _net_drivers='eth_type_trans|register_virtio_device|usbnet_open'
+ local _unwanted_drivers='/(wireless|isdn|uwb|net/ethernet|net/phy|net/team)/'
- net_module_filter() {
- local _net_drivers='eth_type_trans|register_virtio_device|usbnet_open'
- local _unwanted_drivers='/(wireless|isdn|uwb|net/ethernet|net/phy|net/team)/'
- local _ret
- # subfunctions inherit following FDs
- local _merge=8 _side2=9
- function nmf1() {
- local _fname _fcont
- while read _fname; do
- [[ $_fname =~ $_unwanted_drivers ]] && continue
- case "$_fname" in
- *.ko) _fcont="$(< $_fname)" ;;
- *.ko.gz) _fcont="$(gzip -dc $_fname)" ;;
- *.ko.xz) _fcont="$(xz -dc $_fname)" ;;
- esac
- [[ $_fcont =~ $_net_drivers
- && ! $_fcont =~ iw_handler_get_spy ]] \
- && echo "$_fname"
- done
- return 0
- }
- function rotor() {
- local _f1 _f2
- while read _f1; do
- echo "$_f1"
- if read _f2; then
- echo "$_f2" 1>&${_side2}
- fi
- done | nmf1 1>&${_merge}
- return 0
- }
- # Use two parallel streams to filter alternating modules.
- set +x
- eval "( ( rotor ) ${_side2}>&1 | nmf1 ) ${_merge}>&1"
- [[ $debug ]] && set -x
- return 0
- }
+ if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then
+ _s390drivers="=drivers/s390/net"
+ fi
- { find_kernel_modules_by_path drivers/net; if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then find_kernel_modules_by_path drivers/s390/net; fi; } \
- | net_module_filter | instmods
+ dracut_instmods -P ".*${_unwanted_drivers}.*" -s "$_net_drivers" "=drivers/net" ${_s390drivers:+"$_s390drivers"}
#instmods() will take care of hostonly
instmods \
diff --git a/modules.d/90multipath/module-setup.sh b/modules.d/90multipath/module-setup.sh
index a808678..27817bd 100755
--- a/modules.d/90multipath/module-setup.sh
+++ b/modules.d/90multipath/module-setup.sh
@@ -51,41 +51,14 @@ cmdline() {
installkernel() {
local _ret
local _arch=$(uname -m)
- mp_mod_filter() {
- local _funcs='scsi_register_device_handler|dm_dirty_log_type_register|dm_register_path_selector|dm_register_target'
- # subfunctions inherit following FDs
- local _merge=8 _side2=9
- function bmf1() {
- local _f
- while read _f || [ -n "$_f" ]; do
- case "$_f" in
- *.ko) [[ $(< $_f) =~ $_funcs ]] && echo "$_f" ;;
- *.ko.gz) [[ $(gzip -dc <$_f) =~ $_funcs ]] && echo "$_f" ;;
- *.ko.xz) [[ $(xz -dc <$_f) =~ $_funcs ]] && echo "$_f" ;;
- esac
- done
- return 0
- }
+ local _funcs='scsi_register_device_handler|dm_dirty_log_type_register|dm_register_path_selector|dm_register_target'
+ local _s390
- function rotor() {
- local _f1 _f2
- while read _f1 || [ -n "$_f1" ]; do
- echo "$_f1"
- if read _f2; then
- echo "$_f2" 1>&${_side2}
- fi
- done | bmf1 1>&${_merge}
- return 0
- }
- # Use two parallel streams to filter alternating modules.
- set +x
- eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"
- [[ $debug ]] && set -x
- return 0
- }
+ if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then
+ _s390drivers="=drivers/s390/scsi"
+ fi
- ( find_kernel_modules_by_path drivers/scsi; if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then find_kernel_modules_by_path drivers/s390/scsi; fi;
- find_kernel_modules_by_path drivers/md ) | mp_mod_filter | hostonly='' instmods
+ hostonly='' dracut_instmods -s "$_funcs" "=drivers/scsi" "=drivers/md" ${_s390drivers:+"$_s390drivers"}
}
# called by dracut
diff --git a/modules.d/95iscsi/module-setup.sh b/modules.d/95iscsi/module-setup.sh
index beb80e3..203e313 100755
--- a/modules.d/95iscsi/module-setup.sh
+++ b/modules.d/95iscsi/module-setup.sh
@@ -157,44 +157,17 @@ depends() {
# called by dracut
installkernel() {
local _arch=$(uname -m)
+ local _funcs='iscsi_register_transport'
instmods bnx2i qla4xxx cxgb3i cxgb4i be2iscsi
hostonly="" instmods iscsi_tcp iscsi_ibft crc32c iscsi_boot_sysfs
- iscsi_module_filter() {
- local _funcs='iscsi_register_transport'
- # subfunctions inherit following FDs
- local _merge=8 _side2=9
- function bmf1() {
- local _f
- while read _f || [ -n "$_f" ]; do
- case "$_f" in
- *.ko) [[ $(< $_f) =~ $_funcs ]] && echo "$_f" ;;
- *.ko.gz) [[ $(gzip -dc <$_f) =~ $_funcs ]] && echo "$_f" ;;
- *.ko.xz) [[ $(xz -dc <$_f) =~ $_funcs ]] && echo "$_f" ;;
- esac
- done
- return 0
- }
-
- function rotor() {
- local _f1 _f2
- while read _f1 || [ -n "$_f1" ]; do
- echo "$_f1"
- if read _f2; then
- echo "$_f2" 1>&${_side2}
- fi
- done | bmf1 1>&${_merge}
- return 0
- }
- # Use two parallel streams to filter alternating modules.
- set +x
- eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"
- [[ $debug ]] && set -x
- return 0
- }
- { find_kernel_modules_by_path drivers/scsi; if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then find_kernel_modules_by_path drivers/s390/scsi; fi;} \
- | iscsi_module_filter | instmods
+ if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then
+ _s390drivers="=drivers/s390/scsi"
+ fi
+
+ dracut_instmods -s "$_funcs" "=drivers/scsi" ${_s390drivers:+"$_s390drivers"}
+
}
# called by dracut
diff --git a/modules.d/95nfs/module-setup.sh b/modules.d/95nfs/module-setup.sh
index 6f039bd..9767e57 100755
--- a/modules.d/95nfs/module-setup.sh
+++ b/modules.d/95nfs/module-setup.sh
@@ -25,7 +25,7 @@ depends() {
# called by dracut
installkernel() {
- instmods nfs sunrpc ipv6 nfsv2 nfsv3 nfsv4 nfs_acl nfs_layout_nfsv41_files
+ instmods =net/sunrpc =fs/nfs ipv6 nfs_acl nfs_layout_nfsv41_files
}
cmdline() {