From f1731f2e28eae6164a31868c024ae9c1b9d4fdb9 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Fri, 19 Jan 2024 05:39:01 -0500 Subject: [PATCH 1/2] nixos: Support systemd-gpt-auto-root --- nixos/modules/system/boot/stage-1.nix | 2 +- nixos/modules/system/boot/systemd/initrd.nix | 29 ++++++++++++-- nixos/tests/installer-systemd-stage-1.nix | 1 + nixos/tests/installer.nix | 42 +++++++++++++++++++- pkgs/os-specific/linux/systemd/default.nix | 2 +- 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 90a74c0ac578..6462e4fd51fc 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -688,7 +688,7 @@ in config = mkIf config.boot.initrd.enable { assertions = [ - { assertion = any (fs: fs.mountPoint == "/") fileSystems; + { assertion = !config.boot.initrd.systemd.enable -> any (fs: fs.mountPoint == "/") fileSystems; message = "The ‘fileSystems’ option does not specify your root file system."; } { assertion = let inherit (config.boot) resumeDevice; in diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index f83837fbc6d4..7abba80fbefb 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -212,6 +212,19 @@ in { default = []; }; + root = lib.mkOption { + type = lib.types.enum [ "fstab" "gpt-auto" ]; + default = "fstab"; + example = "gpt-auto"; + description = '' + Controls how systemd will interpret the root FS in initrd. See + {manpage}`kernel-command-line(7)`. NixOS currently does not + allow specifying the root file system itself this + way. Instead, the `fstab` value is used in order to interpret + the root file system specified with the `fileSystems` option. + ''; + }; + emergencyAccess = mkOption { type = with types; oneOf [ bool (nullOr (passwdEntry str)) ]; description = lib.mdDoc '' @@ -342,7 +355,12 @@ in { }; config = mkIf (config.boot.initrd.enable && cfg.enable) { - assertions = map (name: { + assertions = [ + { + assertion = cfg.root == "fstab" -> any (fs: fs.mountPoint == "/") (builtins.attrValues config.fileSystems); + message = "The ‘fileSystems’ option does not specify your root file system."; + } + ] ++ map (name: { assertion = lib.attrByPath name (throw "impossible") config.boot.initrd == ""; message = '' systemd stage 1 does not support 'boot.initrd.${lib.concatStringsSep "." name}'. Please @@ -371,7 +389,12 @@ in { "autofs" # systemd-cryptenroll ] ++ lib.optional cfg.enableTpm2 "tpm-tis" - ++ lib.optional (cfg.enableTpm2 && !(pkgs.stdenv.hostPlatform.isRiscV64 || pkgs.stdenv.hostPlatform.isArmv7)) "tpm-crb"; + ++ lib.optional (cfg.enableTpm2 && !(pkgs.stdenv.hostPlatform.isRiscV64 || pkgs.stdenv.hostPlatform.isArmv7)) "tpm-crb" + ++ lib.optional cfg.package.withEfi "efivarfs"; + + boot.kernelParams = [ + "root=${config.boot.initrd.systemd.root}" + ] ++ lib.optional (config.boot.resumeDevice != "") "resume=${config.boot.resumeDevice}"; boot.initrd.systemd = { initrdBin = [pkgs.bash pkgs.coreutils cfg.package.kmod cfg.package]; @@ -554,7 +577,5 @@ in { serviceConfig.Type = "oneshot"; }; }; - - boot.kernelParams = lib.mkIf (config.boot.resumeDevice != "") [ "resume=${config.boot.resumeDevice}" ]; }; } diff --git a/nixos/tests/installer-systemd-stage-1.nix b/nixos/tests/installer-systemd-stage-1.nix index 662017935412..d10256d91d7f 100644 --- a/nixos/tests/installer-systemd-stage-1.nix +++ b/nixos/tests/installer-systemd-stage-1.nix @@ -37,6 +37,7 @@ clevisLuksFallback clevisZfs clevisZfsFallback + gptAutoRoot ; } diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 97bb7f8def59..1de886d6a0d1 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -82,6 +82,7 @@ let testScriptFun = { bootLoader, createPartitions, grubDevice, grubUseEfi, grubIdentifier , postInstallCommands, preBootCommands, postBootCommands, extraConfig , testSpecialisationConfig, testFlakeSwitch, clevisTest, clevisFallbackTest + , disableFileSystems }: let qemu-common = import ../lib/qemu-common.nix { inherit (pkgs) lib pkgs; }; @@ -163,7 +164,7 @@ let ${createPartitions} with subtest("Create the NixOS configuration"): - machine.succeed("nixos-generate-config --root /mnt") + machine.succeed("nixos-generate-config ${optionalString disableFileSystems "--no-filesystems"} --root /mnt") machine.succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2") machine.copy_from_host( "${ makeConfig { @@ -433,6 +434,7 @@ let , testFlakeSwitch ? false , clevisTest ? false , clevisFallbackTest ? false + , disableFileSystems ? false }: makeTest { inherit enableOCR; @@ -541,7 +543,8 @@ let testScript = testScriptFun { inherit bootLoader createPartitions postInstallCommands preBootCommands postBootCommands grubDevice grubIdentifier grubUseEfi extraConfig - testSpecialisationConfig testFlakeSwitch clevisTest clevisFallbackTest; + testSpecialisationConfig testFlakeSwitch clevisTest clevisFallbackTest + disableFileSystems; }; }; @@ -1414,4 +1417,39 @@ in { }; }; }; + + gptAutoRoot = let + rootPartType = { + ia32 = "44479540-F297-41B2-9AF7-D131D5F0458A"; + x64 = "4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709"; + arm = "69DAD710-2CE4-4E3C-B16C-21A1D49ABED3"; + aa64 = "B921B045-1DF0-41C3-AF44-4C6F280D3FAE"; + }.${pkgs.stdenv.hostPlatform.efiArch}; + in makeInstallerTest "gptAutoRoot" { + disableFileSystems = true; + createPartitions = '' + machine.succeed( + "sgdisk --zap-all /dev/vda", + "sgdisk --new=1:0:+100M --typecode=0:ef00 /dev/vda", # /boot + "sgdisk --new=2:0:+1G --typecode=0:8200 /dev/vda", # swap + "sgdisk --new=3:0:+5G --typecode=0:${rootPartType} /dev/vda", # / + "udevadm settle", + + "mkfs.vfat /dev/vda1", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.ext4 -L root /dev/vda3", + "udevadm settle", + + "mount /dev/vda3 /mnt", + "mkdir -p /mnt/boot", + "mount /dev/vda1 /mnt/boot" + ) + ''; + bootLoader = "systemd-boot"; + extraConfig = '' + boot.initrd.systemd.root = "gpt-auto"; + boot.initrd.supportedFilesystems = ["ext4"]; + ''; + }; } diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix index 135d61fd71d7..05e66dd704af 100644 --- a/pkgs/os-specific/linux/systemd/default.nix +++ b/pkgs/os-specific/linux/systemd/default.nix @@ -866,7 +866,7 @@ stdenv.mkDerivation (finalAttrs: { # needed - and therefore `interfaceVersion` should be incremented. interfaceVersion = 2; - inherit withBootloader withCryptsetup withHostnamed withImportd withKmod + inherit withBootloader withCryptsetup withEfi withHostnamed withImportd withKmod withLocaled withMachined withPortabled withTimedated withUtmp util-linux kmod kbd; tests = { From 375868120042070daaf715f72d1a6df94e714a26 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Sat, 16 Mar 2024 15:12:15 -0400 Subject: [PATCH 2/2] nixos/tests/hibernate: Use EFI So that resumeDevice isn't needed to make systemd stage 1 work. --- nixos/tests/hibernate.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/tests/hibernate.nix b/nixos/tests/hibernate.nix index 296aa9ba68b9..6de287f63e08 100644 --- a/nixos/tests/hibernate.nix +++ b/nixos/tests/hibernate.nix @@ -24,8 +24,8 @@ makeTest { virtualisation.useNixStoreImage = true; swapDevices = lib.mkOverride 0 [ { device = "/dev/vdc"; options = [ "x-systemd.makefs" ]; } ]; - boot.resumeDevice = "/dev/vdc"; boot.initrd.systemd.enable = systemdStage1; + virtualisation.useEFIBoot = true; }; };