B.4 Linking Modules on Demand

A module can be automatically linked when the functionality it provides is requested and automatically removed afterward.

For instance, suppose that the MS-DOS filesystem has not been linked, either statically or dynamically. If a user tries to mount an MS-DOS filesystem, the mount( ) system call normally fails by returning an error code, since MS-DOS is not included in the file_systems list of registered filesystems. However, if support for automatic linking of modules has been specified when configuring the kernel, Linux makes an attempt to link the MS-DOS module, and then scans the list of registered filesystems again. If the module is successfully linked, the mount( ) system call can continue its execution as if the MS-DOS filesystem were present from the beginning.

B.4.1 The modprobe Program

To automatically link a module, the kernel creates a kernel thread to execute the modprobe external program,[2] which takes care of possible complications due to module dependencies. The dependencies were discussed earlier: a module may require one or more other modules, and these in turn may require still other modules. For instance, the MS-DOS module requires another module named fat containing some code common to all filesystems based on a File Allocation Table (FAT). Thus, if it is not already present, the fat module must also be automatically linked into the running kernel when the MS-DOS module is requested. Resolving dependencies and finding modules is a type of activity that's best done in User Mode because it requires locating and accessing module object files in the filesystem.

[2] This is one of the few examples in which the kernel relies on an external program.

The modprobe external program is similar to insmod, since it links in a module specified on the command line. However, modprobe also recursively links in all modules used by the module specified on the command line. For instance, if a user invokes modprobe to link the MS-DOS module, the program links the fat module, if necessary, followed by the MS-DOS module. Actually, modprobe just checks for module dependencies; the actual linking of each module is done by forking a new process and executing insmod.

How does modprobe know about module dependencies? Another external program named depmod is executed at system startup. It looks at all the modules compiled for the running kernel, which are usually stored inside the /lib/modules directory. Then it writes all module dependencies to a file named modules.dep. The modprobe program can thus simply compare the information stored in the file with the list of linked modules produced by the query_module( ) system call.

B.4.2 The request_module( ) Function

In some cases, the kernel may invoke the request_module( ) function to attempt automatic linking for a module.

Consider again the case of a user trying to mount an MS-DOS filesystem. If the get_fs_type( ) function discovers that the filesystem is not registered, it invokes the request_module( ) function in the hope that MS-DOS has been compiled as a module.

If the request_module( ) function succeeds in linking the requested module, get_fs_type( ) can continue as if the module were always present. Of course, this does not always happen; in our example, the MS-DOS module might not have been compiled at all. In this case, get_fs_type( ) returns an error code.

The request_module( ) function receives the name of the module to be linked as its parameter. It invokes kernel_thread( ) to create a new kernel thread that executes the exec_modprobe( ) function. Then it simply waits until that kernel thread terminates.

The exec_modprobe( ) function, in turn, also receives the name of the module to be linked as its parameter. It invokes the execve( ) system call and executes the modprobe external program,[3] passing the module name to it. In turn, the modprobe program actually links the requested module, along with any that it depends on.

[3] The name and path of the program executed by exec_modprobe( ) can be customized by writing into the /proc/sys/kernel/modprobe file.

Each module automatically linked into the kernel has the MOD_AUTOCLEAN flag in the flags field of the module object set. This flag allows automatic unlinking of the module when it is no longer used.

To automatically unlink the module, a system process (like crond ) periodically executes the rmmod external program, passing the -a option to it. The latter program executes the delete_module( ) system call with a NULL parameter. The corresponding service routine scans the list of module objects and removes all unused modules having the MOD_AUTOCLEAN flag set.