Why "lsmod | wc -l" not equal "ls /sys/module | wc -l"

Why do these two commands return different results?

lsmod | wc -l
100

ls /sys/module | wc -l
138

Solution 1:

lsmod lists all of your dynamic modules that are loaded.

The entries in /sys/module correspond to dynamic modules and modules which are built into the kernel (and have parameters that need to be accessible) rather than loaded dynamically. For example:

[michael@brazzers:~]$ ls -d /sys/module/ip_tables/
/sys/module/ip_tables/
[michael@brazzers:~]$ lsmod |grep ^ip_tables
ip_tables              26995  3 iptable_filter,iptable_mangle,iptable_nat
[michael@brazzers:~]$ grep CONFIG_NF_NAT_IPV4 /boot/config-3.8.0-30-generic
CONFIG_NF_NAT_IPV4=m

You can see here that the iptables module is configured as a dynamic module. Contrast to:

[michael@brazzers:~]$ ls -d /sys/module/apparmor/
/sys/module/apparmor/
[michael@brazzers:~]$ lsmod |grep ^apparmor
[michael@brazzers:~]$ grep APPARMOR /boot/config-3.8.0-30-generic 
CONFIG_SECURITY_APPARMOR=y

whereas apparmor is built-in.

Solution 2:

  • /sys/module/MODULENAME

MODULENAME is the name of the module that is in the kernel. This module name will always show up if the module is loaded as a dynamic module. This is exactly what you can see when you issue lsmod command or when you check /proc/modules file.

If it is built directly into the kernel it will only show up if it has a version or at least one parameter. The available parameters are then available in the directory:

  • /sys/module/MODULENAME/parameters