SUSE Linux Device and Interface Configuration
Novell Cool Solutions: Feature
Digg This -
Posted: 29 Jul 2004
This document describes a new concept for device initialization and interface configuration. The specific configuration files for other services and processes that may also be located in /etc/sysconfig are described in separate documents accompanying their respective packages.
The first part of this document explains the background needed to understand why the changes made. The second part explains how device initialization and interface configuration are handled.
General Concept and Background
With SUSE Linux 9.1 and all products based on it, device initialization and interface setup has been redesigned. It is based on hotplug and the new sysfs in kernel 2.6. The whole concept will be implemented, step by step, over the next releases.
For a better understanding of this new concept, it is important to understand the meaning of the terms 'device' and 'interface'. A device is a physical thing; something that may break if dropped. A device usually needs to be initialized by a driver. After initialization, the driver creates interfaces to that device. An interface is software; it has a name and a set of functions. There may be several interfaces per device.
Normally, a device and its interface are one unit. For example, a PCI NIC is a unit that consists of a PCI device and a network interface. What was missing in kernels before 2.6 was information regarding which interface belonged to which device. If a device was initialized, the kernel numbered the new interface. However, this number did not depend on the device for that interface, but on which other interfaces of the same class had already been initialized.
The only relation between devices and interfaces were alias lines in modules.conf. However, these never guaranteed anything. For example, there could be:
alias eth0 driver0 # for device0 alias eth1 driver1 # for device1
If device0 could not be initialized, eth0 was not registered. Then an ifup eth1 triggered the loading of driver1. However, the new interface was named eth0, not eth1. This was a rare occurrence in the past, but with more and more hotpluggable devices, it became a real problem.
The same thing happened with other devices, such as storage devices. The kernel assigned interface names like /dev/sd<X> that were not fixed to certain devices. The kernel enumerated them in the order they started. (Imagine what would happen if the second of four SCSI disks fails and the kernel assigns sdb and sdc to what once were sdc and sdd.)
Sysfs and Persistent Names
With sysfs, it is now possible to have persistent interface names. The subdirectories /sys/devices/, /sys/bus, /sys/class, and /sys/block are mainly of interest in sysfs. /sys/devices and /sys/bus are two different views of the hardware (the devices). /sys/class and /sys/block contain all interfaces that can be addressed from applications. (Even if you were used to calling /dev/sda a device file, in our terminology this is the interface to a storage device.)
The main key that makes the new concept possible are links named 'device', which point from an interface subdirectory in /sys/class or /sys/block to a device subdirectory in /sys/devices. It is only possible to know which interface belongs to which device if this link exists:
/sys/block/sda/device -> ../../devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1:1.0/host0/0:0:0:0 /sys/block/sdb/device -> ../../devices/pci0000:20/0000:20:01.1/host1/1:0:0:0 /sys/class/net/eth0/device -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.0 /sys/class/net/eth2/device -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:01.1/0000:07:00.0
Now that these relationships are known, it is possible to assign persistent names to the interfaces. A table is needed that maps the device to the interface names. For all devices that have /dev/* nodes as interfaces, this can be done in /etc/udev/udev.conf. For network devices, the configurations files in /etc/sysconfig/network/ifcfg-* need to be named in a way that describes the hardware. For example, the configuration ifcfg-id-00:e0:98:a0:83:c2 is always used for the device with MAC address 00:e0:98:a0:83:c2. In this configuration, a persistent interface name may be specified.
Reversal of Device Initialization and Interface Configuration
Setting up network interfaces used to begin with the interface. There was a configuration for a network interface that did not need to exist. An ifup interface triggered a modprobe of the module specified in modules.conf. The driver looked for hardware that it could handle and registered all interfaces it created. The only exceptions were USB and PCMCIA, which are hotpluggable.
But now, since the device-interface relationships are known, the process begins at the other end, namely the device. At boot time, a scan is performed for available devices and hotplug events are triggered for each device found. Devices plugged at runtime also trigger an event. Hotplug handles these events and calls the appropriate agent to initialize the devices. In other words, it loads the driver. When the driver registers new interfaces, it again triggers hotplug events, this time for the interfaces. These events are handled by one of the interface agents.
Therefore, alias lines are not needed in modprobe.conf. These are deprecated, because they can cause weird effects. Formerly these aliases helped automatically initialize a device if some operation from a nonexistent interface was requested. Now the device is initialized and the interface is set up automatically. Imagine you want to test, with ifconfig (*), if a certain interface is available and this interface is currently not there -- there is no driver loaded for the device. Then, when 'ifconfig eth1' is called, it does a 'modprobe eth1', which loads the driver specified in the alias eth1 line. This driver triggers an event that sets up the interface via ifup. This is not what you wanted.
'ifup' does load modules, but it just acts on existing interfaces. In normal operation, all available devices are initialized at boot time, so that there is no need to do this later. If the system is configured to leave a certain device uninitialized, it can be initialized later by starting hwup manually. If the interface for that device has an 'auto' start mode, it is set up automatically.
(*) 'ifconfig' is deprecated as well, but for other reasons. 'ip' can now be used instead. However, it is preferred that ifup, ifstatus, and ifdown be used.
Devices should normally be initialized via hwup and stopped via hwdown. Device configurations can be found in /etc/sysconfig/hardware. Mostly, these scripts are called from hotplug agents. The profile manager (SCPM) or power management can also stop and start devices. An hwup on a node of the hardware tree should trigger the initialization of all devices connected to this node via hotplug. An hwdown on a node should first stop connected devices before stopping the node. One problem in this concept is that often one single device cannot be initialized if there are multiple devices served by the same kernel module. This will probably change in the future.
In SUSE Linux 9.1, this concept is not very evolved. hwup is used for hotplug, but if there is no configuration for a device, the system tries automatically to find a driver.
Currently hwup only loads kernel modules and calls possible helper scripts. hwup is called from hotplug with a description of the device (mostly the sysfs devpath). hwup uses getcfg to find a matching configuration and applies that configuration. See man 8 hwup for more information. A start mode can also be added to a configuration. To leave a device uninitialized at boot time or when plugged, set STARTMODE=manual (or off) in the configuration file. The configuration files are /etc/sysconfig/hardware/hwcfg-<configuration name>.
Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com