From 160fb93fdc4155d7e6304f366384ad8afb00db1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Sat, 16 Apr 2022 20:46:32 +0100 Subject: [PATCH 1/2] nixos/filesystems: Make most simple filesystems compatible with systemd This includes disabling some features in the initrd by default, this is only done when the new initrd is used. Namely, ext and bcache are disabled by default. bcache gets an own enable option while ext is detected like any other filesystem. --- .../cd-dvd/system-tarball-sheevaplug.nix | 6 ++--- nixos/modules/tasks/bcache.nix | 22 ++++++++++++++----- nixos/modules/tasks/filesystems/btrfs.nix | 4 ++-- nixos/modules/tasks/filesystems/cifs.nix | 2 +- nixos/modules/tasks/filesystems/ext.nix | 14 ++++++++---- nixos/modules/tasks/filesystems/f2fs.nix | 2 +- nixos/modules/tasks/filesystems/jfs.nix | 2 +- nixos/modules/tasks/filesystems/reiserfs.nix | 2 +- .../tasks/filesystems/unionfs-fuse.nix | 15 +++++++++++-- nixos/modules/tasks/filesystems/vfat.nix | 2 +- nixos/modules/tasks/filesystems/xfs.nix | 4 ++-- 11 files changed, 51 insertions(+), 24 deletions(-) diff --git a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix index 458e313a3f75..329bd329dc15 100644 --- a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix +++ b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix @@ -87,19 +87,19 @@ in boot.initrd.availableKernelModules = [ "mvsdio" "reiserfs" "ext3" "ums-cypress" "rtc_mv" "ext4" ]; - boot.postBootCommands = + boot.postBootCommands = lib.mkIf (!boot.initrd.systemd.enable) '' mkdir -p /mnt cp ${dummyConfiguration} /etc/nixos/configuration.nix ''; - boot.initrd.extraUtilsCommands = + boot.initrd.extraUtilsCommands = lib.mkIf (!boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.util-linux}/sbin/hwclock ''; - boot.initrd.postDeviceCommands = + boot.initrd.postDeviceCommands = lib.mkIf (!boot.initrd.systemd.enable) '' hwclock -s ''; diff --git a/nixos/modules/tasks/bcache.nix b/nixos/modules/tasks/bcache.nix index 41fb7664f3d1..0a13522de11f 100644 --- a/nixos/modules/tasks/bcache.nix +++ b/nixos/modules/tasks/bcache.nix @@ -1,13 +1,23 @@ -{ pkgs, ... }: +{ config, lib, pkgs, ... }: { + options.boot.initrd.services.bcache.enable = (lib.mkEnableOption "bcache support in the initrd") // { + visible = false; # only works with systemd stage 1 + }; - environment.systemPackages = [ pkgs.bcache-tools ]; + config = { - services.udev.packages = [ pkgs.bcache-tools ]; + environment.systemPackages = [ pkgs.bcache-tools ]; - boot.initrd.extraUdevRulesCommands = '' - cp -v ${pkgs.bcache-tools}/lib/udev/rules.d/*.rules $out/ - ''; + services.udev.packages = [ pkgs.bcache-tools ]; + boot.initrd.extraUdevRulesCommands = lib.mkIf (!config.boot.initrd.systemd.enable) '' + cp -v ${pkgs.bcache-tools}/lib/udev/rules.d/*.rules $out/ + ''; + + boot.initrd.services.udev = lib.mkIf config.boot.initrd.services.bcache.enable { + packages = [ pkgs.bcache-tools ]; + binPackages = [ pkgs.bcache-tools ]; + }; + }; } diff --git a/nixos/modules/tasks/filesystems/btrfs.nix b/nixos/modules/tasks/filesystems/btrfs.nix index ae1dab5b8d8d..33736e2043ac 100644 --- a/nixos/modules/tasks/filesystems/btrfs.nix +++ b/nixos/modules/tasks/filesystems/btrfs.nix @@ -66,14 +66,14 @@ in ] ); - boot.initrd.extraUtilsCommands = mkIf inInitrd + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.btrfs-progs}/bin/btrfs ln -sv btrfs $out/bin/btrfsck ln -sv btrfsck $out/bin/fsck.btrfs ''; - boot.initrd.extraUtilsCommandsTest = mkIf inInitrd + boot.initrd.extraUtilsCommandsTest = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' $out/bin/btrfs --version ''; diff --git a/nixos/modules/tasks/filesystems/cifs.nix b/nixos/modules/tasks/filesystems/cifs.nix index 47ba0c03c563..0de292a69208 100644 --- a/nixos/modules/tasks/filesystems/cifs.nix +++ b/nixos/modules/tasks/filesystems/cifs.nix @@ -16,7 +16,7 @@ in boot.initrd.availableKernelModules = mkIf inInitrd [ "cifs" "nls_utf8" "hmac" "md4" "ecb" "des_generic" "sha256" ]; - boot.initrd.extraUtilsCommands = mkIf inInitrd + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.cifs-utils}/sbin/mount.cifs ''; diff --git a/nixos/modules/tasks/filesystems/ext.nix b/nixos/modules/tasks/filesystems/ext.nix index a14a3ac38549..9b61f21643ab 100644 --- a/nixos/modules/tasks/filesystems/ext.nix +++ b/nixos/modules/tasks/filesystems/ext.nix @@ -1,14 +1,20 @@ -{ pkgs, ... }: +{ config, lib, pkgs, ... }: + +let + + inInitrd = lib.any (fs: fs == "ext2" || fs == "ext3" || fs == "ext4") config.boot.initrd.supportedFilesystems; + +in { config = { - system.fsPackages = [ pkgs.e2fsprogs ]; + system.fsPackages = lib.mkIf (config.boot.initrd.systemd.enable -> inInitrd) [ pkgs.e2fsprogs ]; # As of kernel 4.3, there is no separate ext3 driver (they're also handled by ext4.ko) - boot.initrd.availableKernelModules = [ "ext2" "ext4" ]; + boot.initrd.availableKernelModules = lib.mkIf (config.boot.initrd.systemd.enable -> inInitrd) [ "ext2" "ext4" ]; - boot.initrd.extraUtilsCommands = + boot.initrd.extraUtilsCommands = lib.mkIf (!config.boot.initrd.systemd.enable) '' # Copy e2fsck and friends. copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/e2fsck diff --git a/nixos/modules/tasks/filesystems/f2fs.nix b/nixos/modules/tasks/filesystems/f2fs.nix index a305235979a2..1d52861aa39d 100644 --- a/nixos/modules/tasks/filesystems/f2fs.nix +++ b/nixos/modules/tasks/filesystems/f2fs.nix @@ -13,7 +13,7 @@ in boot.initrd.availableKernelModules = mkIf inInitrd [ "f2fs" "crc32" ]; - boot.initrd.extraUtilsCommands = mkIf inInitrd '' + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/fsck.f2fs ${optionalString (any (fs: fs.autoResize) fileSystems) '' # We need f2fs-tools' tools to resize filesystems diff --git a/nixos/modules/tasks/filesystems/jfs.nix b/nixos/modules/tasks/filesystems/jfs.nix index fc3905c7dc20..700f05af2bec 100644 --- a/nixos/modules/tasks/filesystems/jfs.nix +++ b/nixos/modules/tasks/filesystems/jfs.nix @@ -12,7 +12,7 @@ in boot.initrd.kernelModules = mkIf inInitrd [ "jfs" ]; - boot.initrd.extraUtilsCommands = mkIf inInitrd '' + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.jfsutils}/sbin/fsck.jfs ''; }; diff --git a/nixos/modules/tasks/filesystems/reiserfs.nix b/nixos/modules/tasks/filesystems/reiserfs.nix index ab4c43e2ab82..7b017a83db84 100644 --- a/nixos/modules/tasks/filesystems/reiserfs.nix +++ b/nixos/modules/tasks/filesystems/reiserfs.nix @@ -15,7 +15,7 @@ in boot.initrd.kernelModules = mkIf inInitrd [ "reiserfs" ]; - boot.initrd.extraUtilsCommands = mkIf inInitrd + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.reiserfsprogs}/sbin/reiserfsck ln -s reiserfsck $out/bin/fsck.reiserfs diff --git a/nixos/modules/tasks/filesystems/unionfs-fuse.nix b/nixos/modules/tasks/filesystems/unionfs-fuse.nix index f54f3559c341..f9954b5182f9 100644 --- a/nixos/modules/tasks/filesystems/unionfs-fuse.nix +++ b/nixos/modules/tasks/filesystems/unionfs-fuse.nix @@ -6,7 +6,7 @@ (lib.mkIf (lib.any (fs: fs == "unionfs-fuse") config.boot.initrd.supportedFilesystems) { boot.initrd.kernelModules = [ "fuse" ]; - boot.initrd.extraUtilsCommands = '' + boot.initrd.extraUtilsCommands = lib.mkIf (!config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.fuse}/sbin/mount.fuse copy_bin_and_libs ${pkgs.unionfs-fuse}/bin/unionfs substitute ${pkgs.unionfs-fuse}/sbin/mount.unionfs-fuse $out/bin/mount.unionfs-fuse \ @@ -16,12 +16,23 @@ chmod +x $out/bin/mount.unionfs-fuse ''; - boot.initrd.postDeviceCommands = '' + boot.initrd.postDeviceCommands = lib.mkIf (!config.boot.initrd.systemd.enable) '' # Hacky!!! fuse hard-codes the path to mount mkdir -p /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.util-linux.name}-bin/bin ln -s $(which mount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.util-linux.name}-bin/bin ln -s $(which umount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.util-linux.name}-bin/bin ''; + + boot.initrd.systemd.extraBin = { + "mount.fuse" = "${pkgs.fuse}/bin/mount.fuse"; + "unionfs" = "${pkgs.unionfs-fuse}/bin/unionfs"; + "mount.unionfs-fuse" = pkgs.runCommand "mount.unionfs-fuse" {} '' + substitute ${pkgs.unionfs-fuse}/sbin/mount.unionfs-fuse $out \ + --replace '${pkgs.bash}/bin/bash' /bin/sh \ + --replace '${pkgs.fuse}/sbin' /bin \ + --replace '${pkgs.unionfs-fuse}/bin' /bin + ''; + }; }) (lib.mkIf (lib.any (fs: fs == "unionfs-fuse") config.boot.supportedFilesystems) { diff --git a/nixos/modules/tasks/filesystems/vfat.nix b/nixos/modules/tasks/filesystems/vfat.nix index 958e27ae8a32..5baab1c802cf 100644 --- a/nixos/modules/tasks/filesystems/vfat.nix +++ b/nixos/modules/tasks/filesystems/vfat.nix @@ -15,7 +15,7 @@ in boot.initrd.kernelModules = mkIf inInitrd [ "vfat" "nls_cp437" "nls_iso8859-1" ]; - boot.initrd.extraUtilsCommands = mkIf inInitrd + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.dosfstools}/sbin/dosfsck ln -sv dosfsck $out/bin/fsck.vfat diff --git a/nixos/modules/tasks/filesystems/xfs.nix b/nixos/modules/tasks/filesystems/xfs.nix index 98038701ca58..80e46efcc780 100644 --- a/nixos/modules/tasks/filesystems/xfs.nix +++ b/nixos/modules/tasks/filesystems/xfs.nix @@ -15,14 +15,14 @@ in boot.initrd.availableKernelModules = mkIf inInitrd [ "xfs" "crc32c" ]; - boot.initrd.extraUtilsCommands = mkIf inInitrd + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.xfsprogs.bin}/bin/fsck.xfs copy_bin_and_libs ${pkgs.xfsprogs.bin}/bin/xfs_repair ''; # Trick just to set 'sh' after the extraUtils nuke-refs. - boot.initrd.extraUtilsCommandsTest = mkIf inInitrd + boot.initrd.extraUtilsCommandsTest = mkIf (inInitrd && !boot.initrd.systemd.enable) '' sed -i -e 's,^#!.*,#!'$out/bin/sh, $out/bin/fsck.xfs ''; From acca69992cda719eb71f29f5c8eedf7892127e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Sun, 17 Apr 2022 13:55:48 +0100 Subject: [PATCH 2/2] nixos/btrfs: Add systemd stage 1 support --- nixos/modules/tasks/filesystems/btrfs.nix | 2 +- nixos/tests/all-tests.nix | 1 + nixos/tests/systemd-initrd-btrfs-raid.nix | 45 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 nixos/tests/systemd-initrd-btrfs-raid.nix diff --git a/nixos/modules/tasks/filesystems/btrfs.nix b/nixos/modules/tasks/filesystems/btrfs.nix index 33736e2043ac..b7ebc37dd5cf 100644 --- a/nixos/modules/tasks/filesystems/btrfs.nix +++ b/nixos/modules/tasks/filesystems/btrfs.nix @@ -78,7 +78,7 @@ in $out/bin/btrfs --version ''; - boot.initrd.postDeviceCommands = mkIf inInitrd + boot.initrd.postDeviceCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' btrfs device scan ''; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 5158bc681e08..ad426fcf4e0a 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -524,6 +524,7 @@ in systemd-confinement = handleTest ./systemd-confinement.nix {}; systemd-cryptenroll = handleTest ./systemd-cryptenroll.nix {}; systemd-escaping = handleTest ./systemd-escaping.nix {}; + systemd-initrd-btrfs-raid = handleTest ./systemd-initrd-btrfs-raid.nix {}; systemd-initrd-luks-keyfile = handleTest ./systemd-initrd-luks-keyfile.nix {}; systemd-initrd-luks-password = handleTest ./systemd-initrd-luks-password.nix {}; systemd-initrd-shutdown = handleTest ./systemd-shutdown.nix { systemdStage1 = true; }; diff --git a/nixos/tests/systemd-initrd-btrfs-raid.nix b/nixos/tests/systemd-initrd-btrfs-raid.nix new file mode 100644 index 000000000000..40fd2d4dc611 --- /dev/null +++ b/nixos/tests/systemd-initrd-btrfs-raid.nix @@ -0,0 +1,45 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "systemd-initrd-btrfs-raid"; + + nodes.machine = { pkgs, ... }: { + # Use systemd-boot + virtualisation = { + emptyDiskImages = [ 512 512 ]; + useBootLoader = true; + useEFIBoot = true; + }; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + environment.systemPackages = with pkgs; [ btrfs-progs ]; + boot.initrd.systemd = { + enable = true; + emergencyAccess = true; + }; + + specialisation.boot-btrfs-raid.configuration = { + fileSystems = lib.mkVMOverride { + "/".fsType = lib.mkForce "btrfs"; + }; + virtualisation.bootDevice = "/dev/vdc"; + }; + }; + + testScript = '' + # Create RAID + machine.succeed("mkfs.btrfs -d raid0 /dev/vdc /dev/vdd") + machine.succeed("mkdir -p /mnt && mount /dev/vdc /mnt && echo hello > /mnt/test && umount /mnt") + + # Boot from the RAID + machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-btrfs-raid.conf") + machine.succeed("sync") + machine.crash() + machine.wait_for_unit("multi-user.target") + + # Ensure we have successfully booted from the RAID + assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 + assert "/dev/vdc on / type btrfs" in machine.succeed("mount") + assert "hello" in machine.succeed("cat /test") + assert "Total devices 2" in machine.succeed("btrfs filesystem show") + ''; +})