systemd 内置 'kmod' 从哪里获取模块别名
Where does the systemd builtin 'kmod' gets the module aliases from
udev 在插入支持热插拔的设备时加载必要的驱动程序模块。这是通过以下 udev-rule
DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"
因此,kmod 被调用,例如kmod load hid:b0005g0001v0000045Ep000002E0
记录了内置 kmod 的来源 here
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_TABLEs 生成的。
遗憾的是,我无法找到 kmod 在该文件中读取的确切位置或从中获取别名信息的位置。
因此:kmod 如何知道哪个别名代表哪个模块?
来自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]);
...
}
}
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
并从这些文件中获取别名信息。
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);
...
}
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 对象的数据。
udev 在插入支持热插拔的设备时加载必要的驱动程序模块。这是通过以下 udev-rule
DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"
因此,kmod 被调用,例如kmod load hid:b0005g0001v0000045Ep000002E0
记录了内置 kmod 的来源 here
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_TABLEs 生成的。
遗憾的是,我无法找到 kmod 在该文件中读取的确切位置或从中获取别名信息的位置。
因此:kmod 如何知道哪个别名代表哪个模块?
来自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]);
...
}
}
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
并从这些文件中获取别名信息。
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);
...
}
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 对象的数据。