Check all modalias files in /sys/devices for modules
and add the corresponding kernel modules to the host module list https://bugzilla.redhat.com/show_bug.cgi?id=1467427master
parent
26264af7f5
commit
3ad12c7be8
|
@ -52,13 +52,6 @@ if ! [[ -d $initdir ]]; then
|
||||||
mkdir -p "$initdir"
|
mkdir -p "$initdir"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $DRACUT_KERNEL_LAZY ]] && ! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
|
|
||||||
if ! [[ -d "$initdir/.kernelmodseen" ]]; then
|
|
||||||
mkdir -p "$initdir/.kernelmodseen"
|
|
||||||
fi
|
|
||||||
DRACUT_KERNEL_LAZY_HASHDIR="$initdir/.kernelmodseen"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! [[ $kernel ]]; then
|
if ! [[ $kernel ]]; then
|
||||||
kernel=$(uname -r)
|
kernel=$(uname -r)
|
||||||
export kernel
|
export kernel
|
||||||
|
@ -172,6 +165,13 @@ if ! [[ -x $DRACUT_INSTALL ]]; then
|
||||||
exit 10
|
exit 10
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ $hostonly == "-h" ]]; then
|
||||||
|
if ! [[ $DRACUT_KERNEL_MODALIASES ]] || ! [[ -d "$DRACUT_KERNEL_MODALIASES" ]]; then
|
||||||
|
export DRACUT_KERNEL_MODALIASES="${DRACUT_TMPDIR}/modaliases"
|
||||||
|
$DRACUT_INSTALL --modalias > "$DRACUT_KERNEL_MODALIASES"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
[[ $DRACUT_RESOLVE_LAZY ]] || export DRACUT_RESOLVE_DEPS=1
|
[[ $DRACUT_RESOLVE_LAZY ]] || export DRACUT_RESOLVE_DEPS=1
|
||||||
inst_dir() {
|
inst_dir() {
|
||||||
[[ -e ${initdir}/"$1" ]] && return 0 # already there
|
[[ -e ${initdir}/"$1" ]] && return 0 # already there
|
||||||
|
@ -935,9 +935,6 @@ for_each_kmod_dep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
dracut_kernel_post() {
|
dracut_kernel_post() {
|
||||||
local _moddirname=${srcmods%%/lib/modules/*}
|
|
||||||
local _pid
|
|
||||||
|
|
||||||
for _f in modules.builtin.bin modules.builtin modules.order; do
|
for _f in modules.builtin.bin modules.builtin modules.order; do
|
||||||
[[ $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f"
|
[[ $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f"
|
||||||
done
|
done
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <libkmod.h>
|
#include <libkmod.h>
|
||||||
#include <fts.h>
|
#include <fts.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
|
@ -54,6 +55,7 @@ static bool arg_optional = false;
|
||||||
static bool arg_silent = false;
|
static bool arg_silent = false;
|
||||||
static bool arg_all = false;
|
static bool arg_all = false;
|
||||||
static bool arg_module = false;
|
static bool arg_module = false;
|
||||||
|
static bool arg_modalias = false;
|
||||||
static bool arg_resolvelazy = false;
|
static bool arg_resolvelazy = false;
|
||||||
static bool arg_resolvedeps = false;
|
static bool arg_resolvedeps = false;
|
||||||
static bool arg_hostonly = false;
|
static bool arg_hostonly = false;
|
||||||
|
@ -794,6 +796,7 @@ static void usage(int status)
|
||||||
" --kerneldir Specify the kernel module directory\n"
|
" --kerneldir Specify the kernel module directory\n"
|
||||||
" --firmwaredirs Specify the firmware directory search path with : separation\n"
|
" --firmwaredirs Specify the firmware directory search path with : separation\n"
|
||||||
" --silent Don't display error messages for kernel module install\n"
|
" --silent Don't display error messages for kernel module install\n"
|
||||||
|
" --modalias Only generate module list from /sys/devices modalias list\n"
|
||||||
" -o --optional If kernel module does not exist, do not fail\n"
|
" -o --optional If kernel module does not exist, do not fail\n"
|
||||||
" -p --mod-filter-path Filter kernel modules by path regexp\n"
|
" -p --mod-filter-path Filter kernel modules by path regexp\n"
|
||||||
" -P --mod-filter-nopath Exclude kernel modules by path regexp\n"
|
" -P --mod-filter-nopath Exclude kernel modules by path regexp\n"
|
||||||
|
@ -818,6 +821,7 @@ static int parse_argv(int argc, char *argv[])
|
||||||
enum {
|
enum {
|
||||||
ARG_VERSION = 0x100,
|
ARG_VERSION = 0x100,
|
||||||
ARG_SILENT,
|
ARG_SILENT,
|
||||||
|
ARG_MODALIAS,
|
||||||
ARG_KERNELDIR,
|
ARG_KERNELDIR,
|
||||||
ARG_FIRMWAREDIRS,
|
ARG_FIRMWAREDIRS,
|
||||||
ARG_DEBUG
|
ARG_DEBUG
|
||||||
|
@ -843,6 +847,7 @@ static int parse_argv(int argc, char *argv[])
|
||||||
{"mod-filter-symbol", required_argument, NULL, 's'},
|
{"mod-filter-symbol", required_argument, NULL, 's'},
|
||||||
{"mod-filter-nosymbol", required_argument, NULL, 'S'},
|
{"mod-filter-nosymbol", required_argument, NULL, 'S'},
|
||||||
{"mod-filter-noname", required_argument, NULL, 'N'},
|
{"mod-filter-noname", required_argument, NULL, 'N'},
|
||||||
|
{"modalias", no_argument, NULL, ARG_MODALIAS},
|
||||||
{"silent", no_argument, NULL, ARG_SILENT},
|
{"silent", no_argument, NULL, ARG_SILENT},
|
||||||
{"kerneldir", required_argument, NULL, ARG_KERNELDIR},
|
{"kerneldir", required_argument, NULL, ARG_KERNELDIR},
|
||||||
{"firmwaredirs", required_argument, NULL, ARG_FIRMWAREDIRS},
|
{"firmwaredirs", required_argument, NULL, ARG_FIRMWAREDIRS},
|
||||||
|
@ -863,6 +868,10 @@ static int parse_argv(int argc, char *argv[])
|
||||||
case ARG_SILENT:
|
case ARG_SILENT:
|
||||||
arg_silent = true;
|
arg_silent = true;
|
||||||
break;
|
break;
|
||||||
|
case ARG_MODALIAS:
|
||||||
|
arg_modalias = true;
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
arg_loglevel = LOG_INFO;
|
arg_loglevel = LOG_INFO;
|
||||||
break;
|
break;
|
||||||
|
@ -949,6 +958,16 @@ static int parse_argv(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!kerneldir) {
|
||||||
|
struct utsname buf;
|
||||||
|
uname(&buf);
|
||||||
|
kerneldir = strdup(buf.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_modalias) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (arg_module) {
|
if (arg_module) {
|
||||||
if (!firmwaredirs) {
|
if (!firmwaredirs) {
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
|
@ -965,6 +984,7 @@ static int parse_argv(int argc, char *argv[])
|
||||||
firmwaredirs = strv_split(path, ":");
|
firmwaredirs = strv_split(path, ":");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!optind || optind == argc) {
|
if (!optind || optind == argc) {
|
||||||
log_error("No SOURCE argument given");
|
log_error("No SOURCE argument given");
|
||||||
usage(EXIT_FAILURE);
|
usage(EXIT_FAILURE);
|
||||||
|
@ -1297,12 +1317,94 @@ static int install_module(struct kmod_module *mod)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int modalias_list(struct kmod_ctx *ctx)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct kmod_list *loaded_list = NULL;
|
||||||
|
struct kmod_list *itr, *l;
|
||||||
|
_cleanup_fts_close_ FTS *fts = NULL;
|
||||||
|
|
||||||
|
{
|
||||||
|
char *paths[] = { "/sys/devices", NULL };
|
||||||
|
fts = fts_open(paths, FTS_NOCHDIR|FTS_NOSTAT, NULL);
|
||||||
|
}
|
||||||
|
for (FTSENT *ftsent = fts_read(fts); ftsent != NULL; ftsent = fts_read(fts)) {
|
||||||
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
|
_cleanup_kmod_module_unref_list_ struct kmod_list *list = NULL;
|
||||||
|
struct kmod_list *l;
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
char alias[2048];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (strncmp("modalias", ftsent->fts_name, 8) != 0)
|
||||||
|
continue;
|
||||||
|
if (!(f = fopen(ftsent->fts_accpath, "r")))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!fgets(alias, sizeof(alias), f))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
len = strlen(alias);
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (alias[len-1] == '\n')
|
||||||
|
alias[len-1] = 0;
|
||||||
|
|
||||||
|
err = kmod_module_new_from_lookup(ctx, alias, &list);
|
||||||
|
if (err < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
kmod_list_foreach(l, list) {
|
||||||
|
struct kmod_module *mod = kmod_module_get_module(l);
|
||||||
|
char *name = strdup(kmod_module_get_name(mod));
|
||||||
|
kmod_module_unref(mod);
|
||||||
|
hashmap_put(modules_loaded, name, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = kmod_module_new_from_loaded(ctx, &loaded_list);
|
||||||
|
if (err < 0) {
|
||||||
|
errno = err;
|
||||||
|
log_error("Could not get list of loaded modules: %m. Switching to non-hostonly mode.");
|
||||||
|
arg_hostonly = false;
|
||||||
|
} else {
|
||||||
|
kmod_list_foreach(itr, loaded_list) {
|
||||||
|
_cleanup_kmod_module_unref_list_ struct kmod_list *modlist = NULL;
|
||||||
|
|
||||||
|
struct kmod_module *mod = kmod_module_get_module(itr);
|
||||||
|
char *name = strdup(kmod_module_get_name(mod));
|
||||||
|
hashmap_put(modules_loaded, name, name);
|
||||||
|
kmod_module_unref(mod);
|
||||||
|
|
||||||
|
/* also put the modules from the new kernel in the hashmap,
|
||||||
|
* which resolve the name as an alias, in case a kernel module is
|
||||||
|
* renamed.
|
||||||
|
*/
|
||||||
|
err = kmod_module_new_from_lookup(ctx, name, &modlist);
|
||||||
|
if (err < 0)
|
||||||
|
continue;
|
||||||
|
if (!modlist)
|
||||||
|
continue;
|
||||||
|
kmod_list_foreach(l, modlist) {
|
||||||
|
mod = kmod_module_get_module(l);
|
||||||
|
char *name = strdup(kmod_module_get_name(mod));
|
||||||
|
hashmap_put(modules_loaded, name, name);
|
||||||
|
kmod_module_unref(mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kmod_module_unref_list(loaded_list);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int install_modules(int argc, char **argv)
|
static int install_modules(int argc, char **argv)
|
||||||
{
|
{
|
||||||
_cleanup_kmod_unref_ struct kmod_ctx *ctx = NULL;
|
_cleanup_kmod_unref_ struct kmod_ctx *ctx = NULL;
|
||||||
struct kmod_list *loaded_list = NULL;
|
struct kmod_list *itr;
|
||||||
struct kmod_list *itr, *l;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
struct kmod_module *mod = NULL, *mod_o = NULL;
|
struct kmod_module *mod = NULL, *mod_o = NULL;
|
||||||
|
|
||||||
|
@ -1311,38 +1413,34 @@ static int install_modules(int argc, char **argv)
|
||||||
|
|
||||||
ctx = kmod_new(kerneldir, NULL);
|
ctx = kmod_new(kerneldir, NULL);
|
||||||
if (arg_hostonly) {
|
if (arg_hostonly) {
|
||||||
err = kmod_module_new_from_loaded(ctx, &loaded_list);
|
char *modalias_file;
|
||||||
if (err < 0) {
|
modalias_file = getenv("DRACUT_KERNEL_MODALIASES");
|
||||||
errno = err;
|
|
||||||
log_error("Could not get list of loaded modules: %m. Switching to non-hostonly mode.");
|
if (modalias_file == NULL) {
|
||||||
arg_hostonly = false;
|
modalias_list(ctx);
|
||||||
} else {
|
} else {
|
||||||
kmod_list_foreach(itr, loaded_list) {
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
_cleanup_kmod_module_unref_list_ struct kmod_list *modlist = NULL;
|
if ((f = fopen(modalias_file, "r"))) {
|
||||||
|
char name[2048];
|
||||||
|
|
||||||
struct kmod_module *mod = kmod_module_get_module(itr);
|
while (!feof(f)) {
|
||||||
char *name = strdup(kmod_module_get_name(mod));
|
size_t len;
|
||||||
hashmap_put(modules_loaded, name, name);
|
|
||||||
kmod_module_unref(mod);
|
|
||||||
|
|
||||||
/* also put the modules from the new kernel in the hashmap,
|
if(!(fgets(name, sizeof(name), f)))
|
||||||
* which resolve the name as an alias, in case a kernel module is
|
continue;
|
||||||
* renamed.
|
len = strlen(name);
|
||||||
*/
|
|
||||||
err = kmod_module_new_from_lookup(ctx, name, &modlist);
|
if (len == 0)
|
||||||
if (err < 0)
|
continue;
|
||||||
continue;
|
|
||||||
if (!modlist)
|
if (name[len-1] == '\n')
|
||||||
continue;
|
name[len-1] = 0;
|
||||||
kmod_list_foreach(l, modlist) {
|
|
||||||
mod = kmod_module_get_module(l);
|
hashmap_put(modules_loaded, name, strdup(name));
|
||||||
char *name = strdup(kmod_module_get_name(mod));
|
|
||||||
hashmap_put(modules_loaded, name, name);
|
|
||||||
kmod_module_unref(mod);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kmod_module_unref_list(loaded_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
|
@ -1576,6 +1674,20 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
log_open();
|
log_open();
|
||||||
|
|
||||||
|
modules_loaded = hashmap_new(string_hash_func, string_compare_func);
|
||||||
|
if (arg_modalias) {
|
||||||
|
Iterator i;
|
||||||
|
char *name;
|
||||||
|
_cleanup_kmod_unref_ struct kmod_ctx *ctx = NULL;
|
||||||
|
ctx = kmod_new(kerneldir, NULL);
|
||||||
|
|
||||||
|
modalias_list(ctx);
|
||||||
|
HASHMAP_FOREACH(name, modules_loaded, i) {
|
||||||
|
printf("%s\n", name);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
path = getenv("PATH");
|
path = getenv("PATH");
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
|
@ -1614,7 +1726,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
items = hashmap_new(string_hash_func, string_compare_func);
|
items = hashmap_new(string_hash_func, string_compare_func);
|
||||||
items_failed = hashmap_new(string_hash_func, string_compare_func);
|
items_failed = hashmap_new(string_hash_func, string_compare_func);
|
||||||
modules_loaded = hashmap_new(string_hash_func, string_compare_func);
|
|
||||||
|
|
||||||
if (!items || !items_failed || !modules_loaded) {
|
if (!items || !items_failed || !modules_loaded) {
|
||||||
log_error("Out of memory");
|
log_error("Out of memory");
|
||||||
|
|
Loading…
Reference in New Issue