Откуда встроенный в systemd 'kmod' получает псевдонимы модулей?

udev загружает необходимые модули драйверов при подключении устройства с возможностью горячей замены. Это делается следующим правилом udev

DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"

Поэтому kmod вызывается, например. kmod load hid:b0005g0001v0000045Ep000002E0

Исходный код встроенного kmod задокументирован здесь< /а>

hid:b0005g0001v0000045Ep000002E0 — это просто псевдоним модуля вроде hid_xpadneo.

Я знаю, что в /usr/lib/modules/$(uname -r)/modules.alias создается файл с именем modules.alias, где эти псевдонимы перечислены следующим образом:

alias hid:b0005g*v0000045Ep000002E0 hid_xpadneo
alias hid:b0005g*v0000045Ep000002FD hid_xpadneo

Этот файл генерируется из всех драйверов и их MODULE_DEVICE_TABLE во время компиляции.

К сожалению, я не могу найти, где именно kmod читает этот файл или откуда он получает информацию о псевдониме.

Следовательно: как kmod узнает, какой псевдоним соответствует какому модулю?


person ataraxis    schedule 05.01.2019    source источник
comment
В модуле kmod есть список файлов, и все они читаются как здесь.   -  person KamilCuk    schedule 06.01.2019
comment
Я собираюсь удалить этот вопрос, так как никто не проголосовал за него - и поэтому мне больше не разрешено что-то спрашивать... Кто-то против удаления, скажите, пожалуйста.   -  person ataraxis    schedule 21.02.2019


Ответы (1)


Из systemd/udev-builtin-kmod.c :

static int builtin_kmod_init(void) {
        ...
        kmod_load_resources(ctx);
        ...
}

Из kmod/libkmod.c:

static struct _index_files {
    const char *fn;
    const char *prefix;
} index_files[] = {
    [KMOD_INDEX_MODULES_DEP] = { .fn = "modules.dep", .prefix = "" },
    [KMOD_INDEX_MODULES_ALIAS] = { .fn = "modules.alias", .prefix = "alias " },
    [KMOD_INDEX_MODULES_SYMBOL] = { .fn = "modules.symbols", .prefix = "alias "},
    [KMOD_INDEX_MODULES_BUILTIN] = { .fn = "modules.builtin", .prefix = ""},
};

...

KMOD_EXPORT int kmod_load_resources(struct kmod_ctx *ctx)
{
    for (i = 0; i < _KMOD_INDEX_MODULES_SIZE; i++) {
        ...
        snprintf(path, sizeof(path), "%s/%s.bin", ctx->dirname,
                            index_files[i].fn);
        ctx->indexes[i] = index_mm_open(ctx, path,
                        &ctx->indexes_stamp[i]);
        ...
    }
}

Из kmon/libkmod-index.c :

struct index_mm *index_mm_open(struct kmod_ctx *ctx, const char *filename,
                        unsigned long long *stamp)
{
    ...
    if ((fd = open(filename, O_RDONLY|O_CLOEXEC)) < 0) {
    ...
}

kmod читает и индексирует все возможные файлы modules.dep modules.alias modules.symbols и modules.builtin и получает информацию о псевдонимах из этих файлов.

Затем позже в udev-buildin-kmod.c :

static int builtin_kmod(sd_device *dev, int argc, char *argv[], bool test) {
        ...
        for (i = 2; argv[i]; i++)
                (void) module_load_and_warn(ctx, argv[i], false);
        ...
}

И из systemd/module-util.c< /а>:

int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) {
    ...
    r = kmod_module_new_from_lookup(ctx, module, &modlist);
    if (r < 0)
            return log_full_errno(verbose ? LOG_ERR : LOG_DEBUG, r,
                                  "Failed to lookup module alias '%s': %m", module);

    ...
}

А внутри kmod_module_new_from_lookup выполняется поиск псевдонима модуля, т.е. данные, считанные в объект kmod, просматриваются.

person KamilCuk    schedule 05.01.2019
comment
Отлично, это недостающее звено :) Спасибо! - person ataraxis; 06.01.2019