-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
udev: interface name in link file not applied #9006
Comments
Just to expand on this a bit: this behaviour of link files is in contrast to the behaviour of rule files: in udev-event.c, interfaces with a rule that sets their name are renamed unconditionally with this call to |
Arguably this is a bug in initramfs generator that should have included corresponding link file. dracut normally adds all |
I considered that in my earlier debugging (https://bugs.launchpad.net/netplan/+bug/1770082) I have one situation where a fix to the initramfs generator won't be sufficient. Say you create a virtual machine (say an OpenStack or cloud guest). The Ubuntu initialisation process (cloud-init) for these guests creates a network configuration, but doesn't run update-initramfs (the debian dracut). So you end up with the network configuration installed on the root fs but not the initramfs. I don't know why cloud-init doesn't run update-initramfs; I suspect it's because compressing an initramfs is very slow. Now say you shutdown the guest and change some properties - perhaps change the slot of the ethernet card, from slot 3 to slot 10. (Alternatively on some cloud platforms you can change the instance type which will change the way the ethernet device presents.) Now you have a situation where things will be different based on whether you have a rule or a link file.
Is there a reason link files and rule files should operate differently, and could we make the behaviour consistent? |
If your system does not require network stack during initrd, then how about disabling dracut network module or pass If it requires network stack, then there are at least two choices:
The first choice is what I use, because I do not want to rebuild initrd so often. |
Here's the context: In Ubuntu 16.04, the first-boot network configuration system created a .rule file. Ubuntu 18.04 introduced a new network configuration system that makes .link files instead. We then noticed that interfaces were no longer being renamed. I verified that it's not related to any other changes between 16.04 and 18.04: I created a rules file on 18.04, and that caused the interface to be renamed as expected - even if the rules file was not in initrd. Therefore, I'm trying to figure out if link files should operate the same way as rules files and override previously set names. (With regards to initramfs, neither the rules nor the link file get built into the initrd until at least the next time update-initramfs is run - normally this doesn't occur until the kernel or other early-boot stuff is upgraded, which often doesn't happen for ephemeral cloud instances. So the question comes down to what the correct behaviour should be after you've pivoted to the real root.) |
Can someone comment on why if the rename is encoded in a .rules file systemd-udevd will apply the rule (without requiring the rule to be in the initramfs no less), but if the equivalent is in a .link file it isnt? That's the core issue we're looking at here. What's the rationale for the differing behavior w.r.t interface renaming between .rules and .link files? |
Due to a systemd issue[1], using link files to rename interfaces doesn't work as expected. Link files will not rename an interface if it was already renamed, and interfaces are renamed in initrd. However, rules files will cause a renaming, even if the interface has been renamed in initrd. So, if we have a driver and/or a mac address and set-name, generate a udev rules file in /run/udev/rules.d/70-netplan-<interface>.rules This is at least a temporary fix to LP: #1770082 [1] systemd/systemd#9006 Signed-off-by: Daniel Axtens <dja@axtens.net>
Due to a systemd issue[1], using link files to rename interfaces doesn't work as expected. Link files will not rename an interface if it was already renamed, and interfaces are renamed in initrd, so set-name will often not work as expected when rebooting. However, rules files will cause a renaming, even if the interface has been renamed in initrd. So, while we sort out whether the systemd-udev behaviour is broken or now, we can simply generate udev rules files with appropriate renaming info in /run/udev/rules.d/70-netplan-<interface>.rules A file will be created for non-virtual interfaces with both a set-name and a driver or a mac address in the match stanza. (Renaming from name to name doesn't work.) This is at least a temporary fix to LP: #1770082 As far as testing goes, test successful set-name: generations, and a few cases where we expect no files to be generated. [1] systemd/systemd#9006 Signed-off-by: Daniel Axtens <dja@axtens.net>
Due to a systemd issue[1], using link files to rename interfaces doesn't work as expected. Link files will not rename an interface if it was already renamed, and interfaces are renamed in initrd, so set-name will often not work as expected when rebooting. However, rules files will cause a renaming, even if the interface has been renamed in initrd. So, while we sort out whether the systemd-udev behaviour is broken or not, we can simply generate udev rules files with appropriate renaming info in /run/udev/rules.d/70-netplan-<interface>.rules A file will be created for non-virtual interfaces with both a set-name and a driver or a mac address in the match stanza. (Renaming from name to name doesn't work.) This is at least a temporary fix to LP: #1770082 As far as testing goes, test successful set-name: generations, and a few cases where we expect no files to be generated. [1] systemd/systemd#9006 Signed-off-by: Daniel Axtens <dja@axtens.net>
Due to a systemd issue[1], using link files to rename interfaces doesn't work as expected. Link files will not rename an interface if it was already renamed, and interfaces are renamed in initrd, so set-name will often not work as expected when rebooting. However, rules files will cause a renaming, even if the interface has been renamed in initrd. So, while we sort out whether the systemd-udev behaviour is broken or not, we can simply generate udev rules files with appropriate renaming info in /run/udev/rules.d/70-netplan-<interface>.rules A file will be created for non-virtual interfaces with both a set-name and a driver or a mac address in the match stanza. (Renaming from name to name doesn't work.) This is at least a temporary fix to LP: #1770082 As far as testing goes, test successful set-name: generations, and a few cases where we expect no files to be generated. [1] systemd/systemd#9006 Signed-off-by: Daniel Axtens <dja@axtens.net>
Well, .link files are newer, and declarative, while rules files are more imperative. Generally we follow the rule to not override user choices again and again, and hence apply naming only one. To me this appears a shortcoming of the tools in use. .link files should really be included in the initrd i guess... This is necessary in particular as network devices can't be renamed as soon as they are up, and there's a good chance they might be upped in the initrd again. Hence, I am pretty sure this is something to work on with your distro: they should ensure that if .link files change the initrd is updated too. |
We're generating .link files and network configuration on-the-fly during boot, but outside an initramfs. We also need this to work when booting without an initramfs. The generation time happens before networking is configured, so it's perfectly fine to apply different interface names above distro/systemd policy. If .link files are only useful if they are in place prior to udev starting, that does present a problem for generating .link files dynamically during boot. That certainly imposes a lot on tools wishing to generating them: run before udev or reboot to apply. Would it not be possible to preserve the "don't rename after the interface is up" while allowing .link files to apply even if already named once? Users don't generally write directly to the initramfs so newly generate .link files with properties would end up being present on the rootfs first, needing to be copied into the initramfs and a reboot triggered to update an interface name. We could avoid the update and reboot if we could apply .link files to downed interfaces. |
Well, you also have the option to simply not apply any renaming at all in the initrd, i.e. remove /usr/lib/systemd/network/99-default.link from the initrd. The issue after all is caused because that file is included in the initrd, but no others are, and hence it takes effect even though others will become available during later boot |
Equally caused by ignoring additional .link files if udev has already processed renames once. The use-case where a user would like to rename an interface while it is down but without rebooting is not addressed by leaving .link files out of the initramfs. Surely users can use the ip command to do the rename but then was was the point of having the .link files around if they cannot be used to control things they purport to control? You mentioned the "not to override user choices again and again"; I think it's quite hard to determine whether the first .link files that udev processes are actually the users choice. It certainly feels quite hard to enact the users actual choice in these scenarios. Why is it OK to allow the user to update there .network files with different configuration and restart Networkd to have that apply, but changing the interface name when it is down is "overriding the users choice" ? |
Would a NamePolicy that allows link files to override previously set names be acceptable? |
Things seem to work when i change the NamePolicy in the initrd file /lib/systemd/network/99-default.link to Leaving out the other NamePolicy-options, prevents renaming in the initrd fase. |
We only need to allow interfaces which have requested a rename via .link files to be renamed. Changing the default policy means all interfaces will have kernel names rather than just affecting the interface that was requested to have a specific name. |
Yes, but this NamePolicy=kernel setting is only to be changed in the initrd. |
IIUC, Ihaving the kernel names in the initramfs means we won't get any renames; then when we mount root, the Namepolicy on disk will apply, but since we've not performed any renames in the initramfs then set-names will work. That's worth confirming on a system with multiple nics where we set-name only one of the two. There is still the fundamental question as to why .link renaming is different than any other networkd setting here which can be applied after restarting Networkd. |
That is also my understanding. I am not sure about the fundamental part. Just that renaming an interface which is already up, is problematic. |
Possibly useful code snippet, image as on Ubuntu 18.04:
Then reboot and in the grub bootloader edit the initrd part to /boot/initrd.img |
VMs are your friend for multiple nics; I can confirm the behavior. Note that we're not looking at renaming any interface that is already up. |
Nice to see that confirmed! Thus, the solution/fix seems to lie with the distribution. |
I've not yet confirmed, I was indicating that I can perform the confirmation. I don't agree that the solution/fix is in the distro itself; there still remains the unexplained behavior difference on why .link files cannot be used to apply a rename; For a downed interface, we can apply any amount of network related changes, MTU, or WakeOnLan, and general network configuration, but the name of the interface is somehow excluded from allowing runtime changes via .link files. |
I see your point. Excluding name changes seems unnecessary policy. I am not sure, but the initrd-fase may have an interface up. Could that be problematic? Though, i think that, even when runtime interface name changes were allowed, |
Is there really a need for a new NamePolicy= to handle this? Seems to me like there is some disconnect between what I've been told on another issue and what we're discussing here. Elsewhere, I've been told "systemd-networkd wants to manage the network completely". To me this also reads as "if there's a .link file, doesn't matter if the user renamed their interface elsewhere, we want the name in the config applied". I think this tends to somewhat circumvent the idea of name_assign_type. I tend to agree that systemd-networkd should be authoritative on the state of the interfaces it controls, so having what's in .link files always be in effect sounds like the right thing to do in this case. I think it should be fine to always apply the naming specified in .link, even if an interface has already been renamed: with that being the case, users renaming an interface using the 'ip' command are obviously on their own, but the change is also non-persistent for reboots. Users who really want to rename interfaces at boot elsewhere than in a .link file can still do so via udev rules in the appropriate location (ie. after 80-net_setup_link.rules, so it happens after .link files); otherwise .link files can be used and will obviously be honored. To add to this, netplan tends to be affected by this a bit more since we don't want to write files elsewhere than in /run -- the configs are meant to be "dynamic", created by a systemd generator at boot based on the yaml config (the YAML config is static in /etc; but resulting networkd/NetworkManager config doesn't need to be). And with things written in /run and being dynamic, we obviously don't want to add /run to the initramfs-tools hooks for udev ;) I have a tiny patch that just drops should_rename() and seems to achieve just the right behavior. |
…Policy= is specified This is for issue systemd#9006
Imho explicit user configuration of custom interface names should be honoured. |
…Policy= is specified This is for issue systemd#9006
…Policy= is specified This is for issue systemd#9006
Due to a systemd issue[1], using link files to rename interfaces doesn't work as expected. Link files will not rename an interface if it was already renamed, and interfaces are renamed in initrd, so set-name will often not work as expected when rebooting. However, rules files will cause a renaming, even if the interface has been renamed in initrd. So, while we sort out whether the systemd-udev behaviour is broken or not, we can simply generate udev rules files with appropriate renaming info in /run/udev/rules.d/70-netplan-<interface>.rules A file will be created for non-virtual interfaces with both a set-name and a driver or a mac address in the match stanza. (Renaming from name to name doesn't work.) This is at least a temporary fix to LP: #1770082 As far as testing goes, test successful set-name: generations, and a few cases where we expect no files to be generated. [1] systemd/systemd#9006 Signed-off-by: Daniel Axtens <dja@axtens.net>
Due to a systemd issue[1], using link files to rename interfaces doesn't work as expected. Link files will not rename an interface if it was already renamed, and interfaces are renamed in initrd, so set-name will often not work as expected when rebooting. However, rules files will cause a renaming, even if the interface has been renamed in initrd. So, while we sort out whether the systemd-udev behaviour is broken or not, we can simply generate udev rules files with appropriate renaming info in /run/udev/rules.d/70-netplan-<interface>.rules A file will be created for non-virtual interfaces with both a set-name and a driver or a mac address in the match stanza. (Renaming from name to name doesn't work.) This is at least a temporary fix to LP: #1770082 As far as testing goes, test successful set-name: generations, and a few cases where we expect no files to be generated. [1] systemd/systemd#9006 Signed-off-by: Daniel Axtens <dja@axtens.net>
I agree with @xnox. I see absolutely no reason to disregard the explicit user configuration. The current behavior is just confusing since all options from the link file are applied except Name. Also, I don't understand what problem was this code trying to fix, to begin with. |
Dear colleagues, I'm facing a different behavior with renaming interfaces: with net.ifnames=0 biosdevname=0 in GRUB command-line, changing the /etc/systemd/network's ".link" file (Match MACAddress=, Link Name=wan1) successfully renames interface upon boot (e.g. eth0 -> wan1):
but it seems that corresponding .network file (Match Name=wan1, Network ...) is ignored since no IP configuration appears on interface. Just manual "systemctl restart systemd-networkd" (no changes to existing config files) solves the issue with IP-configuration. And interesting is that if I match interface (in .network) not by name but by MAC (as in corresponding .link), no renaming happens, so after reboot it appears with IP configuration but as eth0. No other changes against standard Ubuntu's 18.04 configuration was applied. This happens on Ubuntu 18.04 w/ Systemd 237-3ubuntu10.3. |
@doka-ua I think your issue is already fixed by #8795 which is included in v239. |
…Policy= is specified This is for issue #9006
If "keep" policy is specified, and the interface has a name that is NET_NAME_USER or NET_NAME_RENAMED, we stop processing rules. "keep" should probably be specified either first or last depending on the preference. This partially reimplements 55b6530, in the sense that if the "keep" policy is not specified, and if the interface has a NamingPolicy, it will be renamed, even if it had a name previously. So this breaks backwards compatibility in this case, but that's more in line with what users expect. Closes systemd#9006.
If "keep" policy is specified, and the interface has a name that is NET_NAME_USER or NET_NAME_RENAMED, we stop processing rules. "keep" should probably be specified either first or last depending on the preference. This partially reimplements 55b6530, in the sense that if the "keep" policy is not specified, and if the interface has a NamingPolicy, it will be renamed, even if it had a name previously. So this breaks backwards compatibility in this case, but that's more in line with what users expect. Closes systemd#9006.
If "keep" policy is specified, and the interface has a name that is NET_NAME_USER or NET_NAME_RENAMED, we stop processing rules. "keep" should probably be specified either first or last depending on the preference. This partially reimplements 55b6530, in the sense that if the "keep" policy is not specified, and if the interface has a NamingPolicy, it will be renamed, even if it had a name previously. So this breaks backwards compatibility in this case, but that's more in line with what users expect. Closes systemd#9006.
A question about #11436 my question is about 80-net-setup-link.rules |
Please provide .link files you use, and also provide any relevant configs e.g. kernel command line option if you specify interface name in it. Also, if you invoke some commands to rename the interface, then also provide them. Without such information, we have no way to solve your issue. BTW, here is an upstream bug tracker. Do you really have any issues on interface renaming? Or just asking a question about the logic of interface renaming? If you just ask something, then here is not a good place to do that. Please use mailing list or read documents. |
@yuwata thank u,i‘m just asking a question about the logic of interface renaming.if use standard 80-net-setup-link.rules: Under #11436 circumstances,after apply /etc/udev/rules.d/70-persistent-net.rules: |
Hm? Please try to check attributes with |
sorry, Under #11436 circumstances,after apply /etc/udev/rules.d/70-persistent-net.rules: |
Please try to run
In my case, (of course without your custom rules)
|
what’s u udev version?my version is 241-7~deb10u8,and only include link file line,not include rules file line Under #11436 circumstances,through 70-persistent-net.rules interface can and have renamed to lan0 my question is about the logic of #11436 interface renaming, |
Logic is simple.
Gah,,, that's too old for here. Please use |
I changed the true MAC of 70-persistent-net.rules,because 80-net-setup-link.rules RENAME's conditions is NAME= is unset,and 70-persistent-net.rules rename NAME to lan0,so the final name is lan0.I use SYSTEMD_LOG_LEVEL=debug udevadm test /sys/class/net/lan0. output(I specially customize /etc/systemd/network/99-default.link just only remove keep from NamePolicy): If I remove NAME=="" from 80-net-setup-link.rules,the final name can renamed to enp0s3. so my question is Under #11436 circumstances,how through /usr/lib/systemd/network/99-default.link rename interface name from lan0 to ens3? After all customize 80-net-setup-link.rules through remove NAME=="" is too abnormal condition. |
Now, I am confused about what you expect. Which name Again, the logic is simple:
If you expect the interface is renamed to If you expect ===== This is the final message here I reply to you. |
systemd version the issue has been seen with
v237
Used distribution
Ubuntu 18.04
Expected behaviour you didn't see
I have a link file with the following contents:
I expect to see that when I boot, the interface is renamed to
myif3
.Unexpected behaviour you saw
The interface is not renamed, it stays as
ens3
.This usually breaks networking because other parts of the system assume the interface was renamed.
Steps to reproduce the problem
uvtool
, but it doesn't really matter.)/etc/netplan/50-cloud-init.yaml
and change theset-name:
yaml key tomyif3
. Then reboot.Further Information
I've done further analysis on this.
The interface will be renamed if the link file is in the initrd, but not if the file is absent from the initrd.
Firstly, systemd-udevd renames the interface when running out of initrd. If the link file is in the initrd, it will be read and applied at that time. If the link file is not in the initrd, systemd-udevd will rename the device anyway according to NamePolicy. This will usually be a PCI slot id - here
ens3
.Once we leave initrd and get to the normal root file system, the systemd-udevd daemon will be started. This will also consider the link file, but because the interface has been renamed, the
name_assign_type
will beNET_NAME_RENAMED
(4), soshould_rename
will return false and the device won't be renamed again. This is the cause of the unexpected behaviour.I think
should_rename
should allowNET_NAME_RENAMED
to be overridden; at least when there's a specific name given in the link file.The text was updated successfully, but these errors were encountered: