SUSE Linux Hotplug System Overview
==================================
(Christian Zoz <zoz@suse.de>)


The hotplug system in SUSE Linux is derived from the Linux Hotplug Project, but
behaves partially different. The main difference is that we don't use the event
multiplexer /etc/hotplug.d/ and use /sbin/hw{up,down} to initialize/stop
devices. Details can be found in this document which does describe of course not
only the differences but the whole system.


HOW IT WORKS
============


Hotplug is always used
^^^^^^^^^^^^^^^^^^^^^^
The hotplug system is not only used for devices that can really be (un)plugged
at runtime, but for all devices which are detected after the kernel has booted.
This means that before hot/cold-plug were started, only some basic devices are
initialized, like main bus system (mostly pci), boot disks, keyboard, etc.
All devices handled by hotplug have an entry in sysfs.


Devices and interfaces
^^^^^^^^^^^^^^^^^^^^^^
Not only devices, but also interfaces are handled by hotplug. We distinguish
between devices and interfaces to devices. A device is that part that is
connected to any kind of bus or interface. An interface is what is provided by
this device where we can connect another device or an application. In sysfs
devices can be found in /sys/devices. Interfaces are listed below /sys/class or
/sys/block. All interfaces should have a link to their devices in sysfs, but
there are still some drivers which don't add that link.

Examples:
- A PCI network card is a device which is connected to the pci bus
  (/sys/devices/pci0000:00/0000:00:1e.0/0000:02:00.0). This device
  provides a network interface, which is used by network services or where
  virtual network devices (e.g. a tunnel or vlan) are connected
  (/sys/class/net/eth0).
- A PCI SCSI controller is a device (/sys/devices/pci0000:20/0000:20:01.1) which
  provides several physical interfaces in the form of a bus
  (/sys/class/scsi_host/host1).
- A SCSI disk is a device (/sys/devices/pci0000:20/0000:20:01.1/host1/1:0:0:0)
  with multiple interfaces (/sys/block/sda*)


Hotplug events
^^^^^^^^^^^^^^
All other devices and interfaces are initialized via hotplug. For each device or
interface there is a hotplug event, which is handled by the appropriate hotplug
agent. Hotplug device events are triggered in two different ways:
- By the kernel if the connection to a device is established. There are again
  two cases:
  + The bus or interface where the device is connected is already active and the
    device is plugged physically (USB, PCMCIA, sometimes PCI, ...). The bus
    driver generates an event for each plugged device.
  + The device was already physically connected, but the underlying bus or
    interface was not initialized. Now when the bus is initialized, the bus
	 driver scans the bus for all connected devices and generates an events per
    device.
- By coldplug, which does rescan important busses and generates events for all
  devices that are still not initialized.
Further there are interface events which are triggered by the kernel as soon as
a driver registers an interface.

To generate a hotplug events means to call a hotplug usermode tool, usually
/sbin/hotplug. The kernel calls whatever is written to /proc/sys/kernel/hotplug.
The usermode tool /sbin/hotplug mainly looks for a hotplug agent matching the
type of the event. If there is no agent for that event type and there is a file
'dev' in the devicepath, then it calls generic_udev.agent.

If events of certain types should be skipped always you may set these types to
HOTPLUG_SKIP_EVENTS in /etc/sysconfig/hotplug.


Hotplug agents
^^^^^^^^^^^^^^
Starting with kernel 2.6 there are a lot of different hotplug events, so that it
is not not easily possible to know all of them. Every new driver may introduce a
new event type. For all well known events there are dedicated agents which
execute the necessary actions. 

Device agents mainly have to load kernel modules but sometimes some extra
commands may have to be called. In some hardware architectures as IBM S390 each
device has to be enabled by writing special values somewhere in procfs or sysfs.
In SUSE Linux hotplug we always call /sbin/hw{up,down} to care about these jobs.
It looks in /etc/sysconfig/hardware for a configuration that matches the device
and uses that information. If hwup does not find a configuration it falls back
to automatic module loading. See "automatic module loading" below. For details
about hw{up,down} have a look at /usr/share/doc/packages/sysconfig/README and
'man hwup'.
In future releases we plan to skip old style automatic modules loading
completely and let hwup trigger a configuration process if no configuration file
was found.

Interface agents have mostly two jobs. Setting up an interface and/or call udev
to create a device node. Setting up interfaces is done by /sbin/if{up,down}
which is currently only used for network interfaces. See the sysconfig docu in
/usr/share/doc/packages/sysconfig/README and 'man ifup' for details about
if{up,down}. Also udev has its own documentation and manpages. Handling of
storage devices will be described in section "storage devices".

If there is no agent for a certain event and the device path in sysfs for the
interface contains a file 'dev' then we call a generic udev agent to make sure
that all needed device nodes are created.


Automatic module loading
^^^^^^^^^^^^^^^^^^^^^^^^
All agents that have to initialize devices try to find a driver module for the
device if hwup failed. To do this they process some module maps. All agents look
first in a /etc/hotplug/*.handmap and only if there was no hit they look in
/lib/modules/<kernelversion>/modules.*map. Therefore if the default from the
kernels map does not fit your needs, you may enter an appropriate line in the
handmap. Of course there are two extra rules for PCI and USB.

The usb.agent does additionally look in /etc/hotplug/usb.usermap and
/etc/hotplug/usb/*.usermap for usermode drivers; that means you may start
executables for certain devices.

The pci.agent does at the very first ask hwinfo for driver modules and only look
in the maps if hwinfo does not return any driver. But because hwinfo looks
itself in pci.handmap and the kernel map this should normally not be needed.
hwinfo has an additional database which is used after pci.handmap but before the
kernel map. 

Additionally the pci.agent may be limited to load only modules that are in
certain subdirectories of /lib/modules/<kernelversion>/kernel/drivers. If there
is a least one subdirectory name in HOTPLUG_PCI_DRIVERTYPE_WHITELIST, only
modules from these subdirectories will be loaded. Modules from subdirectories
listed in HOTPLUG_PCI_DRIVERTYPE_BLACKLIST will never be loaded.

Finally there is /etc/hotplug/blacklist. This file contains one module name per
line that should never be loaded by any agent.

If there are multiple modules matching in one map, loading stops after one
module has been loaded succesfully, because normally these modules are just
alternative drivers. If you want hotplug to load all matching modules then you
may set HOTPLUG_LOAD_MULTIPLE_MODULES=yes.

Remember that all this does not affect module loading via hwup. Automatic module
loading is just a fall back mechanism, which will be dropped soon.


Storage devices
^^^^^^^^^^^^^^^
<To be written by adrian>


Network devices and their interface names
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If there are multiple network devices which have different drivers it could
happen that interface names for these devices switch randomly at every boot.
This is because hotplug events are handled asynchronously and therefore two
drivers initialize their devices in paralell. This means there may be a race
between these processes.

To avoid this problem we queue events for network devices. If this seems to be
problematic for any reason you may switch it off in /etc/sysconfig/hotplug with
HOTPLUG_PCI_QUEUE_NIC_EVENTS=no.

But the recommended way to achive persistent interface names is to set dedicated
interface names inside the interface configuration files. Then queuing of events
will not longer be necessary.  See the section about persistent names in
/usr/share/doc/packages/sysconfig/README.


PCI hotplugging
^^^^^^^^^^^^^^^
There are some computer that allow hotplugging of PCI devices. For proper PCI
hotplugging we have to load special kernel modules which may harm on non PCI
hotplug machines. Because we cannot autodetect if there are hotplug PCI slots,
you have to enable this feature manually by setting HOTPLUG_DO_REAL_PCI_HOTPLUG
in /etc/sysconfig/hotplug.


Coldplug
^^^^^^^^
Coldplug cares about devices that were plugged before hotplug system was active.
This is always the case at boot time. It also cares about devices that are not
easily detecable.

At first rccoldplug calls hwup for each static hardware configuration in
/etc/sysconfig/hardware (hwcfg-static-*). This way old or exotic hardware may be
initialized. This may also help to initialize devices in a certain order.

Then the scripts /etc/hotplug/*.rc are scanning for devices that are still not
initialized and generate hotplug events for them. For PCI devices there are a
whitelist and a blacklist of device types, which should be handled or skipped.
These lists are described in comments of /etc/sysconfig/hotplug.

The *.rc scripts print a character for each scanned device:
 .  device is already initialized and therefore skipped
 *  generate a hotplug event for this device
 W  the device is not in the whitelist and therefore skipped
 B  the device is in the blacklist and therefore skipped


-------------------------------------------------------------------------------


HOW TO CONFIGURE
================


/etc/sysconfig/hotplug
^^^^^^^^^^^^^^^^^^^^^^
There is a set of variables in this file to change the behavior of hotplug or
coldplug. There are comments in this file that explain the impact of these
variables.


/proc/sys/kernel/hotplug
^^^^^^^^^^^^^^^^^^^^^^^^
It contains the name of the executable which is called by the kernel.


Bootparameters
^^^^^^^^^^^^^^
There are some parameters that may be set at the bootprompt:
- NOHOTPLUG=yes      If set no hotplug events will be handled until a manually
                     called 'rchotplug start'.
- NOCOLDPLUG=yes     If set coldplug will be skipped
- HOTPLUG_TRACE=<N>  If set hotplug will print the name of the module, it is
                     going to load, to console and wait N seconds.


-------------------------------------------------------------------------------


HOW TO DEBUG
============


Logging
^^^^^^^
With default setting hotplug writes only some important messages to syslog. If
you are interested in more details what is done by hotplug then set
HOTPLUG_DEBUG=yes. If you suspect a bug in any of the scripts you may set
HOTPLUG_DEBUG=max. Then every shell command of these scripts is logged, but this
results in a huge amount of lines in the logfile.

By default the hotplug system uses syslog, i.e. you will find all messages in
/var/log/messages. But when booting syslog is started after hot/coldplug and a
lot of messages get lost. Therefore you may set HOTPLUG_SYSLOG to another
value. Have a look at the comments in /etc/sysconfig/hotplug.


Boot problems
^^^^^^^^^^^^^
If your machine hangs at boot time you may switch of hotplug (NOHOTPLUG=yes)
and/or coldplug (NOCOLDPLUG=yes) at the bootprompt. 
NOHOTPLUG prevents hotplug from calling any agent no matter where the event
comes from, but static hardware configurations (hwcfg-static-*) are still
applied from coldplug. If you later start hotplug manually (not via runlevel
switch) then NOHOTPLUG will be ignored.
NOCOLDPLUG does skip coldplug at boottime, that means no device scan and no
appliance of static hardware configurations, but hotplug is still working.

If you assume that a module loaded from hotplug is the culprit you may watch
hotplug if you set HOTPLUG_TRACE=<N> at the bootprompt. It then writes the name
of the module to load to the console and waits for N seconds before loading it.
There is no interactive mode.


The eventrecorder
^^^^^^^^^^^^^^^^^
There is /sbin/hotplugeventrecorder, which is always called by /sbin/hotplug and
/sbin/hotplug-stopped. If a directory /events exists, then all hotplug events
will be stored there in single files.


-------------------------------------------------------------------------------
