diff options
Diffstat (limited to 'nixos/modules/tasks/filesystems')
-rw-r--r-- | nixos/modules/tasks/filesystems/bcachefs.nix | 4 | ||||
-rw-r--r-- | nixos/modules/tasks/filesystems/btrfs.nix | 11 | ||||
-rw-r--r-- | nixos/modules/tasks/filesystems/nfs.nix | 48 | ||||
-rw-r--r-- | nixos/modules/tasks/filesystems/unionfs-fuse.nix | 6 | ||||
-rw-r--r-- | nixos/modules/tasks/filesystems/zfs.nix | 161 |
5 files changed, 141 insertions, 89 deletions
diff --git a/nixos/modules/tasks/filesystems/bcachefs.nix b/nixos/modules/tasks/filesystems/bcachefs.nix index 5fda24adb97..ac41ba5f93a 100644 --- a/nixos/modules/tasks/filesystems/bcachefs.nix +++ b/nixos/modules/tasks/filesystems/bcachefs.nix @@ -49,8 +49,8 @@ in } (mkIf ((elem "bcachefs" config.boot.initrd.supportedFilesystems) || (bootFs != {})) { - # the cryptographic modules are required only for decryption attempts - boot.initrd.availableKernelModules = [ "bcachefs" "chacha20" "poly1305" ]; + # chacha20 and poly1305 are required only for decryption attempts + boot.initrd.availableKernelModules = [ "bcachefs" "sha256" "chacha20" "poly1305" ]; boot.initrd.extraUtilsCommands = '' copy_bin_and_libs ${pkgs.bcachefs-tools}/bin/bcachefs diff --git a/nixos/modules/tasks/filesystems/btrfs.nix b/nixos/modules/tasks/filesystems/btrfs.nix index c0ff28039b1..ae1dab5b8d8 100644 --- a/nixos/modules/tasks/filesystems/btrfs.nix +++ b/nixos/modules/tasks/filesystems/btrfs.nix @@ -55,7 +55,16 @@ in (mkIf enableBtrfs { system.fsPackages = [ pkgs.btrfs-progs ]; - boot.initrd.kernelModules = mkIf inInitrd [ "btrfs" "crc32c" ]; + boot.initrd.kernelModules = mkIf inInitrd [ "btrfs" ]; + boot.initrd.availableKernelModules = mkIf inInitrd ( + [ "crc32c" ] + ++ optionals (config.boot.kernelPackages.kernel.kernelAtLeast "5.5") [ + # Needed for mounting filesystems with new checksums + "xxhash_generic" + "blake2b_generic" + "sha256_generic" # Should be baked into our kernel, just to be sure + ] + ); boot.initrd.extraUtilsCommands = mkIf inInitrd '' diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix index ddcc0ed8f5a..fd35c35d32a 100644 --- a/nixos/modules/tasks/filesystems/nfs.nix +++ b/nixos/modules/tasks/filesystems/nfs.nix @@ -10,20 +10,9 @@ let rpcMountpoint = "${nfsStateDir}/rpc_pipefs"; - idmapdConfFile = pkgs.writeText "idmapd.conf" '' - [General] - Pipefs-Directory = ${rpcMountpoint} - ${optionalString (config.networking.domain != null) - "Domain = ${config.networking.domain}"} - - [Mapping] - Nobody-User = nobody - Nobody-Group = nogroup - - [Translation] - Method = nsswitch - ''; + format = pkgs.formats.ini {}; + idmapdConfFile = format.generate "idmapd.conf" cfg.idmapd.settings; nfsConfFile = pkgs.writeText "nfs.conf" cfg.extraConfig; requestKeyConfFile = pkgs.writeText "request-key.conf" '' create id_resolver * * ${pkgs.nfs-utils}/bin/nfsidmap -t 600 %k %d @@ -38,6 +27,25 @@ in options = { services.nfs = { + idmapd.settings = mkOption { + type = format.type; + default = {}; + description = '' + libnfsidmap configuration. Refer to + <link xlink:href="https://linux.die.net/man/5/idmapd.conf"/> + for details. + ''; + example = literalExample '' + { + Translation = { + GSS-Methods = "static,nsswitch"; + }; + Static = { + "root/hostname.domain.com@REALM.COM" = "root"; + }; + } + ''; + }; extraConfig = mkOption { type = types.lines; default = ""; @@ -54,6 +62,20 @@ in services.rpcbind.enable = true; + services.nfs.idmapd.settings = { + General = mkMerge [ + { Pipefs-Directory = rpcMountpoint; } + (mkIf (config.networking.domain != null) { Domain = config.networking.domain; }) + ]; + Mapping = { + Nobody-User = "nobody"; + Nobody-Group = "nogroup"; + }; + Translation = { + Method = "nsswitch"; + }; + }; + system.fsPackages = [ pkgs.nfs-utils ]; boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; diff --git a/nixos/modules/tasks/filesystems/unionfs-fuse.nix b/nixos/modules/tasks/filesystems/unionfs-fuse.nix index 1dcc4c87e3c..f54f3559c34 100644 --- a/nixos/modules/tasks/filesystems/unionfs-fuse.nix +++ b/nixos/modules/tasks/filesystems/unionfs-fuse.nix @@ -18,9 +18,9 @@ boot.initrd.postDeviceCommands = '' # Hacky!!! fuse hard-codes the path to mount - mkdir -p /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}-bin/bin - ln -s $(which mount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}-bin/bin - ln -s $(which umount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}-bin/bin + 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 ''; }) diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index 9ca7c6fb343..376d6530f36 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -17,20 +17,8 @@ let inInitrd = any (fs: fs == "zfs") config.boot.initrd.supportedFilesystems; inSystem = any (fs: fs == "zfs") config.boot.supportedFilesystems; - enableZfs = inInitrd || inSystem; - - kernel = config.boot.kernelPackages; - - packages = if config.boot.zfs.enableUnstable then { - zfs = kernel.zfsUnstable; - zfsUser = pkgs.zfsUnstable; - } else { - zfs = kernel.zfs; - zfsUser = pkgs.zfs; - }; - autosnapPkg = pkgs.zfstools.override { - zfs = packages.zfsUser; + zfs = cfgZfs.package; }; zfsAutoSnap = "${autosnapPkg}/bin/zfs-auto-snapshot"; @@ -111,6 +99,21 @@ in options = { boot.zfs = { + package = mkOption { + readOnly = true; + type = types.package; + default = if config.boot.zfs.enableUnstable then pkgs.zfsUnstable else pkgs.zfs; + defaultText = "if config.boot.zfs.enableUnstable then pkgs.zfsUnstable else pkgs.zfs"; + description = "Configured ZFS userland tools package."; + }; + + enabled = mkOption { + readOnly = true; + type = types.bool; + default = inInitrd || inSystem; + description = "True if ZFS filesystem support is enabled"; + }; + enableUnstable = mkOption { type = types.bool; default = false; @@ -175,14 +178,10 @@ in forceImportAll = mkOption { type = types.bool; - default = true; + default = false; description = '' Forcibly import all ZFS pool(s). - This is enabled by default for backwards compatibility purposes, but it is highly - recommended to disable this option, as it bypasses some of the safeguards ZFS uses - to protect your ZFS pools. - If you set this option to <literal>false</literal> and NixOS subsequently fails to import your non-root ZFS pool(s), you should manually import each pool with "zpool import -f <pool-name>", and then reboot. You should only need to do @@ -304,7 +303,7 @@ in }; services.zfs.autoScrub = { - enable = mkEnableOption "Enables periodic scrubbing of ZFS pools."; + enable = mkEnableOption "periodic scrubbing of ZFS pools"; interval = mkOption { default = "Sun, 02:00"; @@ -328,39 +327,53 @@ in }; }; - services.zfs.zed.settings = mkOption { - type = with types; attrsOf (oneOf [ str int bool (listOf str) ]); - example = literalExample '' - { - ZED_DEBUG_LOG = "/tmp/zed.debug.log"; + services.zfs.zed = { + enableMail = mkEnableOption "ZED's ability to send emails" // { + default = cfgZfs.package.enableMail; + }; + + settings = mkOption { + type = with types; attrsOf (oneOf [ str int bool (listOf str) ]); + example = literalExample '' + { + ZED_DEBUG_LOG = "/tmp/zed.debug.log"; - ZED_EMAIL_ADDR = [ "root" ]; - ZED_EMAIL_PROG = "mail"; - ZED_EMAIL_OPTS = "-s '@SUBJECT@' @ADDRESS@"; + ZED_EMAIL_ADDR = [ "root" ]; + ZED_EMAIL_PROG = "mail"; + ZED_EMAIL_OPTS = "-s '@SUBJECT@' @ADDRESS@"; - ZED_NOTIFY_INTERVAL_SECS = 3600; - ZED_NOTIFY_VERBOSE = false; + ZED_NOTIFY_INTERVAL_SECS = 3600; + ZED_NOTIFY_VERBOSE = false; - ZED_USE_ENCLOSURE_LEDS = true; - ZED_SCRUB_AFTER_RESILVER = false; - } - ''; - description = '' - ZFS Event Daemon /etc/zfs/zed.d/zed.rc content - - See - <citerefentry><refentrytitle>zed</refentrytitle><manvolnum>8</manvolnum></citerefentry> - for details on ZED and the scripts in /etc/zfs/zed.d to find the possible variables - ''; + ZED_USE_ENCLOSURE_LEDS = true; + ZED_SCRUB_AFTER_RESILVER = false; + } + ''; + description = '' + ZFS Event Daemon /etc/zfs/zed.d/zed.rc content + + See + <citerefentry><refentrytitle>zed</refentrytitle><manvolnum>8</manvolnum></citerefentry> + for details on ZED and the scripts in /etc/zfs/zed.d to find the possible variables + ''; + }; }; }; ###### implementation config = mkMerge [ - (mkIf enableZfs { + (mkIf cfgZfs.enabled { assertions = [ { + assertion = cfgZED.enableMail -> cfgZfs.package.enableMail; + message = '' + To allow ZED to send emails, ZFS needs to be configured to enable + this. To do so, one must override the `zfs` package and set + `enableMail` to true. + ''; + } + { assertion = config.networking.hostId != null; message = "ZFS requires networking.hostId to be set"; } @@ -370,20 +383,24 @@ in } ]; - virtualisation.lxd.zfsSupport = true; - boot = { kernelModules = [ "zfs" ]; - extraModulePackages = with packages; [ zfs ]; + + extraModulePackages = [ + (if config.boot.zfs.enableUnstable then + config.boot.kernelPackages.zfsUnstable + else + config.boot.kernelPackages.zfs) + ]; }; boot.initrd = mkIf inInitrd { kernelModules = [ "zfs" ] ++ optional (!cfgZfs.enableUnstable) "spl"; extraUtilsCommands = '' - copy_bin_and_libs ${packages.zfsUser}/sbin/zfs - copy_bin_and_libs ${packages.zfsUser}/sbin/zdb - copy_bin_and_libs ${packages.zfsUser}/sbin/zpool + copy_bin_and_libs ${cfgZfs.package}/sbin/zfs + copy_bin_and_libs ${cfgZfs.package}/sbin/zdb + copy_bin_and_libs ${cfgZfs.package}/sbin/zpool ''; extraUtilsCommandsTest = mkIf inInitrd '' @@ -430,21 +447,22 @@ in '') rootPools)); }; - boot.loader.grub = mkIf inInitrd { + # TODO FIXME See https://github.com/NixOS/nixpkgs/pull/99386#issuecomment-798813567. To not break people's bootloader and as probably not everybody would read release notes that thoroughly add inSystem. + boot.loader.grub = mkIf (inInitrd || inSystem) { zfsSupport = true; }; services.zfs.zed.settings = { - ZED_EMAIL_PROG = mkDefault "${pkgs.mailutils}/bin/mail"; + ZED_EMAIL_PROG = mkIf cfgZED.enableMail (mkDefault "${pkgs.mailutils}/bin/mail"); PATH = lib.makeBinPath [ - packages.zfsUser + cfgZfs.package pkgs.coreutils pkgs.curl pkgs.gawk pkgs.gnugrep pkgs.gnused pkgs.nettools - pkgs.utillinux + pkgs.util-linux ]; }; @@ -465,18 +483,18 @@ in "vdev_clear-led.sh" ] ) - (file: { source = "${packages.zfsUser}/etc/${file}"; }) + (file: { source = "${cfgZfs.package}/etc/${file}"; }) // { "zfs/zed.d/zed.rc".text = zedConf; - "zfs/zpool.d".source = "${packages.zfsUser}/etc/zfs/zpool.d/"; + "zfs/zpool.d".source = "${cfgZfs.package}/etc/zfs/zpool.d/"; }; - system.fsPackages = [ packages.zfsUser ]; # XXX: needed? zfs doesn't have (need) a fsck - environment.systemPackages = [ packages.zfsUser ] + system.fsPackages = [ cfgZfs.package ]; # XXX: needed? zfs doesn't have (need) a fsck + environment.systemPackages = [ cfgZfs.package ] ++ optional cfgSnapshots.enable autosnapPkg; # so the user can run the command to see flags - services.udev.packages = [ packages.zfsUser ]; # to hook zvol naming, etc. - systemd.packages = [ packages.zfsUser ]; + services.udev.packages = [ cfgZfs.package ]; # to hook zvol naming, etc. + systemd.packages = [ cfgZfs.package ]; systemd.services = let getPoolFilesystems = pool: @@ -507,10 +525,11 @@ in Type = "oneshot"; RemainAfterExit = true; }; + environment.ZFS_FORCE = optionalString cfgZfs.forceImportAll "-f"; script = (importLib { # See comments at importLib definition. - zpoolCmd="${packages.zfsUser}/sbin/zpool"; - awkCmd="${pkgs.gawk}/bin/awk"; + zpoolCmd = "${cfgZfs.package}/sbin/zpool"; + awkCmd = "${pkgs.gawk}/bin/awk"; inherit cfgZfs; }) + '' poolImported "${pool}" && exit @@ -525,7 +544,7 @@ in ${optionalString (if isBool cfgZfs.requestEncryptionCredentials then cfgZfs.requestEncryptionCredentials else cfgZfs.requestEncryptionCredentials != []) '' - ${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do + ${cfgZfs.package}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do (${optionalString (!isBool cfgZfs.requestEncryptionCredentials) '' if ! echo '${concatStringsSep "\n" cfgZfs.requestEncryptionCredentials}' | grep -qFx "$ds"; then continue @@ -535,10 +554,10 @@ in none ) ;; prompt ) - ${config.systemd.package}/bin/systemd-ask-password "Enter key for $ds:" | ${packages.zfsUser}/sbin/zfs load-key "$ds" + ${config.systemd.package}/bin/systemd-ask-password "Enter key for $ds:" | ${cfgZfs.package}/sbin/zfs load-key "$ds" ;; * ) - ${packages.zfsUser}/sbin/zfs load-key "$ds" + ${cfgZfs.package}/sbin/zfs load-key "$ds" ;; esac) < /dev/null # To protect while read ds kl in case anything reads stdin done @@ -564,7 +583,7 @@ in RemainAfterExit = true; }; script = '' - ${packages.zfsUser}/sbin/zfs set nixos:shutdown-time="$(date)" "${pool}" + ${cfgZfs.package}/sbin/zfs set nixos:shutdown-time="$(date)" "${pool}" ''; }; createZfsService = serv: @@ -590,7 +609,7 @@ in systemd.targets.zfs.wantedBy = [ "multi-user.target" ]; }) - (mkIf (enableZfs && cfgSnapshots.enable) { + (mkIf (cfgZfs.enabled && cfgSnapshots.enable) { systemd.services = let descr = name: if name == "frequent" then "15 mins" else if name == "hourly" then "hour" @@ -628,7 +647,7 @@ in }) snapshotNames); }) - (mkIf (enableZfs && cfgScrub.enable) { + (mkIf (cfgZfs.enabled && cfgScrub.enable) { systemd.services.zfs-scrub = { description = "ZFS pools scrubbing"; after = [ "zfs-import.target" ]; @@ -636,11 +655,11 @@ in Type = "oneshot"; }; script = '' - ${packages.zfsUser}/bin/zpool scrub ${ + ${cfgZfs.package}/bin/zpool scrub ${ if cfgScrub.pools != [] then (concatStringsSep " " cfgScrub.pools) else - "$(${packages.zfsUser}/bin/zpool list -H -o name)" + "$(${cfgZfs.package}/bin/zpool list -H -o name)" } ''; }; @@ -655,18 +674,20 @@ in }; }) - (mkIf (enableZfs && cfgTrim.enable) { + (mkIf (cfgZfs.enabled && cfgTrim.enable) { systemd.services.zpool-trim = { description = "ZFS pools trim"; after = [ "zfs-import.target" ]; - path = [ packages.zfsUser ]; + path = [ cfgZfs.package ]; startAt = cfgTrim.interval; # By default we ignore errors returned by the trim command, in case: # - HDDs are mixed with SSDs # - There is a SSDs in a pool that is currently trimmed. # - There are only HDDs and we would set the system in a degraded state - serviceConfig.ExecStart = ''${pkgs.runtimeShell} -c 'for pool in $(zpool list -H -o name); do zpool trim $pool; done || true' ''; + serviceConfig.ExecStart = "${pkgs.runtimeShell} -c 'for pool in $(zpool list -H -o name); do zpool trim $pool; done || true' "; }; + + systemd.timers.zpool-trim.timerConfig.Persistent = "yes"; }) ]; } |