@@ -8,6 +8,24 @@ let
88
99 cfg = config.services.udev;
1010
11+ initrdUdevRules = pkgs.runCommand "initrd-udev-rules" {} ''
12+ mkdir -p $out/etc/udev/rules.d
13+ for f in 60-cdrom_id 60-persistent-storage 75-net-description 80-drivers 80-net-setup-link; do
14+ ln -s ${config.boot.initrd.systemd.package}/lib/udev/rules.d/$f.rules $out/etc/udev/rules.d
15+ done
16+ '';
17+
18+
19+ # networkd link files are used early by udev to set up interfaces early.
20+ # This must be done in stage 1 to avoid race conditions between udev and
21+ # network daemons.
22+ # TODO move this into the initrd-network module when it exists
23+ initrdLinkUnits = pkgs.runCommand "initrd-link-units" {} ''
24+ mkdir -p $out
25+ ln -s ${udev}/lib/systemd/network/*.link $out/
26+ ${lib.concatMapStringsSep "\n" (file: "ln -s ${file} $out/") (lib.mapAttrsToList (n: v: "${v.unit}/${n}") (lib.filterAttrs (n: _: hasSuffix ".link" n) config.systemd.network.units))}
27+ '';
28+
1129 extraUdevRules = pkgs.writeTextFile {
1230 name = "extra-udev-rules";
1331 text = cfg.extraRules;
@@ -350,7 +368,10 @@ in
350368 ];
351369 boot.initrd.systemd.storePaths = [
352370 "${config.boot.initrd.systemd.package}/lib/systemd/systemd-udevd"
353− "${config.boot.initrd.systemd.package}/lib/udev"
371+ "${config.boot.initrd.systemd.package}/lib/udev/ata_id"
372+ "${config.boot.initrd.systemd.package}/lib/udev/cdrom_id"
373+ "${config.boot.initrd.systemd.package}/lib/udev/scsi_id"
374+ "${config.boot.initrd.systemd.package}/lib/udev/rules.d"
354375 ] ++ map (x: "${x}/bin") config.boot.initrd.services.udev.binPackages;
355376
356377 # Generate the udev rules for the initrd
@@ -364,13 +385,17 @@ in
364385 systemd = config.boot.initrd.systemd.package;
365386 binPackages = config.boot.initrd.services.udev.binPackages ++ [ config.boot.initrd.systemd.contents."/bin".source ];
366387 };
388+ "/etc/systemd/network".source = initrdLinkUnits;
367389 };
368− # Insert custom rules
369− boot.initrd.services.udev.packages = mkIf (config.boot.initrd.services.udev.rules != "") (pkgs.writeTextFile {
370− name = "initrd-udev-rules";
371− destination = "/etc/udev/rules.d/99-local.rules";
372− text = config.boot.initrd.services.udev.rules;
373− });
390+ # Insert initrd rules
391+ boot.initrd.services.udev.packages = [
392+ initrdUdevRules
393+ (mkIf (config.boot.initrd.services.udev.rules != "") (pkgs.writeTextFile {
394+ name = "initrd-udev-rules";
395+ destination = "/etc/udev/rules.d/99-local.rules";
396+ text = config.boot.initrd.services.udev.rules;
397+ }))
398+ ];
374399
375400 environment.etc =
376401 {