ZFS: Difference between revisions

imported>N8henrie
m typo: smbshare -> sharesmb
imported>2r
updates for root on zfs guide, boot.zfs.forceImportAll now false by default
Line 3: Line 3:


* ZFS does not support swap.  Hibernation must be either disabled with <code><nowiki>boot.kernelParams = [ "nohibernate" ];</nowiki></code>, or enabled with a separate, non-ZFS swap partition.
* ZFS does not support swap.  Hibernation must be either disabled with <code><nowiki>boot.kernelParams = [ "nohibernate" ];</nowiki></code>, or enabled with a separate, non-ZFS swap partition.
* By default, all ZFS pools available to the system will be forcibly imported during boot.  This behaviour can be disabled by setting <syntaxhighlight lang="nix" inline>boot.zfs.forceImportAll = false;</syntaxhighlight>.


* If you are running within a VM and NixOS fails to import the zpool on reboot, you may need to add <syntaxhighlight lang="nix" inline>boot.zfs.devNodes = "/dev/disk/by-path";</syntaxhighlight> to your configuration.nix file.
* If you are running within a VM and NixOS fails to import the zpool on reboot, you may need to add <syntaxhighlight lang="nix" inline>boot.zfs.devNodes = "/dev/disk/by-path";</syntaxhighlight> to your configuration.nix file.
Line 11: Line 9:


Common ZFS installation guides are now maintained at [https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/index.html OpenZFS Documentation] website. Visit there for details and if an issue arises, submit an issue or pull request.
Common ZFS installation guides are now maintained at [https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/index.html OpenZFS Documentation] website. Visit there for details and if an issue arises, submit an issue or pull request.
== Root on ZFS ==
Root on ZFS guide is now maintained at [https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/Root%20on%20ZFS.html OpenZFS Documentation] website. Visit there for details and if an issue arises, submit an issue or pull request.


==Importing on boot==
==Importing on boot==
Line 29: Line 31:
   fsType = "zfs";
   fsType = "zfs";
};
};
</syntaxhighlight>
== Root on ZFS ==
Root on ZFS guide is now maintained at [https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/Root%20on%20ZFS.html OpenZFS Documentation] website. Visit there for details and if an issue arises, submit an issue or pull request.
== Immutable Root on ZFS ==
After following the [https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/Root%20on%20ZFS.html OpenZFS Documentation], immutable root can be optionally enabled to clean up root filesystem at boot.
This involves mounting the existing root at a different location and bind mount necessary configuration files from the new mount point. We will use <code>/altroot</code> here.
<syntaxhighlight lang="nix">
## In /etc/nixos/configuration.nix:
  systemd.services.zfs-mount.enable = false;
boot.initrd.postDeviceCommands = ''
  zpool import -Nf rpool
  zfs rollback -r rpool/nixos/empty@start
  zpool export -a
'';
</syntaxhighlight>
<syntaxhighlight lang="nix">
## In /etc/nixos/hardware-configuration.nix:
## Create new root datasets
# zfs create -o canmount=noauto -o mountpoint=/ rpool/nixos/empty
# zfs snapshot rpool/nixos/empty@start
## Replace existing entry for / (root) with
  fileSystems."/" =
    { device = "rpool/nixos/empty";
      fsType = "zfs"; options = [ "zfsutil" "noatime" "X-mount.mkdir" ];
    };
## Mount old root at /altroot
## noatime option is used for better performance
  fileSystems."/altroot" =
    { device = "rpool/nixos/root";
      fsType = "zfs"; options = [ "zfsutil" "noatime" "X-mount.mkdir" ];
      neededForBoot = true;
    };
## /nix/ is needed for the system to boot, so
## bind mount it from old root
  fileSystems."/nix" = {
    device = "/altroot/nix";
    fsType = "none";
    options = [ "bind" "X-mount.mkdir" ];
  };
## /etc/nixos/ stores system configuration
  fileSystems."/etc/nixos" = {
    device = "/altroot/etc/nixos";
    fsType = "none";
    options = [ "bind" "X-mount.mkdir" ];
  };
</syntaxhighlight>
</syntaxhighlight>


Line 140: Line 84:


See <code>services.sanoid</code> section in <code>man configuration.nix</code>.
See <code>services.sanoid</code> section in <code>man configuration.nix</code>.
== Remote unlock ==
=== Unlock encrypted zfs via ssh on boot ===
{{note|As of 22.05, rebuilding your config with the below directions may result in a situation where, if you want to revert the changes, you may need to do some pretty hairy nix-store manipulation to be able to successfully rebuild, see https://github.com/NixOS/nixpkgs/issues/101462#issuecomment-1172926129}}
In case you want unlock a machine remotely (after an update), having an ssh service in initrd for the password prompt is handy:
<syntaxhighlight lang="nix">
boot = {
  initrd.network = {
    # This will use udhcp to get an ip address.
    # Make sure you have added the kernel module for your network driver to `boot.initrd.availableKernelModules`,
    # so your initrd can load it!
    # Static ip addresses might be configured using the ip argument in kernel command line:
    # https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt
    enable = true;
    ssh = {
      enable = true;
      # To prevent ssh clients from freaking out because a different host key is used,
      # a different port for ssh is useful (assuming the same host has also a regular sshd running)
      port = 2222;
      # hostKeys paths must be unquoted strings, otherwise you'll run into issues with boot.initrd.secrets
      # the keys are copied to initrd from the path specified; multiple keys can be set
      # you can generate any number of host keys using
      # `ssh-keygen -t ed25519 -N "" -f /path/to/ssh_host_ed25519_key`
      hostKeys = [ /path/to/ssh_host_rsa_key ];
      # public ssh key used for login
      authorizedKeys = [ "ssh-rsa AAAA..." ];
    };
  };
};
</syntaxhighlight>
* In order to use DHCP in the initrd, network manager must not be enabled and <syntaxhighlight lang="nix" inline>networking.useDHCP = true;</syntaxhighlight> must be set.
* If your network card isn't started, you'll need to add the according kernel module to the kernel and initrd as well, e.g. <syntaxhighlight lang="nix">
boot.kernelModules = [ "r8169" ];
boot.initrd.kernelModules = [ "r8169" ];</syntaxhighlight>
After that you can unlock your datasets using the following ssh command:
<syntaxhighlight>
ssh root@host -p 2222 "zpool import -a; zfs load-key -a && killall zfs"
</syntaxhighlight>


== NFS share ==
== NFS share ==