Merge pull request #107382 from rnhmjoj/no-udev-settle

nixos/{networkd,dhcpcd}: remove udev-settle hack

authored by

Michele Guerini Rocco and committed by
GitHub
19d715c5 008a2b29

+136 -8
+1
nixos/doc/manual/configuration/networking.xml
··· 15 15 <xi:include href="firewall.xml" /> 16 16 <xi:include href="wireless.xml" /> 17 17 <xi:include href="ad-hoc-network-config.xml" /> 18 + <xi:include href="renaming-interfaces.xml" /> 18 19 <!-- TODO: OpenVPN, NAT --> 19 20 </chapter>
+67
nixos/doc/manual/configuration/renaming-interfaces.xml
··· 1 + <section xmlns="http://docbook.org/ns/docbook" 2 + xmlns:xlink="http://www.w3.org/1999/xlink" 3 + xmlns:xi="http://www.w3.org/2001/XInclude" 4 + version="5.0" 5 + xml:id="sec-rename-ifs"> 6 + <title>Renaming network interfaces</title> 7 + 8 + <para> 9 + NixOS uses the udev 10 + <link xlink:href="https://systemd.io/PREDICTABLE_INTERFACE_NAMES/">predictable naming scheme</link> 11 + to assign names to network interfaces. This means that by default 12 + cards are not given the traditional names like 13 + <literal>eth0</literal> or <literal>eth1</literal>, whose order can 14 + change unpredictably across reboots. Instead, relying on physical 15 + locations and firmware information, the scheme produces names like 16 + <literal>ens1</literal>, <literal>enp2s0</literal>, etc. 17 + </para> 18 + 19 + <para> 20 + These names are predictable but less memorable and not necessarily 21 + stable: for example installing new hardware or changing firmware 22 + settings can result in a 23 + <link xlink:href="https://github.com/systemd/systemd/issues/3715#issue-165347602">name change</link>. 24 + If this is undesirable, for example if you have a single ethernet 25 + card, you can revert to the traditional scheme by setting 26 + <xref linkend="opt-networking.usePredictableInterfaceNames"/> to 27 + <literal>false</literal>. 28 + </para> 29 + 30 + <section xml:id="sec-custom-ifnames"> 31 + <title>Assigning custom names</title> 32 + <para> 33 + In case there are multiple interfaces of the same type, it’s better to 34 + assign custom names based on the device hardware address. For 35 + example, we assign the name <literal>wan</literal> to the interface 36 + with MAC address <literal>52:54:00:12:01:01</literal> using a 37 + netword link unit: 38 + </para> 39 + <programlisting> 40 + <link linkend="opt-systemd.network.links">systemd.network.links."10-wan"</link> = { 41 + matchConfig.MACAddress = "52:54:00:12:01:01"; 42 + linkConfig.Name = "wan"; 43 + }; 44 + </programlisting> 45 + <para> 46 + Note that links are directly read by udev, <emphasis>not networkd</emphasis>, 47 + and will work even if networkd is disabled. 48 + </para> 49 + <para> 50 + Alternatively, we can use a plain old udev rule: 51 + </para> 52 + <programlisting> 53 + <link linkend="opt-services.udev.initrdRules">services.udev.initrdRules</link> = '' 54 + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", \ 55 + ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="wan" 56 + ''; 57 + </programlisting> 58 + 59 + <warning><para> 60 + The rule must be installed in the initrd using 61 + <literal>services.udev.initrdRules</literal>, not the usual 62 + <literal>services.udev.extraRules</literal> option. This is to avoid race 63 + conditions with other programs controlling the interface. 64 + </para></warning> 65 + </section> 66 + 67 + </section>
+10
nixos/doc/manual/release-notes/rl-2105.xml
··· 91 91 </para> 92 92 93 93 <itemizedlist> 94 + <listitem> 95 + <para> 96 + If you are using <option>services.udev.extraRules</option> to assign 97 + custom names to network interfaces, this may stop working due to a change 98 + in the initialisation of dhcpcd and systemd networkd. To avoid this, either 99 + move them to <option>services.udev.initrdRules</option> or see the new 100 + <link linkend="sec-custom-ifnames">Assigning custom names</link> section 101 + of the NixOS manual for an example using networkd links. 102 + </para> 103 + </listitem> 94 104 <listitem> 95 105 <para> 96 106 The <literal>systemConfig</literal> kernel parameter is no longer added to boot loader entries. It has been unused since September 2010, but if do have a system generation from that era, you will now be unable to boot into them.
+22 -1
nixos/modules/services/hardware/udev.nix
··· 202 202 ''; 203 203 }; 204 204 205 - extraRules = mkOption { 205 + initrdRules = mkOption { 206 206 default = ""; 207 207 example = '' 208 208 SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:1D:60:B9:6D:4F", KERNEL=="eth*", NAME="my_fast_network_card" 209 + ''; 210 + type = types.lines; 211 + description = '' 212 + <command>udev</command> rules to include in the initrd 213 + <emphasis>only</emphasis>. They'll be written into file 214 + <filename>99-local.rules</filename>. Thus they are read and applied 215 + after the essential initrd rules. 216 + ''; 217 + }; 218 + 219 + extraRules = mkOption { 220 + default = ""; 221 + example = '' 222 + ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="0825", ENV{PULSE_IGNORE}="1" 209 223 ''; 210 224 type = types.lines; 211 225 description = '' ··· 283 297 services.udev.path = [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.util-linux udev ]; 284 298 285 299 boot.kernelParams = mkIf (!config.networking.usePredictableInterfaceNames) [ "net.ifnames=0" ]; 300 + 301 + boot.initrd.extraUdevRulesCommands = optionalString (cfg.initrdRules != "") 302 + '' 303 + cat <<'EOF' > $out/99-local.rules 304 + ${cfg.initrdRules} 305 + EOF 306 + ''; 286 307 287 308 environment.etc = 288 309 {
+1 -2
nixos/modules/services/networking/dhcpcd.nix
··· 191 191 { description = "DHCP Client"; 192 192 193 193 wantedBy = [ "multi-user.target" ] ++ optional (!hasDefaultGatewaySet) "network-online.target"; 194 - wants = [ "network.target" "systemd-udev-settle.service" ]; 194 + wants = [ "network.target" ]; 195 195 before = [ "network-online.target" ]; 196 - after = [ "systemd-udev-settle.service" ]; 197 196 198 197 restartTriggers = [ exitHook ]; 199 198
-3
nixos/modules/system/boot/networkd.nix
··· 1553 1553 wantedBy = [ "multi-user.target" ]; 1554 1554 aliases = [ "dbus-org.freedesktop.network1.service" ]; 1555 1555 restartTriggers = map (x: x.source) (attrValues unitFiles); 1556 - # prevent race condition with interface renaming (#39069) 1557 - requires = [ "systemd-udev-settle.service" ]; 1558 - after = [ "systemd-udev-settle.service" ]; 1559 1556 }; 1560 1557 1561 1558 systemd.services.systemd-networkd-wait-online = {
+11 -2
nixos/modules/system/boot/stage-1.nix
··· 205 205 ''; # */ 206 206 207 207 208 + # Networkd link files are used early by udev to set up interfaces early. 209 + # This must be done in stage 1 to avoid race conditions between udev and 210 + # network daemons. 208 211 linkUnits = pkgs.runCommand "link-units" { 209 212 allowedReferences = [ extraUtils ]; 210 213 preferLocalBuild = true; 211 - } '' 214 + } ('' 212 215 mkdir -p $out 213 216 cp -v ${udev}/lib/systemd/network/*.link $out/ 214 - ''; 217 + '' + ( 218 + let 219 + links = filterAttrs (n: v: hasSuffix ".link" n) config.systemd.network.units; 220 + files = mapAttrsToList (n: v: "${v.unit}/${n}") links; 221 + in 222 + concatMapStringsSep "\n" (file: "cp -v ${file} $out/") files 223 + )); 215 224 216 225 udevRules = pkgs.runCommand "udev-rules" { 217 226 allowedReferences = [ extraUtils ];
+24
nixos/tests/networking.nix
··· 672 672 ), "The IPv6 routing table has not been properly cleaned:\n{}".format(ipv6Residue) 673 673 ''; 674 674 }; 675 + rename = { 676 + name = "RenameInterface"; 677 + machine = { pkgs, ... }: { 678 + virtualisation.vlans = [ 1 ]; 679 + networking = { 680 + useNetworkd = networkd; 681 + useDHCP = false; 682 + }; 683 + } // 684 + (if networkd 685 + then { systemd.network.links."10-custom_name" = { 686 + matchConfig.MACAddress = "52:54:00:12:01:01"; 687 + linkConfig.Name = "custom_name"; 688 + }; 689 + } 690 + else { services.udev.initrdRules = '' 691 + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="custom_name" 692 + ''; 693 + }); 694 + testScript = '' 695 + machine.succeed("udevadm settle") 696 + print(machine.succeed("ip link show dev custom_name")) 697 + ''; 698 + }; 675 699 # even with disabled networkd, systemd.network.links should work 676 700 # (as it's handled by udev, not networkd) 677 701 link = {