Why udev may be trying to rename your VLAN interfaces to bad names

December 25, 2019

When I updated my office workstation to Fedora 30 back in August, I ran into a little issue:

It has been '0' days since systemd/udev blew up my networking. Fedora 30 systemd/udev attempts to rename VLAN devices to the interface's base name and fails spectacularly, causing the sys-subsystem*.device units to not be present. We hope you didn't depend on them! (I did.)

I filed this as Fedora bug #1741678, and just today I got a clue so that now I think I know why this happens.

The symptom of this problem is that during boot, your system will log things like:

systemd-udevd[914]: em-net5: Failed to rename network interface 4 from 'em-net5' to 'em0': Device or resource busy

As you might guess from the name I've given it here, em-net5 is a VLAN on em0. The name 'em0' itself is one that I assigned, because I don't like the network names that systemd-udevd would assign if left on its own (they are what I would call ugly, or at least tangled and long). The failure here prevents systemd from creating the sys-subsystem-net-devices-em-net5.device unit that it normally would (and then this had further consequences because of systemd's lack of good support for networks being ready).

I use networkd with static networking, so I set up the em0 name through a networkd .link file (as covered here). This looks like:

[Match]
MACAddress=60:45:cb:a0:e8:dd

[Link]
Description=Onboard port
MACAddressPolicy=persistent
Name=em0

Based on what 'udevadm test' reports, it appears that when udevd is configuring the em-net5 VLAN, it (still) matches this .link file for the underlying device and applying things from it. My guess is that this is happening because VLANs and their underlying physical interfaces normally share MACs, and so the VLAN MAC matches the MAC here.

This appears to be a behavior change in the version of udev shipped in Fedora 30. Before Fedora 30, systemd-udevd and networkd did not match VLAN MACs against .link files; from Fedora 30 onward, it appears to do so. To stop this, presumably one needs to limit your .link files to only matching on physical interfaces, not VLANs, but unfortunately this seems difficult to do. The systemd.link manpage documents a 'Type=' match, but while VLANs have a type that can be used for this, native interfaces do not appear to (and there doesn't seem to be a way to negate the match). There are various hacks that could be committed here, but all of them are somewhat unpleasant to me (such as specifying the kernel driver; if the kernel's opinion of what driver to use for this hardware changes, I am up a creek again).


Comments on this page:

From 193.219.181.211 at 2019-12-25 05:32:50:

In a way this problem even predates systemd – even back when renaming was mostly done via handwritten udev rules, it was way too early to forget that VLAN devices share the parent's MAC.

The usual trick used in udev rules is to match the driver against ?*, i.e. just ensure it is non-empty (which is always true for Ethernet but never true for vlan).

Oddly, I was sure the .link processor provided a synthetic Type for Ethernet devices as well (the kernel doesn't have one for historical reasons). Will check later.

From 193.219.181.211 at 2019-12-25 05:34:03:

*way too easy

Sigh. It is way too early for me to be online today.

By Alex Xu (Hello71) at 2019-12-25 07:17:29:

scanning the list of [Match] options, wouldn't it be possible to just manually specify the Property? that one allows ! negation.

Written on 25 December 2019.
« The BSD and Linux approaches to development put coherence in different places
Some reasons for Go to not make system calls through the standard C library »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Dec 25 01:47:33 2019
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.