[译]5.8. UserSpace Helpers 用户空间的助手

目录:http://www.cnblogs.com/WuCountry/archive/2008/11/15/1333960.html
 
[不提供插图,读者最好从网上下载源书]

5.8. User-Space Helpers 用户空间的助手
There are cases where it makes sense for the kernel to invoke a user-space application to handle events. Two such helpers are particularly important:
我们关心,它是怎样让内核关注并调用用户空间里的应用程序来处理事件的。这有两个特别重要的助手:

/sbin/modprobe

Invoked when the kernel needs to load a module. This helper is part of the module-init-tools package.
在内核要加载模块时调用。它个助手是module-init-tools工具包的一部份。

/sbin/hotplug

Invoked when the kernel detects that a new device has been plugged or unplugged from the system. Its main job is to load the correct device driver (module) based on the device identifier. Devices are identified by the bus they are plugged into (e.g., PCI) and the associated ID defined by the bus specification.[] This helper is part of the hotplug package.
这个会在内核检测到有新设备被插入到系统中时来被调用。它的主要工作就是根据设备的标识来加载正确的设备驱动(模块)。设备的标识是通过它插入的总线和它所关联的总线规格来标识的。这个助手也是热插拨工具包的一部份。

[] See the section "Registering a PCI NIC Device Driver" in Chapter 6 for an example involving PCI.
参见第6章中“注册一个PCI类型的NIC设备驱动”一节的一个调用实例!

The kernel provides a function named call_usermodehelper to execute such user-space helpers. The function allows the caller to pass the application a variable number of both arguments in arg[] and environment variables in env[]. For example, the first argument arg[0] tells call_usermodehelper what user-space helper to launch, and arg[1] can be used to tell the helper itself what configuration script to use (often called the user-space agent). We will see an example in the later section "/sbin/hotplug."
内核提供了一个名为call_usermodehelper函数用于执行这样的用户空间的助手程序。这个函数充许调用者通过arg[]参数和env[]环境变量来向应用程序传递很多数据。例如,第一个参数arg[0]就告诉call_usermodehelper要启动用户空间中的哪个助手程序,而arg[1]可以用于告诉助手程序它自己,应该使用怎样的配置脚本(通常也叫作用户空间代理)。我们会在后面的“/sbin/hotplug”一节中看到一个例子。

Figure 5-3 shows how two kernel routines, request_module and kobject_hotplug, invoke call_usermodehelper to invoke /sbin/modprobe and /sbin/hotplug, respectively. It also shows examples of how arg[] and envp[] are initialized in the two cases. The following subsections go into a little more detail on each of those two user-space helpers.
图5-3显示了两个内核程序,request_module 和kobject_hotplug, 是如何分别调用/sbin/modprobe 和/sbin/hotplug的。它同时也显示了在这两种情况下arg[]和evn[]是如何初始化的。下面的子章节会详细的讨论这两种情况下的用户空间的助手程序。


Figure 5-3. Event propagation from kernel to user space


5.8.1. kmod 
kmod is the kernel module loader that allows kernel components to request the loading of a module. The kernel provides more than one routine, but here we'll look only at request_module. This function initializes arg[1] with the name of the module to load. /sbin/modprobe uses the configuration file /etc/modprobe.conf to do various things, one of which is to see whether the module name received from the kernel is actually an alias to something else (see Figure 5-3).
kmod是内核模块的加载器,它充许内核组件请求加载一个模块。内核提供了不只一个程序,但我们只会看一下request_module。这个函数初用要加载的模块名来始化arg[1]。/sbin/modprobe使用/ect/modprobe.conf这个配置文件来做一些其它的事,其中之一就是看从内核收到的要加载的模块名是否实际上与某些事关联在一起(参见图5-3)。

Here are two examples of events that would lead the kernel to ask /sbin/modprobe to load a module:
这里有两个事件的例子,这些事件引导内核要求/sbin/modprob去加载一个模块:

When the administrator uses ifconfig to configure a network card whose device driver has not been loaded yetsay, for device eth0[*]the kernel sends a request to /sbin/modprobe to load the module whose name is the string "eth0". If /etc/prorobe.conf contains the entry "alias eth0 3c59x", /sbin/modprobe tries loading the module 3c59x.ko.
当管理员使用ifconfig来配置一个还没有加载驱动程序的网卡时,例如eth0设备,内核发送一个请求到/sbin/modprobe来加载名为“eth0”的设备。如果/ect/prorobe.conf里包含了条“alias eth0 3c59x”的信息,/sbin/modprobe就试着加载3c59x.ko这个模块。

[*] Note that because the device driver has not been loaded yet, eth0 does not exist yet either.
注意,因为这里设备的驱动还没有被加载,所以eth0还不存在!

When the administrator configures Traffic Control on a device with the IPROUTE2 package's tc command, it may refer to a queuing discipline or a classifier that is not in the kernel. In this case, the kernel sends /sbin/modprobe a request to load the relevant module.
当管理员在一个设备上使用IPROUTER2软件包里的tc命令来配置网络流量控制时,这可能会涉及到队列原则和一个不在内核里的分类器。在这种情况下,内核发送一个请求给/sbin/modprobe去加载相关的模块。

For more details on modules and kmod, refer to Linux Device Drivers.
关于kmod和模块的细节,可以参考Linux Device Drivers.

5.8.2. Hotplug 热插拨
Hotplug was introduced into the Linux kernel to implement the popular consumer feature known as Plug and Play (PnP) . This feature allows the kernel to detect the insertion or removal of hot-pluggable devices and to notify a user-space application, giving the latter enough details to make it able to load the associated driver if needed, and to apply the associated configuration if one is present.
热插拨被引入到Linux内核中去实现众所周知的流行PnP(即插即用)的用户特性。这一特性充许内核检测插入和移走的支持热插拨的设备,并且会告知用户空间的应用程序,如果有一个出现时就应用相关的配置。后面会足够详细的介绍是如何在需要时加载相关的驱动。

Hotplug can actually be used to take care of non-hot-pluggable devices as well, at boot time. The idea is that it does not matter whether a device was hot-plugged on a running system or if it was already plugged in at boot time; the user-space helper is notified in both cases. The user-space application decides whether the event requires any action on its part.
热插拨技术实际上可以在启动时,很好的应用在非热插拨设备中。这样使用是因为它并不关注在启动时,已经插在系统中的设备是不是热插拨的;用户空间的助手程序在两种情况下都会被通知。用户空间的应用程序来决定是否要在事件上对自己的设备做出响应。

Linux systems, like most Unix systems, execute a set of scripts at boot time to initialize peripherals, including network devices. The syntax, names, and locations of these scripts change with different Linux distributions. (For example, distributions using the System V init model have a directory per run level in /etc/rc.d/, each one with its own configuration file indicating what to start. Other distributions are either based on the BSD model, or follow the BSD model in compatibility mode with System V.) Therefore, notifications for devices already present at boot time may be ignored because the scripts will eventually configure the associated devices.
Linux系统,或者是类Unix系统,在系统启动时要执行大量的脚本来初始化外围设备,包括网络设备。这些脚本的语法,名字,以及存放的位置都会根据不同的发生版有所变化。(例如,使用System V来初始化模型的发行版,/etc/rc.d/对每个运行级上都有一个目录,每个人在启动时都有自己的配置文件来决定启动什么。其它的发行版,有基于BSD模型的,也有根据BSD模型而兼容System V的模型。)因此,发给在启动时已经出现的设备的通知可能会被忽略,因为脚本最终会配置这相关的设备。

When you compile the kernel modules, the object files are placed by default in the directory /lib/modules/kernel_version/, where kernel_version is, for instance, 2.6.12. In the same directory you can find two interesting files: modules.pcimap and modules.usbmap. These files contain, respectively, the PCI IDs[*] and USB IDs of the devices supported by the kernel. The same files include, for each device ID, a reference to the associated kernel module. When the user-space helper receives a notification about a hot-pluggable device being plugged, it uses these files to find out the correct device driver.
当你编译内核模块时,目录文件已经放在默认的目录/lib/modules/ker_version/中,当kernel_version给定版本,例如2.6.12。在同样的目录下,你可发现两个有趣的文件:modules.pcimap和modules.usbmap。这些文件分别包括内核所支持的所有设备的PCI的ID,和USB的ID。同样的文件还包括每个设备的ID,以及它所关联到内核的模块。当用户空间的助手程序收到一个热插拨的设备被插入的通知时,它使用这些文件去查找出正确的设备驱动。

[*] The section "Example of PCI NIC Driver Registration" in Chapter 6 gives a brief description of a PCI device identifier.

The modules.xxxmap files are populated from ID vectors provided by device drivers. For example, you will see in the section "Example of PCI NIC Driver Registration" in Chapter 6 how the Vortex driver initializes its instance of pci_device_id. Because that driver is written for a PCI device, the contents of that table go into the modules.pcimap file.
这个modules.xxxmap文件是板上组装的由设备驱动提供的ID向量。例如,你会在第6章中的“一个PCN NIC设备驱动注册实例”这一节中看到,Vortex驱动是如何初始化它的一个pci_device_id实例。因这这个驱动被写成支持一个PCI设备,所以它的内容表存放在modules.pcimap文件中。

If you are interested in the latest code, you can find more information at http://linux-hotplug.sourceforge.net.
如果你已经对最后的代码吸引住,你可以在http://linux-hotplug.sourceforge.net上找到更多的信息。

5.8.2.1. /sbin/hotplug
The default user-space helper for Hotplug is the script[] /sbin/hotplug, part of the Hotplug package. This package can be configured with the files located in the default directories /etc/hotplug/ and /etc/hotplug.d/.
默认的用户空间支持热插拨的助手程序在/sbin/hotplug脚本中,是热插拨软件包中的一部份。这个包可以通过在默认目录/etc/hotplug/ and /etc/hotplug.d中配置。

[] The administrator can write his own scripts or use the ones provided by the most common Linux distributions.

The kobject_hotplug function is invoked by the kernel to respond to the insertion and removal of a device, among other events. kobject_hotplug initializes arg[0] to /sbin/hotplug and arg[1] to the agent to be used: /sbin/hotplug is a simple script that delegates the processing of the event to another script (the agent) based on arg[1].
内核调用kobject_hotplug函数在其它事件中来报告一个设备的插入和移除。kobject_hotplug用/sbin/hotplug来初始arg[0],同时arg[1]以这样的方式来做代理:/sbin/hotplug是一个简单的脚本,用于代理另一个基于arg[1]脚本(代理)的进程事件。(不明白说的啥)

The user-space helper agents can be more or less complex based on how fancy you want the auto-configuration to be. The scripts provided with the Hotplug package try to recognize the Linux distribution and adapt the actions to their configuration file's syntax and location.
用户空间的助手代码可以有更多或者更少的复杂性。这要基于你的想象力,你想自动到什么程度。这个软件包提供的脚本试着识别Linux的发行版,并适配它的配置文件的语法和位置。

Let's take networking, the subject of this book, as an example of hotplugging. When an NIC is added to or removed from the system, kobject_hotplug initializes arg[1] to net, leading /sbin/hotplug to execute the net.agent agent.
让我们来看看网络,这也是本书的主题,做为一个热插拨的例子。当一个NIC添加到系统或者从系统中移除时,kobject_hotplug 给网络初始化arg[1],让/sbin/hotplug去执行这个net.agent代理。

Unlike the other agents shown in Figure 5-3, net.agent does not represent a medium or bus type. While the net agent is used to configure a device, other agents are used to load the correct modules (device drivers) based on the device identifiers.
与图5-3中所显示的其它代理不同,net.agent并不会响应一个媒体或者总线类型。当net代理被用于配置一个设备时,另一个代理就被用于根据模块的设备ID来锁定上下文。

net.agent is supposed to apply any configuration associated with the new device, so it needs the kernel to provide at least the device identifier. In the example shown in Figure 5-3, the device identifier is passed by the kernel through the INTERFACE environment variable.
net.agent是假设可以支持任何关于新设备的配置的,所以它需要内核最少提供设备标识。在图5-3的例子中,这个设备标识是内核通过INTERFACE环境变量为传递的。

To be able to configure a device, it must first be created and registered with the kernel. This task is normally driven by the associated device driver, which must therefore be loaded first. For instance, adding a PCMCIA Ethernet card causes several calls to /sbin/hotplug; among them:
为了可以配置一个设备,它开始必须被创建和注册到内核。这个任务通常是由相关的设备驱动来完成的,也就是说,这(设备驱动)必须是要先加载的。

One leading to the execution of /sbin/modprobe,[*] which will take care of loading the right module device driver. In the case of PCMCIA, the driver is loaded by the pci.agent agent (using the action ADD).
可执行文件/sbin/modprobe,用于关注加载正确的设备驱动模块。在PCMCIA情况下,驱动会由pci.agent这个代理来加载(使用ADD动作)。

[*] Unlike /sbin/hotplug, which is a shell script, /sbin/modprobe is a binary executable file. If you want to give it a look, download the source code of the modutil package.
与/sbin/hotplug不一样,这只是一个脚本,/sbin/modprob是一个二进制的可执行文件。如果你想看看它,可以下载modutil软件包。

One configuring the new device. This is done by the net.agent agent (again using the action ADD).
一个配置新设备,这是由net.ageng代理来完成的(再次使用ADD动作)。

原文地址:https://www.cnblogs.com/WuCountry/p/1395592.html