Hotplugging and Policy Agents

17-Jan-20001: See the latest information, including setup instructions, at the linux-hotplug project ...

This document gives an overview of /sbin/hotplug and related hotplug software, used to perform dynamic reconfiguration after a device has been "hotplugged" into a running system based on the Linux 2.4 kernel. The first part of this document is an overview of user mode policy agents generically, and is followed by information about how those agents are called. There are descriptions of the interfaces supported by USB, PCI/Cardbus, and Network Hotplug Policy Agents.

If you don't want to read about it, you may prefer to just download and install the Linux-USB hotplug tools, so that USB is fully set up and so that you can use your kernel HOTPLUG support. If your GNU/Linux OS distribution already initializes USB, and you're using a recent 2.4 kernel (test11 or later), you can just grab a copy of the /sbin/hotplug script right from CVS. That gives you some basic USB, Network, and PCI/Cardbus hotplugging: it loads modules and brings network interfaces up. If you provide a smarter policy agent, it'll gladly call it for you!

Sorry, there's not a "how-to" yet.

User Mode Policy Agents

In this document, hotplugging is what a user does with certain types of hardware connections like USB, Cardbus, and networks. He (or she) connects components with power on, knowing that each system will immediately see and use those connections. Think about some kinds of things that may need to happen to make that work:

Binding drivers to new devices.
The kernel does this automatically, for drivers that are already loaded. Otherwise some user mode task needs to modprobe the driver. Complex driver selection algorithms may be needed.
Driver-specific configuration actions
Some drivers may need special setup such as starting up a dedicated daemon or mounting a filesystem. Others may need an installation step, calling for administrative intercession.
Subsystem-specific configuration actions
When a network interface becomes available, the system may be able to recognize and enable it immediately. Such configuration is done using tools like "ifconfig", and saved system configuration data files. (Printer setup may eventually be similar.)

Such tasks are normally driven by shell scripts, and there's no reason not to keep doing it that way. What's needed is a working framework to tie it together. Preferably one that's simple and can grow easily. Here, the scripts in such a framework are called hotplug "policy agents", and one way that they are tied together is by having a common entry point (the /sbin/hotplug program) that can be used when debugging, logging, and otherwise controlling a system's varied hotplug agents.

In effect, these agents are receivers in event delivery channels. The event can be delivered by the kernel (invoking a command directly) or by a user mode daemon (monitoring something like /proc/bus/usb or devfs). Both approaches have been used. This document focuses on the path where the kernel invokes a command directly. It's lower overhead since it doesn't tie down system resources, and it can be especially simple to set up and run.

How are Agents Called?

The kernel calls hotplug agents using the /sbin/hotplug program. That's the name we'll assume here, but the actual name is gotten from the /proc/sys/kernel/hotplug file. Like all this functionality, it isn't available unless the kernel is compiled with the HOTPLUG kernel configuration option.

Such agents may be called when a subsystem detects a new object, such as a device (USB, Cardbus, etc) or an abstraction layered on top of a device (network interface, print queue, etc). Some may be called at other times also; and the same framework could handle some less dynamic bootstrapping tasks.

The first parameter to that program identifies the particular type of agent that is being called. Agent types include:

The reference implementation will invoke any agent named /etc/hotplug/type.agent if it is available; otherwise, it may use some built-in code. The reference implementation is what one might call an "80%" implementation; you may well run into things it should do, but doesn't.

Only that first argument to /sbin/hotplug is standard, all other parameters may be used to pass information to the agent. That includes positional arguments and named environment variables. These standard environment variables are defined:

Variable Example Notes
DEBUG kernel Set only if the event notifier is in a debugging mode, suggesting the same should be true of the policy agent.
HOME / Conventional; included "just in case"
PATH /sbin:/bin:/usr/sbin:/usr/bin Conventional "trusted" system path

There is a convention that similar actions should use similar idioms. For example, when things are added the "add" verb is used to describe that event (not "insert" or some other idiom). Devices can be "remove"d too (they aren't "eject"ed).

USB Policy Agent

A USB policy agent should be installed into /etc/hotplug/usb.agent where it will be invoked by /sbin/hotplug as appropriate.

The current API to the USB policy agent is used from the kernel and by (older) user mode invokers. It uses named environment variables as shown in the following tables. Any command line parameters provided are ignored. This API is used by kernels after about 2.4.0-test5, and some 2.2 backports.

Variable Example Notes
ACTION add a USB device has been added or removed;
PRODUCT 46d/c281/108 idVendor/idProduct/bcdDevice, from device descriptor. Numbers are hexadecimal, without leading '0x' or zeros.
TYPE 9/0/0 bDeviceClass/bDeviceSubClass/bDeviceProtocol, from device descriptor ... when 0/*/* is seen, a variable of type INTERFACE is also provided. Numbers are decimal.
INTERFACE 3/1/1 bInterfaceClass/bInterfaceSubClass/bInterfaceProtocol, from first interface descriptor. Available only for device class zero. Numbers are decimal.

If usbdevfs is enabled, the following variables are also available:

Variable Example Notes
DEVFS /proc/bus/usb Where the USB "drivers" list lives; perhaps this will get coupled to /devfs in some 2.5-ish configurations
DEVICE /proc/bus/usb/002/008 The path to the usbdevfs node for this device

Current agent implementations use PRODUCT, INTERFACE, and TYPE along with a driver information database (preferably modules.usbmap) to select and load a driver module, without requiring any additional USB related software to be installed.

As is the case with PCI and networking, a default agent is in /sbin/hotplug and will be used if no separate policy agent is installed. At this writing, an older /etc/usb/policy agent script may be used if present; it should be configured only with older kernels (kernel 2.2.18, or before 2.4.0-test11).

Cardbus/PCI Policy Agent

A PCI policy agent should be installed as /etc/hotplug/pci.agent where it will be invoked by /sbin/hotplug as appropriate.

The API to the PCI policy agent has no parameters except the "pci" specifier and these named environment variables:

Variable Example Notes
ACTION add a PCI device has been added or removed;
PCI_CLASS c0310 PCI class and programming interface; hex.
PCI_ID TBD $Vendor/$Device, from PCI descriptor. numbers are four hexadecimal characters
PCI_SUBSYS_ID TBD $Vendor/$Device, from PCI descriptor (subsystem info) numbers are four hexadecimal characters
PCI_SLOT_NAME 00:07.2 $Bus:$Slot.$Func, from PCI descriptor. The pci slot name that 'lspci' shows.

As is the case with USB and networking, a default agent implementation is in /sbin/hotplug and will be used if no separate agent is installed at /etc/hotplug/pci.agent; that fallback knows how to load the first module that shows up in modules.pcimap (from depmod 2.3.20 and later).

Network Policy Agent

A network policy agent should be installed as /etc/hotplug/net.agent where it will be invoked by /sbin/hotplug as appropriate.

In 2.4.0-test11, this agent takes no positional parameters, but uses these environment variables:

Variable Example Notes
ACTION register "register" or "unregister" a network interface
INTERFACE eth0 Name of the interface being registered or unregistered.

As is the case with USB and PCI, a default agent implementation is in /sbin/hotplug and will be used if no separate agent is installed at /etc/hotplug/net.agent; that fallback currently tries to bring up interfaces (in the background!) on systems that have an ifup command. (This policy agent is triggered after the network device driver is initialized; it doesn't need to know about bus-specific driver selection, loading or probing policies.)