diff options
Diffstat (limited to 'nixpkgs/nixos/modules/tasks/filesystems/zfs.nix')
-rw-r--r-- | nixpkgs/nixos/modules/tasks/filesystems/zfs.nix | 142 |
1 files changed, 81 insertions, 61 deletions
diff --git a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix index 16ba0b746789..59676e996785 100644 --- a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixpkgs/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,20 @@ in options = { boot.zfs = { + package = mkOption { + readOnly = true; + type = types.package; + default = 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; @@ -324,39 +326,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; + }; - ZED_EMAIL_ADDR = [ "root" ]; - ZED_EMAIL_PROG = "mail"; - ZED_EMAIL_OPTS = "-s '@SUBJECT@' @ADDRESS@"; + settings = mkOption { + type = with types; attrsOf (oneOf [ str int bool (listOf str) ]); + example = literalExample '' + { + ZED_DEBUG_LOG = "/tmp/zed.debug.log"; - ZED_NOTIFY_INTERVAL_SECS = 3600; - ZED_NOTIFY_VERBOSE = false; + ZED_EMAIL_ADDR = [ "root" ]; + ZED_EMAIL_PROG = "mail"; + ZED_EMAIL_OPTS = "-s '@SUBJECT@' @ADDRESS@"; - 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_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 + ''; + }; }; }; ###### 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"; } @@ -366,20 +382,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 '' @@ -431,9 +451,9 @@ in }; 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 @@ -461,18 +481,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: @@ -506,8 +526,8 @@ in 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 @@ -522,7 +542,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 @@ -532,10 +552,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 @@ -561,7 +581,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: @@ -587,7 +607,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" @@ -625,7 +645,7 @@ in }) snapshotNames); }) - (mkIf (enableZfs && cfgScrub.enable) { + (mkIf (cfgZfs.enabled && cfgScrub.enable) { systemd.services.zfs-scrub = { description = "ZFS pools scrubbing"; after = [ "zfs-import.target" ]; @@ -633,11 +653,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)" } ''; }; @@ -652,11 +672,11 @@ 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 |