It's not as simple as tell user to check if the module is loaded before
calling this function. Due to race conditions, module might not be
loaded before the function call, but fail later because another process
inserted it.
Share code of module creation among the several new functions. With this
we let the alias/modname/path parsing to the separate functions, and the
rest with the common one.
This fixes the issue of alias names not being able to contain dots.
Alias names may contain dots. However since kmod_module_from_alias()
still calls kmod_module_new_from_name(), the bug is not entirely fixed,
and will be completely corrected in a later patch.
Split kmod_module_probe_insert_module() in 2:
1) Get list of modules to be loaded
2) Iterate the list, loading the module
With this in future we will be able to cover use cases of modprobe,
that has a logic a bit more complicated.
With this we also change the logic to detect dependency loops: instead
of checking the recursion every STEP times, we now keep a field in
kmod_module, marking it as visited. We simply ignore already visited
modules and thus we break loops.
This field can be used to iterate the modules, controlling whether we
are revisiting a certain module. A function to clear the values in all
modules is needed since when we are iterating, we don't know if the
module is created anew or if it's picked from the pool. Therefore we
can't know if the field is true because of a previous iteration or if
the module was indeed already visited.
Not all libc's have a mtim member in struct stat (dietlibc doesn't).
Change ts_usec() to receive a struct stat as parameter and implement it
accordingly for both cases.
Index dump doesn't use stdio.h function and instead call write()
directly on STDOUT_FILENO file descriptor. Therefore we need to flush
stdio buffers before calling it, to be sure the configuration dump will
appear before index's.
Provide a function to dump the index files to a certain fd. It could be
more optimized (particularly the functions to dump the index that were
copied and pasted from m-i-t), but it seems like the only user of it is
'modprobe -c', used for debugging purposes. So, keep it as is.
Config iterators are useful to get each configuration list, remember its
type and how to get their key/value pair.
softdeps don't have the value yet, because they are stored as string
vectors.
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).