aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/system/boot
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-03-24 10:15:32 +0100
committerKatharina Fey <kookie@spacekookie.de>2020-03-24 10:15:32 +0100
commit96f063dd321abc80ecaa156226cfb7cf9540315a (patch)
tree7a53ef61484fc7bfff6419b1fd635c67199f27d2 /nixpkgs/nixos/modules/system/boot
parentaf58f08d3d524e7b008b73a8497ea710915ffaf1 (diff)
parentd96bd3394b734487d1c3bfbac0e8f17465e03afe (diff)
Merge commit 'd96bd3394b734487d1c3bfbac0e8f17465e03afe'
Diffstat (limited to 'nixpkgs/nixos/modules/system/boot')
-rw-r--r--nixpkgs/nixos/modules/system/boot/initrd-network.nix64
-rw-r--r--nixpkgs/nixos/modules/system/boot/kernel.nix272
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix8
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/grub/install-grub.pl3
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/grub/memtest.nix57
-rw-r--r--nixpkgs/nixos/modules/system/boot/networkd.nix168
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1-init.sh19
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1.nix28
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd-lib.nix5
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd.nix28
10 files changed, 430 insertions, 222 deletions
diff --git a/nixpkgs/nixos/modules/system/boot/initrd-network.nix b/nixpkgs/nixos/modules/system/boot/initrd-network.nix
index cb8fc957a99..0ab6e626b34 100644
--- a/nixpkgs/nixos/modules/system/boot/initrd-network.nix
+++ b/nixpkgs/nixos/modules/system/boot/initrd-network.nix
@@ -6,7 +6,11 @@ let
cfg = config.boot.initrd.network;
- dhcpinterfaces = lib.attrNames (lib.filterAttrs (iface: v: v.useDHCP == true) (config.networking.interfaces or {}));
+ dhcpInterfaces = lib.attrNames (lib.filterAttrs (iface: v: v.useDHCP == true) (config.networking.interfaces or {}));
+ doDhcp = config.networking.useDHCP || dhcpInterfaces != [];
+ dhcpIfShellExpr = if config.networking.useDHCP
+ then "$(ls /sys/class/net/ | grep -v ^lo$)"
+ else lib.concatMapStringsSep " " lib.escapeShellArg dhcpInterfaces;
udhcpcScript = pkgs.writeScript "udhcp-script"
''
@@ -62,6 +66,16 @@ in
'';
};
+ boot.initrd.network.flushBeforeStage2 = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to clear the configuration of the interfaces that were set up in
+ the initrd right before stage 2 takes over. Stage 2 will do the regular network
+ configuration based on the NixOS networking options.
+ '';
+ };
+
boot.initrd.network.udhcpc.extraArgs = mkOption {
default = [];
type = types.listOf types.str;
@@ -89,49 +103,45 @@ in
boot.initrd.kernelModules = [ "af_packet" ];
boot.initrd.extraUtilsCommands = ''
- copy_bin_and_libs ${pkgs.mkinitcpio-nfs-utils}/bin/ipconfig
+ copy_bin_and_libs ${pkgs.klibc}/lib/klibc/bin.static/ipconfig
'';
boot.initrd.preLVMCommands = mkBefore (
# Search for interface definitions in command line.
''
+ ifaces=""
for o in $(cat /proc/cmdline); do
case $o in
ip=*)
- ipconfig $o && hasNetwork=1
+ ipconfig $o && ifaces="$ifaces $(echo $o | cut -d: -f6)"
;;
esac
done
''
# Otherwise, use DHCP.
- + optionalString (config.networking.useDHCP || dhcpinterfaces != []) ''
- if [ -z "$hasNetwork" ]; then
-
- # Bring up all interfaces.
- for iface in $(ls /sys/class/net/); do
- echo "bringing up network interface $iface..."
- ip link set "$iface" up
- done
+ + optionalString doDhcp ''
+ # Bring up all interfaces.
+ for iface in ${dhcpIfShellExpr}; do
+ echo "bringing up network interface $iface..."
+ ip link set "$iface" up && ifaces="$ifaces $iface"
+ done
- # Acquire DHCP leases.
- for iface in ${ if config.networking.useDHCP then
- "$(ls /sys/class/net/ | grep -v ^lo$)"
- else
- lib.concatMapStringsSep " " lib.escapeShellArg dhcpinterfaces
- }; do
- echo "acquiring IP address via DHCP on $iface..."
- udhcpc --quit --now -i $iface -O staticroutes --script ${udhcpcScript} ${udhcpcArgs} && hasNetwork=1
- done
- fi
+ # Acquire DHCP leases.
+ for iface in ${dhcpIfShellExpr}; do
+ echo "acquiring IP address via DHCP on $iface..."
+ udhcpc --quit --now -i $iface -O staticroutes --script ${udhcpcScript} ${udhcpcArgs}
+ done
''
- + ''
- if [ -n "$hasNetwork" ]; then
- echo "networking is up!"
- ${cfg.postCommands}
- fi
- '');
+ + cfg.postCommands);
+
+ boot.initrd.postMountCommands = mkIf cfg.flushBeforeStage2 ''
+ for iface in $ifaces; do
+ ip address flush "$iface"
+ ip link down "$iface"
+ done
+ '';
};
diff --git a/nixpkgs/nixos/modules/system/boot/kernel.nix b/nixpkgs/nixos/modules/system/boot/kernel.nix
index 6edb9082e75..43871f439f7 100644
--- a/nixpkgs/nixos/modules/system/boot/kernel.nix
+++ b/nixpkgs/nixos/modules/system/boot/kernel.nix
@@ -101,7 +101,12 @@ in
type = types.bool;
default = false;
description = ''
- Whether to activate VESA video mode on boot.
+ (Deprecated) This option, if set, activates the VESA 800x600 video
+ mode on boot and disables kernel modesetting. It is equivalent to
+ specifying <literal>[ "vga=0x317" "nomodeset" ]</literal> in the
+ <option>boot.kernelParams</option> option. This option is
+ deprecated as of 2020: Xorg now works better with modesetting, and
+ you might want a different VESA vga setting, anyway.
'';
};
@@ -187,139 +192,144 @@ in
###### implementation
- config = mkIf (!config.boot.isContainer) {
-
- system.build = { inherit kernel; };
-
- system.modulesTree = [ kernel ] ++ config.boot.extraModulePackages;
-
- # Implement consoleLogLevel both in early boot and using sysctl
- # (so you don't need to reboot to have changes take effect).
- boot.kernelParams =
- [ "loglevel=${toString config.boot.consoleLogLevel}" ] ++
- optionals config.boot.vesa [ "vga=0x317" "nomodeset" ];
-
- boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel;
-
- boot.kernelModules = [ "loop" "atkbd" ];
-
- boot.initrd.availableKernelModules =
- [ # Note: most of these (especially the SATA/PATA modules)
- # shouldn't be included by default since nixos-generate-config
- # detects them, but I'm keeping them for now for backwards
- # compatibility.
-
- # Some SATA/PATA stuff.
- "ahci"
- "sata_nv"
- "sata_via"
- "sata_sis"
- "sata_uli"
- "ata_piix"
- "pata_marvell"
-
- # Standard SCSI stuff.
- "sd_mod"
- "sr_mod"
-
- # SD cards and internal eMMC drives.
- "mmc_block"
-
- # Support USB keyboards, in case the boot fails and we only have
- # a USB keyboard, or for LUKS passphrase prompt.
- "uhci_hcd"
- "ehci_hcd"
- "ehci_pci"
- "ohci_hcd"
- "ohci_pci"
- "xhci_hcd"
- "xhci_pci"
- "usbhid"
- "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat"
- "hid_logitech_hidpp" "hid_logitech_dj"
-
- ] ++ optionals (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [
- # Misc. x86 keyboard stuff.
- "pcips2" "atkbd" "i8042"
-
- # x86 RTC needed by the stage 2 init script.
- "rtc_cmos"
- ];
-
- boot.initrd.kernelModules =
- [ # For LVM.
- "dm_mod"
- ];
-
- # The Linux kernel >= 2.6.27 provides firmware.
- hardware.firmware = [ kernel ];
-
- # Create /etc/modules-load.d/nixos.conf, which is read by
- # systemd-modules-load.service to load required kernel modules.
- environment.etc =
- { "modules-load.d/nixos.conf".source = kernelModulesConf;
- };
-
- systemd.services.systemd-modules-load =
- { wantedBy = [ "multi-user.target" ];
- restartTriggers = [ kernelModulesConf ];
- serviceConfig =
- { # Ignore failed module loads. Typically some of the
- # modules in ‘boot.kernelModules’ are "nice to have but
- # not required" (e.g. acpi-cpufreq), so we don't want to
- # barf on those.
- SuccessExitStatus = "0 1";
+ config = mkMerge
+ [ (mkIf config.boot.initrd.enable {
+ boot.initrd.availableKernelModules =
+ [ # Note: most of these (especially the SATA/PATA modules)
+ # shouldn't be included by default since nixos-generate-config
+ # detects them, but I'm keeping them for now for backwards
+ # compatibility.
+
+ # Some SATA/PATA stuff.
+ "ahci"
+ "sata_nv"
+ "sata_via"
+ "sata_sis"
+ "sata_uli"
+ "ata_piix"
+ "pata_marvell"
+
+ # Standard SCSI stuff.
+ "sd_mod"
+ "sr_mod"
+
+ # SD cards and internal eMMC drives.
+ "mmc_block"
+
+ # Support USB keyboards, in case the boot fails and we only have
+ # a USB keyboard, or for LUKS passphrase prompt.
+ "uhci_hcd"
+ "ehci_hcd"
+ "ehci_pci"
+ "ohci_hcd"
+ "ohci_pci"
+ "xhci_hcd"
+ "xhci_pci"
+ "usbhid"
+ "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat"
+ "hid_logitech_hidpp" "hid_logitech_dj"
+
+ ] ++ optionals (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [
+ # Misc. x86 keyboard stuff.
+ "pcips2" "atkbd" "i8042"
+
+ # x86 RTC needed by the stage 2 init script.
+ "rtc_cmos"
+ ];
+
+ boot.initrd.kernelModules =
+ [ # For LVM.
+ "dm_mod"
+ ];
+ })
+
+ (mkIf (!config.boot.isContainer) {
+ system.build = { inherit kernel; };
+
+ system.modulesTree = [ kernel ] ++ config.boot.extraModulePackages;
+
+ # Implement consoleLogLevel both in early boot and using sysctl
+ # (so you don't need to reboot to have changes take effect).
+ boot.kernelParams =
+ [ "loglevel=${toString config.boot.consoleLogLevel}" ] ++
+ optionals config.boot.vesa [ "vga=0x317" "nomodeset" ];
+
+ boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel;
+
+ boot.kernelModules = [ "loop" "atkbd" ];
+
+ # The Linux kernel >= 2.6.27 provides firmware.
+ hardware.firmware = [ kernel ];
+
+ # Create /etc/modules-load.d/nixos.conf, which is read by
+ # systemd-modules-load.service to load required kernel modules.
+ environment.etc =
+ { "modules-load.d/nixos.conf".source = kernelModulesConf;
};
- };
-
- lib.kernelConfig = {
- isYes = option: {
- assertion = config: config.isYes option;
- message = "CONFIG_${option} is not yes!";
- configLine = "CONFIG_${option}=y";
- };
-
- isNo = option: {
- assertion = config: config.isNo option;
- message = "CONFIG_${option} is not no!";
- configLine = "CONFIG_${option}=n";
- };
-
- isModule = option: {
- assertion = config: config.isModule option;
- message = "CONFIG_${option} is not built as a module!";
- configLine = "CONFIG_${option}=m";
- };
-
- ### Usually you will just want to use these two
- # True if yes or module
- isEnabled = option: {
- assertion = config: config.isEnabled option;
- message = "CONFIG_${option} is not enabled!";
- configLine = "CONFIG_${option}=y";
- };
-
- # True if no or omitted
- isDisabled = option: {
- assertion = config: config.isDisabled option;
- message = "CONFIG_${option} is not disabled!";
- configLine = "CONFIG_${option}=n";
- };
- };
- # The config options that all modules can depend upon
- system.requiredKernelConfig = with config.lib.kernelConfig; [
- # !!! Should this really be needed?
- (isYes "MODULES")
- (isYes "BINFMT_ELF")
- ] ++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT"));
+ systemd.services.systemd-modules-load =
+ { wantedBy = [ "multi-user.target" ];
+ restartTriggers = [ kernelModulesConf ];
+ serviceConfig =
+ { # Ignore failed module loads. Typically some of the
+ # modules in ‘boot.kernelModules’ are "nice to have but
+ # not required" (e.g. acpi-cpufreq), so we don't want to
+ # barf on those.
+ SuccessExitStatus = "0 1";
+ };
+ };
- # nixpkgs kernels are assumed to have all required features
- assertions = if config.boot.kernelPackages.kernel ? features then [] else
- let cfg = config.boot.kernelPackages.kernel.config; in map (attrs:
- { assertion = attrs.assertion cfg; inherit (attrs) message; }
- ) config.system.requiredKernelConfig;
+ lib.kernelConfig = {
+ isYes = option: {
+ assertion = config: config.isYes option;
+ message = "CONFIG_${option} is not yes!";
+ configLine = "CONFIG_${option}=y";
+ };
- };
+ isNo = option: {
+ assertion = config: config.isNo option;
+ message = "CONFIG_${option} is not no!";
+ configLine = "CONFIG_${option}=n";
+ };
+
+ isModule = option: {
+ assertion = config: config.isModule option;
+ message = "CONFIG_${option} is not built as a module!";
+ configLine = "CONFIG_${option}=m";
+ };
+
+ ### Usually you will just want to use these two
+ # True if yes or module
+ isEnabled = option: {
+ assertion = config: config.isEnabled option;
+ message = "CONFIG_${option} is not enabled!";
+ configLine = "CONFIG_${option}=y";
+ };
+
+ # True if no or omitted
+ isDisabled = option: {
+ assertion = config: config.isDisabled option;
+ message = "CONFIG_${option} is not disabled!";
+ configLine = "CONFIG_${option}=n";
+ };
+ };
+
+ # The config options that all modules can depend upon
+ system.requiredKernelConfig = with config.lib.kernelConfig;
+ [
+ # !!! Should this really be needed?
+ (isYes "MODULES")
+ (isYes "BINFMT_ELF")
+ ] ++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT"));
+
+ # nixpkgs kernels are assumed to have all required features
+ assertions = if config.boot.kernelPackages.kernel ? features then [] else
+ let cfg = config.boot.kernelPackages.kernel.config; in map (attrs:
+ { assertion = attrs.assertion cfg; inherit (attrs) message; }
+ ) config.system.requiredKernelConfig;
+
+ })
+
+ ];
}
diff --git a/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix b/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
index 9a4db84f7b7..b97ef88a7ca 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix
@@ -224,7 +224,11 @@ in
extraConfig = mkOption {
default = "";
- example = "serial; terminal_output.serial";
+ example = ''
+ serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
+ terminal_input --append serial
+ terminal_output --append serial
+ '';
type = types.lines;
description = ''
Additional GRUB commands inserted in the configuration file
@@ -630,7 +634,7 @@ in
boot.loader.grub.extraPrepareConfig =
concatStrings (mapAttrsToList (n: v: ''
- ${pkgs.coreutils}/bin/cp -pf "${v}" "/boot/${n}"
+ ${pkgs.coreutils}/bin/cp -pf "${v}" "@bootPath@/${n}"
'') config.boot.loader.grub.extraFiles);
assertions = [
diff --git a/nixpkgs/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixpkgs/nixos/modules/system/boot/loader/grub/install-grub.pl
index a09c5dc4761..ca0fb0248e0 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixpkgs/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -475,6 +475,9 @@ if ($grubVersion == 2) {
}
}
+# extraPrepareConfig could refer to @bootPath@, which we have to substitute
+$extraPrepareConfig =~ s/\@bootPath\@/$bootPath/g;
+
# Run extraPrepareConfig in sh
if ($extraPrepareConfig ne "") {
system((get("shell"), "-c", $extraPrepareConfig));
diff --git a/nixpkgs/nixos/modules/system/boot/loader/grub/memtest.nix b/nixpkgs/nixos/modules/system/boot/loader/grub/memtest.nix
index 94e5a14174b..71e50dd0577 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/grub/memtest.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/grub/memtest.nix
@@ -1,4 +1,4 @@
-# This module adds Memtest86+ to the GRUB boot menu.
+# This module adds Memtest86+/Memtest86 to the GRUB boot menu.
{ config, lib, pkgs, ... }:
@@ -6,6 +6,7 @@ with lib;
let
memtest86 = pkgs.memtest86plus;
+ efiSupport = config.boot.loader.grub.efiSupport;
cfg = config.boot.loader.grub.memtest86;
in
@@ -18,8 +19,11 @@ in
default = false;
type = types.bool;
description = ''
- Make Memtest86+, a memory testing program, available from the
- GRUB boot menu.
+ Make Memtest86+ (or MemTest86 if EFI support is enabled),
+ a memory testing program, available from the
+ GRUB boot menu. MemTest86 is an unfree program, so
+ this requires <literal>allowUnfree</literal> to be set to
+ <literal>true</literal>.
'';
};
@@ -75,19 +79,38 @@ in
};
};
- config = mkIf cfg.enable {
-
- boot.loader.grub.extraEntries =
- if config.boot.loader.grub.version == 2 then
- ''
- menuentry "Memtest86+" {
- linux16 @bootRoot@/memtest.bin ${toString cfg.params}
- }
- ''
- else
- throw "Memtest86+ is not supported with GRUB 1.";
-
- boot.loader.grub.extraFiles."memtest.bin" = "${memtest86}/memtest.bin";
+ config = mkMerge [
+ (mkIf (cfg.enable && efiSupport) {
+ assertions = [
+ {
+ assertion = cfg.params == [];
+ message = "Parameters are not available for MemTest86";
+ }
+ ];
+
+ boot.loader.grub.extraFiles = {
+ "memtest86.efi" = "${pkgs.memtest86-efi}/BOOTX64.efi";
+ };
- };
+ boot.loader.grub.extraEntries = ''
+ menuentry "Memtest86" {
+ chainloader /memtest86.efi
+ }
+ '';
+ })
+
+ (mkIf (cfg.enable && !efiSupport) {
+ boot.loader.grub.extraEntries =
+ if config.boot.loader.grub.version == 2 then
+ ''
+ menuentry "Memtest86+" {
+ linux16 @bootRoot@/memtest.bin ${toString cfg.params}
+ }
+ ''
+ else
+ throw "Memtest86+ is not supported with GRUB 1.";
+
+ boot.loader.grub.extraFiles."memtest.bin" = "${memtest86}/memtest.bin";
+ })
+ ];
}
diff --git a/nixpkgs/nixos/modules/system/boot/networkd.nix b/nixpkgs/nixos/modules/system/boot/networkd.nix
index 56a9d6b1138..3078f84f6e9 100644
--- a/nixpkgs/nixos/modules/system/boot/networkd.nix
+++ b/nixpkgs/nixos/modules/system/boot/networkd.nix
@@ -55,6 +55,11 @@ let
(assertMacAddress "MACAddress")
];
+ checkVRF = checkUnitConfig "VRF" [
+ (assertOnlyFields [ "Table" ])
+ (assertMinimum "Table" 0)
+ ];
+
# NOTE The PrivateKey directive is missing on purpose here, please
# do not add it to this list. The nix store is world-readable let's
# refrain ourselves from providing a footgun.
@@ -62,7 +67,12 @@ let
(assertOnlyFields [
"PrivateKeyFile" "ListenPort" "FwMark"
])
- (assertRange "FwMark" 1 4294967295)
+ # The following check won't work on nix <= 2.2
+ # see https://github.com/NixOS/nix/pull/2378
+ #
+ # Add this again when we'll have drop the
+ # nix < 2.2 support.
+ # (assertRange "FwMark" 1 4294967295)
];
# NOTE The PresharedKey directive is missing on purpose here, please
@@ -176,7 +186,12 @@ let
(assertOnlyFields [
"InterfaceId" "Independent"
])
- (assertRange "InterfaceId" 1 4294967295)
+ # The following check won't work on nix <= 2.2
+ # see https://github.com/NixOS/nix/pull/2378
+ #
+ # Add this again when we'll have drop the
+ # nix < 2.2 support.
+ # (assertRange "InterfaceId" 1 4294967295)
(assertValueOneOf "Independent" boolValues)
];
@@ -230,6 +245,26 @@ let
(assertValueOneOf "AutoJoin" boolValues)
];
+ checkRoutingPolicyRule = checkUnitConfig "RoutingPolicyRule" [
+ (assertOnlyFields [
+ "TypeOfService" "From" "To" "FirewallMark" "Table" "Priority"
+ "IncomingInterface" "OutgoingInterface" "SourcePort" "DestinationPort"
+ "IPProtocol" "InvertRule" "Family"
+ ])
+ (assertRange "TypeOfService" 0 255)
+ # The following check won't work on nix <= 2.2
+ # see https://github.com/NixOS/nix/pull/2378
+ #
+ # Add this again when we'll have drop the
+ # nix < 2.2 support.
+ # (assertRange "FirewallMark" 1 4294967295)
+ (assertInt "Priority")
+ (assertPort "SourcePort")
+ (assertPort "DestinationPort")
+ (assertValueOneOf "InvertRule" boolValues)
+ (assertValueOneOf "Family" ["ipv4" "ipv6" "both"])
+ ];
+
checkRoute = checkUnitConfig "Route" [
(assertOnlyFields [
"Gateway" "GatewayOnLink" "Destination" "Source" "Metric"
@@ -320,6 +355,14 @@ let
};
linkOptions = commonNetworkOptions // {
+ # overwrite enable option from above
+ enable = mkOption {
+ default = true;
+ type = types.bool;
+ description = ''
+ Whether to enable this .link unit. It's handled by udev no matter if <command>systemd-networkd</command> is enabled or not
+ '';
+ };
linkConfig = mkOption {
default = {};
@@ -349,6 +392,21 @@ let
'';
};
+ vrfConfig = mkOption {
+ default = {};
+ example = { Table = 2342; };
+ type = types.addCheck (types.attrsOf unitOption) checkVRF;
+ description = ''
+ Each attribute in this set specifies an option in the
+ <literal>[VRF]</literal> section of the unit. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> for details.
+ A detailed explanation about how VRFs work can be found in the
+ <link xlink:href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">kernel
+ docs</link>.
+ '';
+ };
+
wireguardConfig = mkOption {
default = {};
example = {
@@ -515,6 +573,22 @@ let
};
};
+ routingPolicyRulesOptions = {
+ options = {
+ routingPolicyRuleConfig = mkOption {
+ default = { };
+ example = { routingPolicyRuleConfig = { Table = 10; IncomingInterface = "eth1"; Family = "both"; } ;};
+ type = types.addCheck (types.attrsOf unitOption) checkRoutingPolicyRule;
+ description = ''
+ Each attribute in this set specifies an option in the
+ <literal>[RoutingPolicyRule]</literal> section of the unit. See
+ <citerefentry><refentrytitle>systemd.network</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> for details.
+ '';
+ };
+ };
+ };
+
routeOptions = {
options = {
routeConfig = mkOption {
@@ -752,6 +826,16 @@ let
'';
};
+ routingPolicyRules = mkOption {
+ default = [ ];
+ type = with types; listOf (submodule routingPolicyRulesOptions);
+ description = ''
+ A list of routing policy rules sections to be added to the unit. See
+ <citerefentry><refentrytitle>systemd.network</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> for details.
+ '';
+ };
+
routes = mkOption {
default = [ ];
type = with types; listOf (submodule routeOptions);
@@ -845,6 +929,11 @@ let
${attrsToSection def.xfrmConfig}
''}
+ ${optionalString (def.vrfConfig != { }) ''
+ [VRF]
+ ${attrsToSection def.vrfConfig}
+
+ ''}
${optionalString (def.wireguardConfig != { }) ''
[WireGuard]
${attrsToSection def.wireguardConfig}
@@ -904,6 +993,11 @@ let
${attrsToSection x.routeConfig}
'')}
+ ${flip concatMapStrings def.routingPolicyRules (x: ''
+ [RoutingPolicyRule]
+ ${attrsToSection x.routingPolicyRuleConfig}
+
+ '')}
${def.extraConfig}
'';
};
@@ -947,9 +1041,10 @@ in
systemd.network.units = mkOption {
description = "Definition of networkd units.";
default = {};
+ internal = true;
type = with types; attrsOf (submodule (
{ name, config, ... }:
- { options = concreteUnitOptions;
+ { options = mapAttrs (_: x: x // { internal = true; }) concreteUnitOptions;
config = {
unit = mkDefault (makeUnit name config);
};
@@ -958,44 +1053,49 @@ in
};
- config = mkIf config.systemd.network.enable {
+ config = mkMerge [
+ # .link units are honored by udev, no matter if systemd-networkd is enabled or not.
+ {
+ systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links;
+ environment.etc = unitFiles;
+ }
- users.users.systemd-network.group = "systemd-network";
+ (mkIf config.systemd.network.enable {
- systemd.additionalUpstreamSystemUnits = [
- "systemd-networkd.service" "systemd-networkd-wait-online.service"
- ];
+ users.users.systemd-network.group = "systemd-network";
- systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links
- // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs
- // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks;
+ systemd.additionalUpstreamSystemUnits = [
+ "systemd-networkd.service" "systemd-networkd-wait-online.service"
+ ];
- environment.etc = unitFiles;
+ systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs
+ // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks;
- systemd.services.systemd-networkd = {
- wantedBy = [ "multi-user.target" ];
- restartTriggers = attrNames unitFiles;
- # prevent race condition with interface renaming (#39069)
- requires = [ "systemd-udev-settle.service" ];
- after = [ "systemd-udev-settle.service" ];
- };
+ systemd.services.systemd-networkd = {
+ wantedBy = [ "multi-user.target" ];
+ restartTriggers = attrNames unitFiles;
+ # prevent race condition with interface renaming (#39069)
+ requires = [ "systemd-udev-settle.service" ];
+ after = [ "systemd-udev-settle.service" ];
+ };
- systemd.services.systemd-networkd-wait-online = {
- wantedBy = [ "network-online.target" ];
- };
+ systemd.services.systemd-networkd-wait-online = {
+ wantedBy = [ "network-online.target" ];
+ };
- systemd.services."systemd-network-wait-online@" = {
- description = "Wait for Network Interface %I to be Configured";
- conflicts = [ "shutdown.target" ];
- requisite = [ "systemd-networkd.service" ];
- after = [ "systemd-networkd.service" ];
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = true;
- ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
+ systemd.services."systemd-network-wait-online@" = {
+ description = "Wait for Network Interface %I to be Configured";
+ conflicts = [ "shutdown.target" ];
+ requisite = [ "systemd-networkd.service" ];
+ after = [ "systemd-networkd.service" ];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
+ };
};
- };
- services.resolved.enable = mkDefault true;
- };
+ services.resolved.enable = mkDefault true;
+ })
+ ];
}
diff --git a/nixpkgs/nixos/modules/system/boot/stage-1-init.sh b/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
index f520bf54ad1..607aec87f01 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
@@ -210,6 +210,8 @@ done
# Create device nodes in /dev.
@preDeviceCommands@
echo "running udev..."
+mkdir -p /etc/systemd
+ln -sfn @linkUnits@ /etc/systemd/network
mkdir -p /etc/udev
ln -sfn @udevRules@ /etc/udev/rules.d
mkdir -p /dev/.mdadm
@@ -266,7 +268,7 @@ checkFS() {
return 0
fi
- # Device might be already mounted manually
+ # Device might be already mounted manually
# e.g. NBD-device or the host filesystem of the file which contains encrypted root fs
if mount | grep -q "^$device on "; then
echo "skip checking already mounted $device"
@@ -334,8 +336,10 @@ mountFS() {
# Filter out x- options, which busybox doesn't do yet.
local optionsFiltered="$(IFS=,; for i in $options; do if [ "${i:0:2}" != "x-" ]; then echo -n $i,; fi; done)"
+ # Prefix (lower|upper|work)dir with /mnt-root (overlayfs)
+ local optionsPrefixed="$( echo "$optionsFiltered" | sed -E 's#\<(lowerdir|upperdir|workdir)=#\1=/mnt-root#g' )"
- echo "$device /mnt-root$mountPoint $fsType $optionsFiltered" >> /etc/fstab
+ echo "$device /mnt-root$mountPoint $fsType $optionsPrefixed" >> /etc/fstab
checkFS "$device" "$fsType"
@@ -349,15 +353,16 @@ mountFS() {
elif [ "$fsType" = f2fs ]; then
echo "resizing $device..."
fsck.f2fs -fp "$device"
- resize.f2fs "$device"
+ resize.f2fs "$device"
fi
;;
esac
- # Create backing directories for unionfs-fuse.
- if [ "$fsType" = unionfs-fuse ]; then
- for i in $(IFS=:; echo ${options##*,dirs=}); do
- mkdir -m 0700 -p /mnt-root"${i%=*}"
+ # Create backing directories for overlayfs
+ if [ "$fsType" = overlay ]; then
+ for i in upper work; do
+ dir="$( echo "$optionsPrefixed" | grep -o "${i}dir=[^,]*" )"
+ mkdir -m 0700 -p "${dir##*=}"
done
fi
diff --git a/nixpkgs/nixos/modules/system/boot/stage-1.nix b/nixpkgs/nixos/modules/system/boot/stage-1.nix
index 4c2d130d5a5..93cd801ef80 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1.nix
+++ b/nixpkgs/nixos/modules/system/boot/stage-1.nix
@@ -120,6 +120,7 @@ let
# Copy udev.
copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd
+ copy_bin_and_libs ${udev}/lib/systemd/systemd-sysctl
copy_bin_and_libs ${udev}/bin/udevadm
for BIN in ${udev}/lib/udev/*_id; do
copy_bin_and_libs $BIN
@@ -198,6 +199,14 @@ let
''; # */
+ linkUnits = pkgs.runCommand "link-units" {
+ allowedReferences = [ extraUtils ];
+ preferLocalBuild = true;
+ } ''
+ mkdir -p $out
+ cp -v ${udev}/lib/systemd/network/*.link $out/
+ '';
+
udevRules = pkgs.runCommand "udev-rules" {
allowedReferences = [ extraUtils ];
preferLocalBuild = true;
@@ -208,7 +217,9 @@ let
cp -v ${udev}/lib/udev/rules.d/60-cdrom_id.rules $out/
cp -v ${udev}/lib/udev/rules.d/60-persistent-storage.rules $out/
+ cp -v ${udev}/lib/udev/rules.d/75-net-description.rules $out/
cp -v ${udev}/lib/udev/rules.d/80-drivers.rules $out/
+ cp -v ${udev}/lib/udev/rules.d/80-net-setup-link.rules $out/
cp -v ${pkgs.lvm2}/lib/udev/rules.d/*.rules $out/
${config.boot.initrd.extraUdevRulesCommands}
@@ -222,7 +233,7 @@ let
--replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \
--replace ${pkgs.mdadm}/sbin ${extraUtils}/sbin \
--replace ${pkgs.bash}/bin/sh ${extraUtils}/bin/sh \
- --replace ${udev}/bin/udevadm ${extraUtils}/bin/udevadm
+ --replace ${udev} ${extraUtils}
done
# Work around a bug in QEMU, which doesn't implement the "READ
@@ -257,7 +268,7 @@ let
${pkgs.buildPackages.busybox}/bin/ash -n $target
'';
- inherit udevRules extraUtils modulesClosure;
+ inherit linkUnits udevRules extraUtils modulesClosure;
inherit (config.boot) resumeDevice;
@@ -379,6 +390,17 @@ in
'';
};
+ boot.initrd.enable = mkOption {
+ type = types.bool;
+ default = !config.boot.isContainer;
+ defaultText = "!config.boot.isContainer";
+ description = ''
+ Whether to enable the NixOS initial RAM disk (initrd). This may be
+ needed to perform some initialisation tasks (like mounting
+ network/encrypted file systems) before continuing the boot process.
+ '';
+ };
+
boot.initrd.prepend = mkOption {
default = [ ];
type = types.listOf types.str;
@@ -544,7 +566,7 @@ in
};
- config = mkIf (!config.boot.isContainer) {
+ config = mkIf config.boot.initrd.enable {
assertions = [
{ assertion = any (fs: fs.mountPoint == "/") fileSystems;
message = "The ‘fileSystems’ option does not specify your root file system.";
diff --git a/nixpkgs/nixos/modules/system/boot/systemd-lib.nix b/nixpkgs/nixos/modules/system/boot/systemd-lib.nix
index fd1a5b9f62c..a3360291586 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd-lib.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd-lib.nix
@@ -59,6 +59,11 @@ in rec {
optional (attr ? ${name} && ! isMacAddress attr.${name})
"Systemd ${group} field `${name}' must be a valid mac address.";
+ isPort = i: i >= 0 && i <= 65535;
+
+ assertPort = name: group: attr:
+ optional (attr ? ${name} && ! isPort attr.${name})
+ "Error on the systemd ${group} field `${name}': ${attr.name} is not a valid port number.";
assertValueOneOf = name: values: group: attr:
optional (attr ? ${name} && !elem attr.${name} values)
diff --git a/nixpkgs/nixos/modules/system/boot/systemd.nix b/nixpkgs/nixos/modules/system/boot/systemd.nix
index 941df5797c6..cdc9d237939 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd.nix
@@ -697,6 +697,16 @@ in
'';
};
+ systemd.sleep.extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ example = "HibernateDelaySec=1h";
+ description = ''
+ Extra config options for systemd sleep state logic.
+ See sleep.conf.d(5) man page for available options.
+ '';
+ };
+
systemd.user.extraConfig = mkOption {
default = "";
type = types.lines;
@@ -776,6 +786,18 @@ in
'';
};
+ systemd.suppressedSystemUnits = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ example = [ "systemd-backlight@.service" ];
+ description = ''
+ A list of units to suppress when generating system systemd configuration directory. This has
+ priority over upstream units, <option>systemd.units</option>, and
+ <option>systemd.additionalUpstreamSystemUnits</option>. The main purpose of this is to
+ suppress a upstream systemd unit with any modifications made to it by other NixOS modules.
+ '';
+ };
+
};
@@ -808,8 +830,11 @@ in
done
${concatStrings (mapAttrsToList (exec: target: "ln -s ${target} $out/${exec};\n") links)}
'';
+
+ enabledUpstreamSystemUnits = filter (n: ! elem n cfg.suppressedSystemUnits) upstreamSystemUnits;
+ enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units;
in ({
- "systemd/system".source = generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants;
+ "systemd/system".source = generateUnits "system" enabledUnits enabledUpstreamSystemUnits upstreamSystemWants;
"systemd/user".source = generateUnits "user" cfg.user.units upstreamUserUnits [];
@@ -863,6 +888,7 @@ in
"systemd/sleep.conf".text = ''
[Sleep]
+ ${config.systemd.sleep.extraConfig}
'';
# install provided sysctl snippets