From dfd0f18d9df417bb185d95ac806c220049fbfca1 Mon Sep 17 00:00:00 2001 From: ThinkChaos Date: Wed, 18 Feb 2026 15:27:28 -0500 Subject: [PATCH 1/2] nixos/zfs: default `forceImportRoot` to false for stateVersion >= 26.11 and warn before that As per 12e77fdc3f6f223be1a4d5c88d6c79bff63ae70c that set it to true: > This may currently be necessary, especially if your pools have not > been correctly imported with a proper host id configuration (which > is probably true for 99% of current NixOS ZFS users). Once host id > configuration becomes mandatory when using ZFS in NixOS and we are > sure that most users have updated their configurations and rebooted > at least once, we should disable force-import by default. Probably, > this shouldn't be done before the next stable release. A couple stable releases have come and gone since 2014! Let's remove this armed and aimed footgun. --- nixos/modules/tasks/filesystems/zfs.nix | 39 ++++++++++++++++--------- nixos/tests/zfs.nix | 5 ++-- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index 60db7399cdda..4644d007ebec 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -358,19 +358,18 @@ in forceImportRoot = lib.mkOption { type = lib.types.bool; - default = true; + default = lib.versionOlder config.system.stateVersion "26.11"; + defaultText = lib.literalExpression ''lib.versionOlder config.system.stateVersion "26.11"''; description = '' Forcibly import the ZFS root pool(s) during early boot. - 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. + It is highly recommended to keep this option disabled as it bypasses ZFS + safeguard that protect your pools. - If you set this option to `false` and NixOS subsequently fails to - boot because it cannot import the root pool, you should boot with the - `zfs_force=1` option as a kernel parameter (e.g. by manually - editing the kernel params in grub during boot). You should only need to do this - once. + If NixOS fails to boot because it cannot import the root pool, you should boot + with the `zfs_force=1` option as a kernel parameter (e.g. by manually + editing the kernel params via your bootloader). + You should only need to do this after unclean shutdowns. ''; }; @@ -380,10 +379,10 @@ in description = '' Forcibly import all ZFS pool(s). - If you set this option to `false` and NixOS subsequently fails to - import your non-root ZFS pool(s), you should manually import each pool with - "zpool import -f \", and then reboot. You should only need to do - this once. + It is highly recommended to keep this option disabled as it bypasses ZFS + safeguard that protect your pools. + + See {option}`boot.zfs.forceImportRoot` for details. ''; }; @@ -680,7 +679,7 @@ in message = "ZFS requires networking.hostId to be set"; } { - assertion = !cfgZfs.forceImportAll || cfgZfs.forceImportRoot; + assertion = cfgZfs.forceImportAll -> cfgZfs.forceImportRoot; message = "If you enable boot.zfs.forceImportAll, you must also enable boot.zfs.forceImportRoot"; } { @@ -698,6 +697,18 @@ in } ]; + warnings = + lib.optional + ( + options.boot.zfs.forceImportRoot.definitionsWithLocations == [ + { + inherit (__curPos) file; + value = true; + } + ] + ) + "`boot.zfs.forceImportRoot` is using the default value of `true`. It is highly recommended to set it to `false`, the new default from 26.11 on, to reduce the risk of data loss. Alternatively, you can silence this warning by explicitly setting it to `true`."; + boot = { kernelModules = [ "zfs" ]; # https://github.com/openzfs/zfs/issues/260 diff --git a/nixos/tests/zfs.nix b/nixos/tests/zfs.nix index 5a7c493e42b1..7851368075a0 100644 --- a/nixos/tests/zfs.nix +++ b/nixos/tests/zfs.nix @@ -23,7 +23,6 @@ let nodes.machine = { - config, pkgs, lib, ... @@ -54,6 +53,8 @@ let # /dev/disk/by-id doesn't get populated in the NixOS test framework boot.zfs.devNodes = "/dev/disk/by-uuid"; + boot.zfs.forceImportRoot = lib.mkDefault false; + specialisation.samba.configuration = { services.samba = { enable = true; @@ -101,6 +102,7 @@ let systemd.services.zfs-import-forcepool.wantedBy = lib.mkVMOverride [ "forcepool.mount" ]; systemd.targets.zfs.wantedBy = lib.mkVMOverride [ ]; boot.zfs.forceImportAll = true; + boot.zfs.forceImportRoot = true; virtualisation.fileSystems."/forcepool" = { device = "forcepool"; fsType = "zfs"; @@ -203,7 +205,6 @@ let in { - series_2_3 = makeZfsTest { zfsPackage = pkgs.zfs_2_3; kernelPackages = pkgs.linuxPackages; From 17fd12ce9c20f388a042cf1651917f9d1f9a4ddc Mon Sep 17 00:00:00 2001 From: ThinkChaos Date: Wed, 18 Feb 2026 17:28:57 -0500 Subject: [PATCH 2/2] nixos/zfs: rename `allowHibernation` to `unsafeAllowHibernation` Update the name and documentation to make it clear it's a matter of "when" not "if". This change was recommended in 2023 but noone followed up: https://github.com/NixOS/nixpkgs/pull/208037#issuecomment-1688855654 (I never used this and have suffered no dataloss, but might as well make this small improvement while I notice the currently dire situation.) --- nixos/modules/tasks/filesystems/zfs.nix | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index 4644d007ebec..910bd302b98e 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -285,6 +285,10 @@ in "zfs" "enableUnstable" ] "Instead set `boot.zfs.package = pkgs.zfs_unstable;`") + (lib.mkRenamedOptionModule + [ "boot" "zfs" "allowHibernation" ] + [ "boot" "zfs" "unsafeAllowHibernation" ] + ) ]; ###### interface @@ -313,12 +317,12 @@ in description = "True if ZFS filesystem support is enabled"; }; - allowHibernation = lib.mkOption { + unsafeAllowHibernation = lib.mkOption { type = lib.types.bool; default = false; description = '' - Allow hibernation support, this may be a unsafe option depending on your - setup. Make sure to NOT use Swap on ZFS. + Allow hibernation (suspend to disk) support. This is generally considered **UNSAFE**, + is not well supported by openzfs, and could lead to corruption and data loss. ''; }; @@ -683,8 +687,8 @@ in message = "If you enable boot.zfs.forceImportAll, you must also enable boot.zfs.forceImportRoot"; } { - assertion = cfgZfs.allowHibernation -> !cfgZfs.forceImportRoot && !cfgZfs.forceImportAll; - message = "boot.zfs.allowHibernation while force importing is enabled will cause data corruption"; + assertion = cfgZfs.unsafeAllowHibernation -> !cfgZfs.forceImportRoot && !cfgZfs.forceImportAll; + message = "boot.zfs.unsafeAllowHibernation while force importing is enabled will cause data corruption"; } { assertion = !(lib.elem "" allPools); @@ -711,10 +715,11 @@ in boot = { kernelModules = [ "zfs" ]; - # https://github.com/openzfs/zfs/issues/260 + # https://github.com/openzfs/zfs/issues/260#issuecomment-982142240 # https://github.com/openzfs/zfs/issues/12842 + # https://github.com/openzfs/zfs/issues/14118#issuecomment-1301576647 # https://github.com/NixOS/nixpkgs/issues/106093 - kernelParams = lib.optionals (!config.boot.zfs.allowHibernation) [ "nohibernate" ]; + kernelParams = lib.optionals (!config.boot.zfs.unsafeAllowHibernation) [ "nohibernate" ]; extraModulePackages = [ cfgZfs.modulePackage