Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: December 17, 2024
In this tutorial, we’ll discuss determining whether a specific module is currently loaded in the Linux kernel. The Linux kernel supports two types of modules: built-in kernel modules (those inserted during the booting process) and loadable kernel modules (loadable by the user at runtime).
Thus, we’ll split the tutorial into built-in kernel modules and loadable kernel modules. In the latter, we’ll discuss several solutions and approaches to find if a given module is in the Linux kernel.
Let’s first review the kernel modules that have been loaded during the booting process. The best way to inspect these built-in kernel modules is to search the content of the /lib/modules/[kernel version]/modules.builtin directory.
We can use uname to get the kernel version that we’re currently running and automate the command:
$ cat /lib/modules/$(uname -r)/modules.builtin
kernel/arch/x86/kernel/msr.ko
kernel/arch/x86/kernel/cpuid.ko
kernel/arch/x86/platform/intel/iosf_mbi.ko
kernel/kernel/configs.ko
kernel/mm/zsmalloc.ko
kernel/fs/binfmt_misc.ko
kernel/fs/binfmt_script.ko
kernel/fs/configfs/configfs.ko
kernel/fs/exportfs/exportfs.ko
kernel/fs/nls/nls_base.ko
...
The list may be long, depending on our system configuration. Therefore, we can search in this list for a specific module with grep. For example, let’s search for the usbcore.ko built-in kernel module:
$ grep "usbcore.ko$" /lib/modules/$(uname -r)/modules.builtin
kernel/drivers/usb/core/usbcore.ko
We included $ in the search pattern “usbcore.ko$” because we want to match only those lines that end in “usbcore.ko”.
The command uname -r may fail when we’ve upgraded a kernel and we haven’t rebooted. Moreover, we must note that we may have several kernels installed in our system:
$ ls /lib/modules/
6.12.1-arch1-1
6.12.3-arch1-1
The use of uname -r will return the current kernel version, so using cat /lib/modules/$(uname -r)/modules.builtin will return the built-in modules for the currently running kernel. We can always rely on autocompletion or the manual typing of the kernel version to get other specific information.
After covering the built-in kernel modules, we need to examine the loadable kernel modules. Several tools can be used to gather the loaded kernel modules.
The command modinfo is not a valid solution for this problem. modinfo doesn’t check whether the kernel has loaded a given module or not. It only displays the information of kernel modules that we’ve installed in our filesystem.
As we did for the built-in kernel modules, there is a directory containing this information. The /proc/modules directory lists those loadable kernel modules that are currently loaded.
As before, let’s peek into the directory to see how this directory looks:
$ cat /proc/modules
uvcvideo 176128 0 - Live 0x0000000000000000
videobuf2_vmalloc 20480 1 uvcvideo, Live 0x0000000000000000
uvc 12288 1 uvcvideo, Live 0x0000000000000000
videobuf2_memops 16384 1 videobuf2_vmalloc, Live 0x0000000000000000
videobuf2_v4l2 40960 1 uvcvideo, Live 0x0000000000000000
videobuf2_common 94208 4 uvcvideo,videobuf2_vmalloc,videobuf2_memops,videobuf2_v4l2, Live 0x0000000000000000
videodev 393216 2 uvcvideo,videobuf2_v4l2, Live 0x0000000000000000
mc 90112 4 uvcvideo,videobuf2_v4l2,videobuf2_common,videodev, Live 0x0000000000000000
ccm 20480 6 - Live 0x0000000000000000
algif_aead 12288 0 - Live 0x0000000000000000
...
We can again use grep to search for the long list of modules that we have in our system. For example, let’s search for the ip_tables kernel module:
$ grep -E "^ip_tables\>" /proc/modules
ip_tables 36864 0 - Live 0x000000000000000
In this case, we’re using the search pattern “^ip_tables\>”. We need the ^ symbol to match the lines that start with our module name. Otherwise, we’ll also list modules that depend on the module we’re searching for:
$ grep -E "ip_tables\>" /proc/modules
ip_tables 36864 0 - Live 0x0000000000000000
x_tables 65536 1 ip_tables, Live 0x0000000000000000
Moreover, we use “\>” at the end of the search pattern to ensure that we match only the lines with the right full name:
$ grep -E "^ip_tables" /proc/modules
ip_tables 36864 0 - Live 0x0000000000000000
ip_tables_2 62375 0 - Live 0x0000000000000000
If we find a module in the /proc/modules, we can assume that the kernel has loaded it. Otherwise, the module won’t be currently loaded into the kernel.
The lsmod command shows the kernel modules that the kernel has currently loaded. Thus, we’re getting mostly the same information as looking at the /proc/modules directory with some extra formatting to have it in columns.
Let’s see how the output of lsmod looks like:
$ lsmod
Module Size Used by
uvcvideo 176128 0
videobuf2_vmalloc 20480 1 uvcvideo
uvc 12288 1 uvcvideo
videobuf2_memops 16384 1 videobuf2_vmalloc
videobuf2_v4l2 40960 1 uvcvideo
ccm 20480 0
algif_aead 12288 0
crypto_null 16384 1 algif_aead
des3_ede_x86_64 45056 0
cbc 12288 0
des_generic 12288 0
...
This list of kernel modules may be long. Therefore, we can combine lsmod with a grep search:
$ lsmod | grep -E "^ip_tables\>"
ip_tables 36864 0
We’re using the same search pattern as before to match lines containing the whole module name at the beginning of the line.
The command modprobe provides a set of tools to handle loadable modules from the Linux kernel. We can use it to load modules or remove them from the Linux kernel.
The solution discussed here consists of trying to load the module we’re looking for and see what modprobe returns. Based on this output, we can infer which is the status of this kernel module.
For example, let’s check if we’ve loaded the ip_tables module in the kernel of our system by trying to load it into the kernel:
$ modprobe --dry-run --first-time ip_tables
modprobe: ERROR: could not insert 'ip_tables': Module already in kernel
We can see that modprobe has failed to insert the module because the kernel has already loaded it.
We’re using two flags. The –dry-run flag does all the normal checks that modprobe does without inserting the kernel module. The –first-time flag is used to make modprobe fail when we request that it inserts a module already present. Otherwise, modprobe will succeed by default in those cases.
Another scenario is trying to load a kernel module that we don’t have loaded in the kernel. For example, let’s assume that the kernel has not loaded the module ib_core:
$ modprobe --dry-run --first-time ib_core
In this case, modprobe doesn’t return anything because no error would happen when trying to load the module into the kernel.
However, even if we’ve requested that modprobe loads the ib_core module into the kernel and no error has appeared, the module has not been loaded because we’re using the –dry-run flag. To test this we can use lsmod as described previously to test if the kernel has loaded a module or not:
$ lsmod | grep -E "^ib_core\>"
This will not return anything, certifying that we didn’t load the module when we called modprobe and received no error.
Finally, modprobe will also inform us if we ever request to load a kernel that doesn’t exist in our system:
$ modprobe --dry-run --first-time non_existing_module
modprobe: FATAL: Module non_existing_module not found in directory /lib/modules/6.12.1-arch1-1
This way, we’ve covered three possibilities: modules that we’ve already loaded (getting the error from modprobe that the module was already loaded), modules that have not been loaded (getting no error from modprobe), and modules that don’t exist (with the modprobe error that the module was not found).
In this article, we’ve talked about checking whether the kernel has a given module loaded or not. Firstly, we considered built-in kernel modules and a solution checking under the /lib/modules/ path.
Secondly, we discussed loadable kernel modules. There are different approaches: checking under the /proc/modules directory, using lsmod, or testing whether we can load a module or not with modprobe.