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
[[ -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*}
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
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
exit 1
fi
- [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && rm -fr -- "$DRACUT_KERNEL_LAZY_HASHDIR"
}
[[ "$kernel_current" ]] || export kernel_current=$(uname -r)
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
}
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
-
+#undef _FILE_OFFSET_BITS
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#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"
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);
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;
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) {
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);
enum {
ARG_VERSION = 0x100,
+ ARG_SILENT,
+ ARG_KERNELDIR,
+ ARG_FIRMWAREDIRS,
ARG_DEBUG
};
{"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);
case ARG_DEBUG:
arg_loglevel = LOG_DEBUG;
break;
+ case ARG_SILENT:
+ arg_silent = true;
+ break;
case 'v':
arg_loglevel = LOG_INFO;
break;
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;
}
}
+ 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);
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;
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)
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) {
}
}
- 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]);
hashmap_free(items_failed);
free(destrootdir);
-
+ strv_free(firmwaredirs);
+ strv_free(pathdirs);
return r;
}