Persistent device naming with udev

Suppose that you have to build a root filesystem which will be dumped on thousands of systems and you have multiple ethernet interfaces of same chip, same kernel driver. You will realize that some of the systems start use ethernet interfaces with eth1, eth2 and some of them eth3, eth7 etc.

In order to have a persistent ethernet interface naming, you should give a udev rule to specify which name assigned which card. In this stage, it is possible to use some udev variables for given device. You can look at this:

udevinfo -a -p /sys/class/net/eth1
    KERNEL=="eth1"
    SUBSYSTEM=="net"
    DRIVER==""
    ATTR{addr_len}=="6"
    ATTR{iflink}=="3"
    ATTR{ifindex}=="3"
    ATTR{features}=="0x0"
    ATTR{type}=="1"
    ATTR{link_mode}=="1"
    ATTR{address}=="00:15:00:4a:67:b6"
   ...

As you can see, it is easy to select right card with an udev rule based on MAC address (ATTR{address} field). But if you want to build a filesystem image which will be deployed on same type of systems with different mac addresses, you can’t enter an udev rule relying on mac address.

Solution is looking at the parent device info of udevinfo's output:

  looking at parent device '/devices/pci0000:00/0000:00:1c.0':
    KERNELS=="0000:00:1c.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="e100"

You will see that even if all the ethernet cards runs with e100 kernel module, their pci bus id (KERNELS field) is different. So, we can make a rule like that: First pci bus with e100 module will have eth2, second eth3, or third with a name of vlan0. Here a simple rule to do this:

KERNELS=="0000:00:1c.0", SUBSYSTEMS=="pci", \ DRIVERS=="e100", NAME="eth2"
KERNELS=="0000:00:1d.0", SUBSYSTEMS=="pci", \ DRIVERS=="e100", NAME="eth3"
KERNELS=="0000:00:0f.0", SUBSYSTEMS=="pci", \ DRIVERS=="e100", NAME="vlan0"

You can save this rule file in /etc/udev/rules.d/z99custom.rules

You can also test new udev rules with:

udevinfo -a -p /sys/class/net/eth1

It just basically shows that what the name will be on next udev start. Please note that, if a previous matching udev rule already exist in /etc/udev/rules.d directory, your rule doesn’t work, so you must delete conflicting rule first for that case.

For detailed information about udev usage you can visit: Writing udev rules