Managing Linux Kernel Modules: lsmod, modprobe and Friends
AI generated
$
/etc
Linux · Kernel · System Internals · Administration
Managing Linux Kernel Modules
lsmod, modprobe and safely working with the running kernel

Anyone who treats kernel modules as a black box is missing one of the most useful diagnostic tools on Linux. lsmod, modinfo and modprobe show which drivers and subsystems are actually loaded, how dependencies between modules get resolved, and how to load, remove or permanently block a module without ever recompiling the kernel.

17 min read lsmod · modinfo · modprobe · insmod · rmmod Ubuntu · Debian · RHEL · Kernel 5.x/6.x

1. What kernel modules are and why they matter

A kernel module is a piece of code that can be loaded into or removed from a running Linux kernel without a reboot. Drivers for network cards, filesystem drivers such as XFS or Btrfs, firewall backends like nf_tables, or virtual devices such as the loopback device are almost always shipped as kernel modules rather than built statically into the kernel. This keeps the running kernel small in memory, since only the subsystems actually needed are loaded, and it lets distributions ship a single kernel that works across very different hardware.

For system administrators, kernel modules matter mainly because they are one of the first places to look when hardware or networking breaks. If a driver for a RAID controller card is missing, the kernel will not load the matching module automatically, and the disks stay invisible. If a kernel module is misconfigured, it can trigger kernel panics or leave network interfaces in an inconsistent state. lsmod, modinfo and modprobe together form the standard toolset for fully understanding and deliberately changing the module state of a system.

2. lsmod: listing and understanding loaded kernel modules

The lsmod command reads /proc/modules and prints a formatted table of every currently loaded kernel module with three columns: name, size in bytes, and a usage counter listing the names of modules depending on it. A module with a usage counter of 0 is loaded but no longer referenced by any other module or running process, which makes it a candidate for unloading. A usage counter above 0 means an unload attempt with rmmod will fail as long as the dependency exists.

In practice, lsmod is almost always combined with grep to search for a specific driver or subsystem, for example to check whether the kernel module for a given network card or filesystem is loaded at all. Since lsmod is just a readable formatting of /proc/modules, the same state can also be read directly with cat /proc/modules, which is useful in scripts that should not depend on lsmod itself. The output is deterministic and works well for monitoring checks that verify a security relevant module such as overlay for containers is actually active.


# List all currently loaded kernel modules
lsmod

# Typical output columns: Module, Size, Used by
# Module                  Size  Used by
# nf_tables             172032  10 nft_ct,nft_chain_nat,...
# xt_conntrack           16384  1
# ip6table_filter        16384  1
# xfs                  2072576  1

# Search for a specific driver or subsystem
lsmod | grep -i xfs

# Check whether the overlay filesystem module (used by Docker) is loaded
lsmod | grep overlay

# Same information without lsmod, straight from the proc filesystem
cat /proc/modules | column -t

# Count how many modules are currently loaded
lsmod | tail -n +2 | wc -l

3. modinfo: checking metadata and dependencies

While lsmod only shows what is currently loaded, modinfo provides detailed metadata for any kernel module, whether it is loaded or not. This includes the file path in the module tree under /lib/modules/$(uname -r), the license, the author, a short description, the list of dependencies (depends), and every parameter the module accepts when loaded. This parameter list matters because many drivers let you control their behaviour through module parameters, for example the debug level of a network driver or the maximum number of supported devices.

A common practical scenario: before loading an unfamiliar kernel module on a production system, you first check with modinfo which other modules must be loaded as a prerequisite, and whether the module is signed. Signed modules are mandatory when Secure Boot is active, and unsigned modules are otherwise rejected by the kernel with an error. The output of modinfo -F depends gives you exactly the dependency chain that modprobe will later resolve automatically.


# Show full metadata for a module, whether loaded or not
modinfo xfs

# Typical fields returned:
# filename:       /lib/modules/6.8.0-generic/kernel/fs/xfs/xfs.ko
# license:        GPL
# description:    SGI XFS with ACLs, security attributes...
# depends:        libcrc32c
# retpoline:      Y
# intree:         Y
# signature:      (signed, appended)

# Query a single field, useful in scripts
modinfo -F depends xfs
modinfo -F version nf_tables

# List every parameter a module accepts
modinfo -p e1000e

# Check module signature status for Secure Boot compliance
modinfo -F signer nvidia 2>/dev/null || echo "module unsigned or not present"

4. modprobe: loading and unloading modules with dependency resolution

The central command for daily work is modprobe, because unlike insmod it automatically resolves every dependency of a kernel module and loads them in the correct order. Running modprobe nf_nat makes modprobe ensure nf_conntrack gets loaded first if missing, because nf_nat depends on it. This resolution is based on a database generated from the depends fields of every module under /lib/modules/$(uname -r), which has to be kept up to date with depmod, especially after manually copying new module files.

To unload, modprobe -r is used, which also works recursively: every module that came along automatically during loading and now has no other user gets removed as well. This differs clearly from rmmod, which only removes the exact kernel module specified and fails with an error when dependencies still exist. For testing purposes, modprobe --dry-run -v is useful because it shows the exact load order without changing anything.


# Load a module, resolving all dependencies automatically
modprobe nf_nat

# Dry run: show what WOULD be loaded, without changing anything
modprobe --dry-run -v nf_nat

# Load a module with custom parameters (not persisted across reboots here)
modprobe e1000e InterruptThrottleRate=3000

# Unload a module and every dependency no longer in use
modprobe -r nf_nat

# Rebuild the module dependency database after adding new module files
depmod -a

# Force a re-scan of module aliases (useful after driver package updates)
depmod -a "$(uname -r)"

5. insmod and rmmod: the direct, riskier path

insmod loads a kernel module directly from a given .ko file, without consulting the module database and without resolving dependencies itself. If a prerequisite is missing, the kernel reports an error such as Unknown symbol, and the administrator has to identify the missing modules manually and load them in the correct order. This path matters mostly when testing a self compiled driver, for example while developing a custom kernel module that is not yet installed under /lib/modules and not yet registered in the depmod database.

rmmod is the counterpart for unloading and also works without automatically resolving dependencies. Trying to remove a kernel module that is still referenced by another module fails with the error rmmod: ERROR: Module ... is in use. In production environments, modprobe -r is almost always preferred over rmmod, since automatic resolution avoids mistakes caused by forgotten dependencies. insmod and rmmod still matter as the precise, controlled tool for situations where you want to know exactly what is happening, for example while debugging a failing module load.


# Load a module directly from a .ko file (no dependency resolution)
sudo insmod /lib/modules/6.8.0-generic/kernel/drivers/net/dummy.ko

# If dependencies are missing, the kernel log shows something like:
# dummy: Unknown symbol register_netdevice (err -2)
# In that case, load the dependency first, then retry insmod

# Remove an exact module (fails if still referenced elsewhere)
sudo rmmod dummy

# Typical failure when dependencies still reference the module:
# rmmod: ERROR: Module nf_conntrack is in use by: nf_nat

# Force removal (dangerous, can destabilize the running kernel)
sudo rmmod -f some_module   # avoid on production systems

6. Loading kernel modules automatically at boot

Systemd ships with /etc/modules-load.d/, a declarative mechanism for loading certain kernel modules automatically on every boot. Every file in this directory with a .conf extension holds a list of module names, one per line, and is processed by the systemd-modules-load.service at boot. This is the preferred path over the older /etc/modules, which is still used on systems without systemd but offers less structure for multiple configuration sources.

A typical example from the container world: for Docker or Podman to work reliably, the kernel modules overlay and br_netfilter must be loaded, the latter especially for correct bridge network filtering with iptables. If one of these modules is not loaded automatically at boot, container networking behaves inconsistently, often only fixed after a manual modprobe. Configuring this through modules-load.d makes the behaviour reproducible and documents at the same time which modules a system deliberately needs.


# /etc/modules-load.d/containers.conf
# Kernel modules loaded automatically at every boot via systemd-modules-load.service
overlay
br_netfilter

# /etc/modules-load.d/network.conf
# Bonding driver required for NIC teaming on this host
bonding

# Verify the service picked up the configuration after a reboot
# systemctl status systemd-modules-load.service
# journalctl -u systemd-modules-load.service --boot

7. Blacklisting modules and persisting parameters

Sometimes a kernel module should specifically not be loaded, even though the kernel would pick it automatically, for example because an alternative driver is preferred, or because a module has known stability issues with particular hardware. Blacklisting through files in /etc/modprobe.d/ with the directive blacklist modulename exists for exactly this. It is important to understand that blacklisting only prevents automatic loading via hardware detection (udev aliases), not an explicit modprobe modulename by an administrator or another module requesting it as a dependency.

For parameters meant to be permanent rather than valid for a single session only, the same /etc/modprobe.d/ files are used with the directive options modulename parameter=value. This is the correct place for production configuration, unlike parameters passed directly on a manual modprobe call, which are lost after a reboot. After changing files under /etc/modprobe.d/, the initramfs usually needs to be rebuilt (update-initramfs -u on Debian/Ubuntu, dracut -f on RHEL based systems) so that early boot stage modules also respect the new configuration.


# /etc/modprobe.d/blacklist-nouveau.conf
# Prevent the open-source nouveau driver from loading automatically,
# because the proprietary NVIDIA driver should take over instead.
blacklist nouveau
options nouveau modeset=0

# /etc/modprobe.d/network-tuning.conf
# Persist a module parameter across reboots for a specific NIC driver
options e1000e InterruptThrottleRate=3000

# After changing files in /etc/modprobe.d/, rebuild the initramfs so early
# boot stages also respect the new configuration:
# update-initramfs -u          (Debian/Ubuntu)
# dracut -f                    (RHEL/CentOS/Fedora)

8. Troubleshooting: when a kernel module refuses to load

When an expected kernel module refuses to load, the first step is almost always dmesg, filtered by module name. The kernel writes every load failure with a concrete cause into the kernel ring buffer, such as missing symbols, a version mismatch between the compiled module and the running kernel, or a missing signature when Secure Boot is active. It is also worth checking journalctl -k, which stores the same kernel messages persistently across boots, while dmesg only shows the current boot unless configured for persistent storage.

A second common failure is a stale module database after a kernel update: if a new kernel was installed but depmod was not run for the new version, modprobe may not find the kernel module at all, even though the file physically exists. The command modprobe --show-depends modulename shows the resolved dependency chain and makes visible where the resolution breaks. For modules built through DKMS (Dynamic Kernel Module Support), it is also worth checking /var/lib/dkms/ to see whether the build for the currently running kernel version actually succeeded.


# First stop for module load failures: filter kernel ring buffer
dmesg | grep -i -A2 modulename

# Persistent kernel log across boots (systemd-journald with persistent storage)
journalctl -k --boot | grep -i modulename

# Show the resolved dependency chain modprobe would use
modprobe --show-depends modulename

# Confirm the module file actually exists for the running kernel
find /lib/modules/"$(uname -r)" -name "modulename.ko*"

# Rebuild module dependencies after a kernel update
sudo depmod -a "$(uname -r)"

# For DKMS-built modules: check build status for the current kernel
dkms status

9. Kernel module tools compared

Each of the tools described covers a different part of the kernel module lifecycle, and choosing the right one decides whether a change is reproducible and safe or only valid for the current session.

Tool Purpose Resolves dependencies Persists across reboot
lsmod Show loaded modules not applicable, display only not applicable
modinfo Check metadata not applicable, display only not applicable
modprobe Load and unload yes, automatically no, only via modules-load.d
insmod / rmmod Direct load/unload no, manual no
modules-load.d Boot automation uses modprobe internally yes, permanent

For daily operations this means: diagnose always with lsmod and modinfo, make active changes almost exclusively with modprobe, and configure permanent behaviour through /etc/modules-load.d/ and /etc/modprobe.d/. insmod and rmmod remain tools for targeted exceptions and kernel module development, not for standard management of production systems.

Mironsoft

Linux server administration and kernel level system diagnosis

Kernel issues nobody on the team can properly classify?

We analyze module load failures, driver problems and kernel log anomalies on your production systems, and bring them into a documented, reproducible state.

Module audit

Complete inventory of loaded kernel modules and their dependencies

Boot configuration

Setting up reproducible modules-load.d and modprobe.d configuration

Kernel diagnosis

Systematic troubleshooting for driver and loading problems

10. Summary

Working with kernel modules is one of the fundamental skills of Linux system administration, since almost every driver and many core subsystems are implemented as loadable modules. lsmod shows the current state, modinfo provides metadata and dependencies before loading, and modprobe is the central tool for safely loading and unloading with automatic dependency resolution. insmod and rmmod remain relevant for special cases where full control without automatic resolution is needed.

For production systems, permanent, documented configuration through /etc/modules-load.d/ and /etc/modprobe.d/ matters most, instead of loading modules manually without any traceability. Anyone diagnosing kernel module failures almost always starts with dmesg and journalctl -k, complemented by an up to date module database via depmod -a. This combination of display, loading and diagnostic tools covers the complete lifecycle of a kernel module.

Managing kernel modules — the key points at a glance

Checking status

lsmod shows loaded modules, modinfo shows metadata and dependencies even for unloaded modules.

Loading and unloading

modprobe resolves dependencies automatically, insmod/rmmod work directly on the file without resolution.

Boot configuration

/etc/modules-load.d/*.conf for automatic loading, /etc/modprobe.d/*.conf for blacklisting and parameters.

Troubleshooting

dmesg and journalctl -k show load failures, depmod -a fixes a stale module database.

11. FAQ: Managing Linux Kernel Modules

1modprobe vs. insmod difference?
modprobe resolves dependencies automatically, insmod loads a single .ko file without resolution.
2Non-zero usage counter in lsmod?
Shows active references from other modules or processes. Unloading fails while the dependency exists.
3Finding module parameters?
modinfo -p modulename lists every supported parameter with type and description, even for unloaded modules.
4Permanently blacklisting a module?
Create a file in /etc/modprobe.d/ with blacklist modulename. Only blocks automatic loading via udev, not manual modprobe.
5Module not found after kernel update?
Run depmod -a for the new kernel version to refresh the dependency database.
6Where do kernel modules physically live?
Under /lib/modules/$(uname -r)/, grouped by subsystem such as kernel/fs or kernel/drivers/net.
7modules-load.d vs. /etc/modules?
modules-load.d is the structured systemd mechanism with multiple files, /etc/modules the older, single-file variant.
8Unloading a module despite usage?
Refused by default, rmmod -f forces it but can destabilize the running kernel.
9Diagnosing a failed load?
dmesg and journalctl -k --boot filtered by module name show the concrete cause.
10What are DKMS modules?
DKMS automatically rebuilds modules like proprietary drivers for every new kernel version. dkms status shows the build state.