Linux STREAMS (LiS) |
||
|
||||||||||||||||
The LiS demand load system supports both the old kerneld and the new kmod mechanisms for demand loading kernel modules. The convention for LiS kernel loadable object files is:
Unconfigured drivers and modulesAn unconfigured driver or module is a driver or module that LiS does not have any special information about. Even in this case, you can take advantage of demand loading. ModulesModule demand loading is simple. When a user does an I_PUSH requesting that module mymod be pushed onto a stream, LiS will check if mymod is already registered. If not, LiS asks the kernel to load streams-mymod. A security related implication of this is that any user capable of doing an I_PUSH can provoke loading of any module that has the streams- prefix. Demand loading also works when autopushing modules, but you should be aware that when a module is unloaded, is it silently removed from all autopush lists. You can have more than one module in a single kernel loadable module,
but for demand loading to work with modules whose object names are not
derived from the module name, you have to set up alias lines
in /etc/conf.modules.
in your /etc/conf.modules for demand loading to work properly when pushing mymod2. DriversDemand loading drivers is slightly more complicated. When a device special node with major device number major is opened, the kernel checks if device major is registered in the kernel. If not, the kernel will try to load "char-major-major".
Kernel loadable modules generally do not have names of the form char-major-number, so a mapping to the correct name is needed. This is done with alias lines in /etc/conf.modules, or, on newer systems, /etc/modules.conf. If your driver has major device number 123 and is in the kernel loadable object file streams-mydriver.o, you should have the line
in your /etc/conf.modules.
in your /etc/conf.modules and the clone driver major is 240, both LiS and your driver will be demand loaded when you do a clone open of your driver. You can configure autopush on an unconfigured driver, but you should be aware that when the driver is unloaded, all its autopush lists are silently removed. You can have more than one driver in a single kernel loadable module, but you should set up a separate alias line for each driver. Configured drivers and modulesWhen drivers and modules are added to the LiS configuration files, you can specify the object name that will be used for requesting a demand load of the driver or module. If demand loading of the configured object name fails, LiS will revert to the procedure for demand loading an unconfigured driver or module.
Writing kernel loadable modules for LiSIt takes little extra effort to make LiS modules and drivers loadable. In most cases, all you have to do is to add the special Linux module functions init_module() and cleanup_module() and some lines to maintain the usage count of the loadable module. The init_module() function id used for initializing the loadable module, and can be as simple as: int init_module(void) { return lis_register_strmod(&mymod_info, "mymod"); } for a module, or int init_module(void) { return lis_register_strdev(123,&mydrv_info, 10, "mydrv"); } for a driver. In this example, the driver's major device number is assumed to be 123. You must know this major device number ahead of time so that you can make the entry in the /dev directory that will cause your driver to autoload. The major number in your /dev entry and in your call to lis_register_strdev must match. The cleanup_module() function is called by the kernel just before a loadable module is unloaded. This function has to unregister the drivers and/or modules registered in the init_module() function.
To avoid that the loadable module is unloaded while somebody is still using it, a usage count has to be maintained. This is done using the macros MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT. MOD_INC_USE_COUNT is used in the open routines, but be careful not to call it if your open fails. MOD_DEC_USE_COUNT is used in the close routines. For a complete example, see the ldl driver in drivers/str/linux/ldl.c.
|