Current limitation is horrible no support to sections: we have to to
have separate header files or to maintain the libkmod-sections.txt file.
We are doing the latter.
Module aliases can be bigger than NAME_MAX. So, replace with PATH_MAX
that is bigger enough to hold them.
Technically in some places NAME_MAX would be sufficient (those using
module names only), but they use functions that can be called with
alias. So increase the buffers in these cases to PATH_MAX too.
Refactor code to use pointer to functions, avoiding the previous
Now comp_types defines a magic header to be checked (size and bytes),
with the associated load() and unload() operations. If a header
matches, their operations are used. Otherwise the regular file
operations (mmap/munmap) are used.
File descriptor close is managed by the common code if it's valid
(>=0). If some code steals the file descriptor (eg: gzopen), then they
must change file->fd to -1.
This way the code should be easier to extend and avoid bugs.
ouch, I did a mess in the original function, fix them:
* on errors (read() < 0), continue reading after the done bytes, not
at position 0.
* read buflen - 1 bytes, so there is always room to store the
trailing \0, as expected by user due behavior of snprintf(),
fgets() and others.
Return -errno instead of the value returned by init_module(). We need to
differentiate between the several errors that might occur, e.g. "module
already loaded", access denied, etc.
Treat module insertion as modprobe does: look for (soft-)dependencies, run
install commands, apply blacklist.
The difference with the blacklist is that it's applied to all modules,
including the dependencies. If you want to apply a blacklist only on the
module it's better to call the filter function by yourself.
This implementation detects loops caused by poorly written
soft-dependencies and fail gracefully, printing the loop to the log.
It only worked because n was always 1. kmod_list_remove returns a
pointer to the next element, relative to the removed one. Therefore we
need to always get a pointer to the last.
build: explicitly call PKG_PROG_PKG_CONFIG
Per the manual page, PKG_PROG_PKG_CONFIG needs to be invoked
explicitly if PKG_CHECK_MODULES might not happen (it is indeed stowed
in an AS_IF in kmod). Without this, funny failures can occur.
(As it did.)
Uses kmod_elf_get_dependency_symbols() that looks into ".symtab" for
UNDEF symbols and matches the name from ".strtab" to "__versions" to
get crc.
Likely the public API should unify the symbol information getters and
list release, they are almost the same.
Similar to module-init-tools load_symbols(), it will try .symtab and
.strtab for symbols starting with __crc_, if they are found their crc
is read from ELF's Elf_Sym::st_value.
If not found, then it will fallback to __ksymtab_strings.
Just now realized that my distro (Gentoo) enables support for gzip but
does not compress modules by default.
In this case it's better to have a special case that uses mmap()
instead of a loop of realloc() + gzread().
We need to keep config files sorted and use them taking the precedence
order into account.
The following message was taken from module-init-tools commit doing a
similar thing:
Configuration files are parsed in alphabetic order, regardles of
what directory they reside in. Furthermore, if several files by
the same name exist in different directories only the one in the
directory with highest precedence is loaded.
The order of precedence is /run, /etc, /usr/lib, /lib.
The sad thing is that we are not using openat() anymore since each file
is in different directories. In future we might change the
implementation to open all DIRs and keep a reference
to them instead of the path. However we'd have to keep a separate list
with all the opened dirs so we can close them later (when all configs
are parsed).
Check if '=' appeared before the dot. In this case, it's not a valid
module option in kernel command line.
The command line that was failing is:
"root=/dev/sda3 ro pcie_aspm=force init=/sbin/bootchartd
initrd=../initramfs-linux.img BOOT_IMAGE=../vmlinuz-linux"
Commit "b20dc17 Remove unneeded reference to last string" reverted the
fix in "47a0ef6 elf: do not output empty strings." and empty strings are
appearing again in kmod-modinfo.
With this commit we do a bit different and instead of keeping the
reference to last string we skip the '\0' inside the loop.
module-init-tools modprobe.c use fnmatch() and not strcmp() to match
commands and softdeps, although the man page does not say so. Then use
the same function to provide compatibility.
kmod_list_prev() should return NULL if the current element is the
head, not if the previous element is the head. This was likely a copy
& paste error from kmod_list_next().
Install and remove commands are now properly treated on lookup. Example
config file:
$ ./test/test-lookup installme
libkmod version 1
Alias: 'installme'
Modules matching:
installme
install commands: 'echo "this is a install message"'
$ ./test/test-lookup removeme
libkmod version 1
Alias: 'removeme'
Modules matching:
removeme
remove commands: 'echo "this is a remove message"'
modprobe from module-init-tools does not use more than one
install/remove command, it just stops on the first one. Test
modprobe.conf:
install bla echo "this is a message"
install bla echo "this is a message"
$ modprobe bla
this is a message
$
Install and remove commands are already a legacy thing we need to carry,
but let's not extend it so people do not start doing crazy things.
With this patch we are breaking on the first element we find in the
configuration. May be we can add a warning later when parsing the config
that install commands are duplicated.
Module was never being removed from hash table. Therefore, if we create
a module, unref it and create it again we will access freed memory.
Commit "53385cf Improve test of double references" introduced a new test
in test-mod-double-ref.c that previously to this commit was crashing and
now it's working fine.
The hash key is not copied so we can't change the string from:
modname/modalias
to:
modname'\0'modalias
in order to setup mod->name and mod->alias.
Now what we do is:
1) if name is in the form 'modname/modalias', the final struct
kmod_module will be:
struct kmod_module {
char *alias;------,
char *name;-----, |
char *hashkey;--|-|-,
} | | |
name <------------------' | |
alias <-------------------' |
hashkey <-------------------'
2) if name is in the simple form 'modname', then the final struct
kmod_module will be:
struct kmod_module {
char *alias;------> NULL
char *name;-----,
char *hashkey;--|---,
} | |
name <------------------*---'
1 alias may correspond to more than 1 module. This would cause a
conflict in the hash table when inserting a module there and bad things
could happen.
Now we use 'modname/aliasname' as key, '/aliasname' part being optional.
Internally kmod_module_new_from_alias() will setup a 'modname/aliasname'
string and pass to kmod_module_new_from_name() that will treat the case
with a '/' in the name.
User might call kmod_module_new_from_name() without any slashes, so the
key my not contain it.
We have a static vector of indexes. There's no need to check if they
have a suffix or if they are absolute, we just already know in advance
and there are no plans to change it.
Remove function kmod_resolve_alias_options since it's not needed
anymore. Test is using the following configuration file:
alias blablabla ac
options ac test=1
options blablabla test=2
Lookup test by module name:
$ ./test/test-lookup ac
libkmod version 1
Alias: 'ac'
Modules matching:
ac
options: 'test=1'
Lookup test by alias:
$ ./test/test-lookup blablabla
libkmod version 1
Alias: 'blablabla'
Modules matching:
ac
options: 'test=1 test=2'
This function will create a new kmod_module() by calling
kmod_module_new_from_name(), but instead of given the module name, it
gives the alias. This way, the modules' hash will contain the alias
instead of the name. If module was created successfully, then it swap
the alias with the actual name.
The downside is that the structure is not shared anymore if we create a
kmod_module by alias and after by name. However, in modprobe's
configuration it's possible to have different options for different
aliases. In future we might want to create a way to share the common
part of the structure (then having only one instance as we had before).
We still have name allocated just after the struct kmod_module, but
now we use a pointer instead of putting name as a vector in the end of
the structure.
The previous way has some problems, the worst is:
- it's not possible to swap the name with another value: this is
the real problem that this patch is solving. Later patches
will make name be swappable with alias, which is not possible
if name is a vector.
When normalizing alias names (or if we don't know if it's an alias or
modname), use alias_normalize() instead of modname_normalize(). The
difference is that alias names can contain dashes withing brackets, and
those should not be changed to underscores.
Most of the places using underscores() function might be converted to
alias_normalize(), but this is not done now.
It's not possible to move functions related to "live" modules to
libkmod-loaded.c because they depend on the definition of kmod_module.
Putting this structure in the private header is not a good idea, so let
all functions related to "live" information in the end of
libkmod-module.c, and move the sole function from libkmod-loaded.c to
this place. This way all functions get the right documentation
about their sections.
Lines should not go over 80 chars with a few exceptions:
- headers
- function definitions with only 1 argument
- long strings, otherwise we break grep
This should go later in a coding-style file
This will be required to implement modprobe later. The implementation
follows "man modprobe.conf" and allows options to be specified for
alias as well, thus the need for kmod_resolve_alias_options().
Example mod-a.conf:
options mod-a a=1 b=2
options mod-a c=3
alias mymod-a mod-a
options mymod-a d=4
Results in:
options mod-a a=1 b=2 c=3
options mymod-a a=1 b=2 c=3 d=4
Install commands are being concatenated with ";", but manpage is not
clean about this behavior.
For mmap mode, we can avoid allocating and copying strings from the
mmap'ed memory.
With that we have fixed length "struct index_mm_value" that can be
allocated inline with "struct index_mm_node".
uint32_t reads must be aligned, they're not then use memcpy().
read_alloc_chars_mm() and read_chars_mm() were wrong, normalize all
address calculation using single byte pointer "addr" that is
incremented by the amount read, this will avoid further errors.
Put all names in a static vector and declare a enum containing the
number of indexes. This way it's easier to create vectors inside ctx
that depend on these files.
Grow buffer based on a step, avoiding hitting the system over and over
again.
Do not allocate the 'struct buffer' as in all cases the lifetime is
known and the pattern was allocate then free in every call site.
"buf[NAME_MAX] = value" is invalid since it would access the byte
right after the array.
Also fix the const of modname, do not mess with it to avoid mistakes.
rmmod/insmod should be able to operate directly on files, not relying on
indexes and configuration.
The following test was not working and now it is:
$ # go to a dir != mod->dirname
$ cd /lib/modules/$(uname -r)/kernel
$ # try to insert module giving a relative path
$ insmod drivers/acpi/ac.ko
1) Allocate less by not sorting the result with qsort. Instead,
insert the nodes in the correct order;
2) Do not maintain the whole path in memory, but rely on openat()