Discovering device names
Find Nemo!
Recently, a customer asked me what was going on with his system. All of a sudden, he no longer had an eth0
; instead, he was seeing strange names like em1
or p3p1
at the console. He wanted to know exactly what was happening.
The explanation is fairly simple. The rule-based udev subsystem is responsible for naming. If all criteria for a rule match a network device found at boot time, the device is typically given the defined name, such as eth<X>
. Here's an example:
# grep eth0 /etc/udev/rules.d/70-persistent-net.rules SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="f0:de:f1:d5:c1:25", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
The rule says that a network device with the stated MAC address should be given a device name of eth0
and thus be the first device visible on the system. The name in the file is arbitrary. If you like, you can call the card public
or private
. This principle works to a certain extent. The downside is that you don't know which card exactly this is on the system. The only thing that is clear is that it is the card with the stated MAC address; whether this is also the first network device on the system remains unclear. For system administrators, this situation has always been a big worry. If you've ever stood in front of a server with a dozen network ports looking for eth0, you will know exactly what I mean.
Danger of Confusion
The situation is aggravated in network installations where the TFTP boot request is sent on eth0
, but the installer later sends the DHCPDISCOVER message via a different network card identified as eth0
. This situation is really fun to troubleshoot.
I would like the name I see on the system to be identical to the chassis name so that I can see directly whether this is an onboard network port or a port on the external PCI card. You can get help from various tricks, such as, letting the LED on the card flash by issuing an
ethtool -p eth<X>
command, or telling the installer to use the network card via which the boot image was loaded for the installation by issuing ksdevice=bootif
. However, this approach is not convenient.
Early in 2011, some Dell developers published a new tool called biosdevname
under the GPL. Biosdevname ensures that the system BIOS detects the arrangement of the network devices and passes this information to the operating system. The operating system thus knows whether this is an onboard card or an external PCI adapter, and it detects the exact port on the mainboard or the PCI card.
The nomenclature, also known as Consistent Network Device Naming, then follows this pattern. The names of onboard NICs are:
emPort-number_instance_of_virtualFunction
(e.g., em1
for the first onboard card). The situation for external PCI cards is:
pSlot-NumberpPort-number_instance_of_virtual_function
(e.g., p2p1
for the first port on the external NIC in slot 2).
Virtual functions are used when the network card supports Single Root I/O Virtualization (SR-IOV). This functionality makes it possible to split a single PCI device across multiple virtual systems without sacrificing performance. A virtual system is then assigned a virtual function of the device. For example, a network card with a single port appears with multiple entries in the lspci
output on the hypervisor (Listing 1).
Listing 1: Virtual Network Interfaces
# lspci | grep -i ether 07:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) # modprobe -r igb # modprobe igb max_vfs=2 # lspci | grep -i ether 07:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 07:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01) 07:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
The first entry relates to the physical function of the card, and the other two relate to the virtual functions, each of which can be passed on to a virtual system with a simple PCI assignment.
On a system with biosdevname enabled, the following device names thus exist for the network card mentioned above in PCI slot 3: p3p1
, p3p1_0
, p3p1_1
. The designation for the network technology, such as VLAN or aliases, is kept. For example, p3p1:0
designates an alias for the network device p3p1
with more than one IPv4 address.
Info from the BIOS
What tells the operating system which slot a card is plugged into or which ports a card offers? The answer is fairly simple: The system BIOS (on current Dell and HP systems) stores this information in two tables: 9 (for external PCI cards) and 41 (for onboard cards).
The biosdevname simply accesses the tables and writes corresponding entries to a new udev rule. The rule is then responsible for the network cards being given their new names. If the system does not have a current version of SMBIOS, or if the information is missing from the corresponding tables, biosdevname can also access the data from the PCI IRQ routing table. The dmidecode
and biosdecode
tools provide this information on request. Alternatively, the script in Listing 2 can help.
Listing 2: Hardware Check
# curl -s https://fedoraproject.org/w/uploads/3/38/Biosdevname-support-check.sh | bash Checking hardware requirements [ OK ] Checking for SMBIOS type 41 support [ OK ] Checking for SMBIOS type 9 support [ OK ] Checking for PCI Interrupt Routing support [ OK ]
New Rules
Figure 1 shows the information path from the hardware to the application, which then sees the device names defined by biosdevname. The udev rule that implements the device names looks like this:
# grep PROGRAM /lib/udev/rules.d/71-biosdevname.rules PROGRAM="/sbin/biosdevname --smbios 2.6 --policy physical -i %k", NAME="%c", OPTIONS+="string_escape=replace"
You can see that the biosdevname assigns a device a new name (%c
) directly after the kernel driver has detected the device (%k
).
If you want to use the new nomenclature on your system, you should first run the script above to see whether your hardware provides the desired information. Then, delete the /etc/udev/rules.d/70-persistent-net.rules
file. You want the device names to come from biosdevname and not be set statically by udev. Finally, you must rename the configuration files for the network cards below /etc/sysconfig/network-scripts/
and change the DEVICE
entry to a new name.
Red Hat Enterprise Linux as of 6.1, Fedora as of Version 15, and the current versions of openSUSE, SUSE Linux Enterprise Server, and Ubuntu already use the new naming approach, and the installer uses these new names during the installation. If you can't or don't want to change scripts that point to eth<X>
, you can revert to the old way using the biosdevname=0
parameter at boot time.