Read Loaded Kernel Modules Clearly with lsmod
lsmod tells you exactly what is loaded into the running Linux kernel right now, not what a package manager or config file thinks should be there. Reach for it before you touch modprobe, insmod or rmmod, whenever a driver update misbehaves or a device stops responding.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell on the Linux host you want to inspect. No elevated privilege is normally required. This guide describes kmod 31+20240202-2ubuntu7.2, the package installed on the reference system; output order and the particular modules will differ on other kernels.
1. Run the basic listing
Run lsmod with no arguments. Its installed manual documents no command-line operands at all: the command simply formats the contents of /proc/modules.
$ lsmod
Module Size Used by
ip_set_hash_ip 49152 0
macsec 77824 0
algif_hash 12288 0
cpuid 12288 0
8021q 45056 0
What you get is a snapshot of the running kernel, not an inventory of every module installed on disk. A module can sit ready to load and never appear here. A module shown here is present in the kernel right now, whether or not a package manager touched anything recently.
Checkpoint
A header followed by module rows means the basic inspection is working. Save the output if you are comparing a host before and after a planned change:
$ lsmod > /tmp/lsmod-before.txt
$ test -s /tmp/lsmod-before.txt && echo "listing captured"
listing captured
2. Read the three useful columns
- Name. The module itself, for example
8021q. - Size. Reported in bytes.
- Used by. A use count, then the names of modules that use it. A row such as
garp 20480 1 8021qmeansgarpis 20480 bytes with a use count of 1, and8021qshows up in its users column.
The use count is not a measure of traffic, performance or importance: it is kernel reference information. Zero does not mean broken; it means no current user is recorded in that column. A non-zero count is one reason an unload can be refused, so do not treat a zero as proof that unloading is safe.
Module names sometimes carry an underscore where a config file or hardware description uses a hyphen. Treat the exact name lsmod prints as authoritative when you go and investigate it.
3. Find one module without losing the header
Filter the listing after it has been produced, keeping the header row so the columns still make sense:
$ lsmod | grep -E '^(Module|8021q[[:space:]])'
Module Size Used by
8021q 45056 0
Replace 8021q with a module name from your own listing. The beginning-of-line anchor matters: a dependent module named later in the users column is not the same as a row for that module. If the command returns only the header, that module is not loaded.
Tip
A module name that is also a substring of another name is not a safe search term on its own. Use the anchored expression above, or check the full row by eye before drawing a conclusion.
4. Cross-check the kernel's source data
The lsmod manual describes the command as a formatter for /proc/modules. Compare the first few raw rows against the formatted listing:
$ sed -n '1,6p' /proc/modules
ip_set_hash_ip 49152 0 - Live 0x0000000000000000
macsec 77824 0 - Live 0x0000000000000000
algif_hash 12288 0 - Live 0x0000000000000000
cpuid 12288 0 - Live 0x0000000000000000
8021q 45056 0 - Live 0x0000000000000000
The raw format is kernel-facing and nowhere near as easy on the eye. Its first fields are the module name, size and use count; later fields carry state information. Do not script against lsmod's display spacing. If you need the source interface, parse /proc/modules directly and check your assumptions against the running kernel version.
5. Check whether a module is loaded, not merely installed
When a script needs a plain yes or no, use an exact first-column test. This example keeps the module name in one obvious variable:
module_name='8021q'
if lsmod | awk -v wanted="$module_name" 'NR > 1 && $1 == wanted { found = 1 } END { exit !found }'; then
echo "$module_name is loaded"
else
echo "$module_name is not listed as loaded"
fi
That test only answers whether the running kernel lists the exact name you gave it. It proves nothing about whether the module file exists on disk, whether the hardware is present, or whether a future load will succeed. Do not reach for sudo just because the answer is no: lsmod reads status and works fine as the invoking user.
6. Diagnose an empty or failing result
If lsmod prints nothing, or complains it cannot open /proc/modules, check the interface directly:
$ test -r /proc/modules && echo "/proc/modules is readable" || echo "/proc/modules is unavailable"
/proc/modules is readable
Inside a container, a restricted namespace, or an unusual recovery environment, /proc can be absent, partially mounted, or deliberately hidden. That is an environment boundary, not evidence the host has no modules. Inspect the host in its own namespace and permissions before changing mounts or container configuration.
If the numbers in a row look odd, remember module state can change mid-read. Rerun lsmod and compare whole rows rather than pairing a size from one snapshot with a use count from another. This command observes; it does not freeze kernel state while you look at it.
7. Keep state-changing tools separate
lsmod does not load or remove anything. modprobe, insmod and rmmod do that job and may need elevated privileges. Do not reach for one of them just because a module is missing from the listing.
Safety boundary
Loading or unloading a module can affect networking, storage, filesystems or security controls. Plan a maintenance window, confirm the dependency chain, and keep a recovery path before using those tools. Nothing in this guide needs an undo: everything here only reads status and writes one temporary capture under /tmp.
Done means
lsmodproduced a current list from the running kernel.- You can distinguish module name, size, use count and listed users.
- You can test an exact module row without confusing it with a substring.
- You know that the listing covers loaded modules, not every installed module.
- You checked
/proc/modulesbefore diagnosing an empty result. - No module, service, mount or persistent configuration was changed.