ZFS: Difference between revisions

imported>2r
zfs root
imported>2r
update auto-snapshot
Line 65: Line 65:
   fileSystems."/etc/nixos" = {
   fileSystems."/etc/nixos" = {
     device = "/altroot/etc/nixos";
     device = "/altroot/etc/nixos";
    fsType = "none";
    options = [ "bind" "X-mount.mkdir" ];
  };
</syntaxhighlight>
'''Optional''': stateless home directory.  This requires you to keep track of your dot files with a version control system.  Git is used here as an example.
<syntaxhighlight lang="nix">
## In /etc/nixos/configuration.nix:
## Manage home with home-manager
  environment.systemPackages = with pkgs; [
    home-manager
  ];
## Disable mutable users
  users.mutableUsers = false;
## Password hashes now need to be declared in config
## generate hash with mkpasswd -m SHA-512 -s
    users.users.myUser.initialHashedPassword = "HASH";
## New service to fix home permissions
  systemd.services.home-perm = {
    enable = true;
    description = "Fix home dir permission";
    wantedBy = [ "multi-user.target" ];
    path = [ pkgs.coreutils pkgs.git ];
    after = [ "local-fs.target" ];
    serviceConfig = {
      ExecStart = ''/bin/sh -c "git -C /home/myUser reset --hard; chown -R myUser:users /home/myUser; chmod  700 /home/myUser"'';
      User = "root";
      Type = "oneshot";
      PrivateTmp = "true";
      ProtectSystem = "full";
      WorkingDirectory = "/tmp";
    };
  };
</syntaxhighlight>
<syntaxhighlight lang="nix">
## In /etc/nixos/hardware-configuration.nix:
  fileSystems."/home/myUser" = {
    device = "none";
    fsType = "tmpfs";
    options = [ "defaults" "size=1G" "mode=755" "X-mount=mkdir" ];
  };
  fileSystems."/home/myUser/.git" = {
    device = "/altroot/home/myUser/.git";
    fsType = "none";
    options = [ "bind" "X-mount.mkdir" ];
  };
  fileSystems."/home/myUser/Downloads" = {
    device = "/altroot/home/myUser/Downloads";
    fsType = "none";
    options = [ "bind" "X-mount.mkdir" ];
  };
  fileSystems."/home/myUser/Documents" = {
    device = "/altroot/home/myUser/Documents";
     fsType = "none";
     fsType = "none";
     options = [ "bind" "X-mount.mkdir" ];
     options = [ "bind" "X-mount.mkdir" ];
Line 155: Line 93:
== Reservations ==
== Reservations ==


Since zfs is a copy-on-write filesystem even for deleting files disk space is needed. Therefore it should be avoided to run out of disk space. Luckily it is possible to reserve disk space for datasets to prevent this.
On ZFS, the performance will deteriorate significantly when more than 80% of the available space is used. To avoid this, reserve disk space beforehand.  
 
To reserve space create a new unused dataset that gets a guaranteed disk space of 1GB.
 
<syntaxhighlight lang="console">
# zfs create -o refreservation=1G -o mountpoint=none zroot/reserved
</syntaxhighlight>


where <code>zroot</code> should be replaced by a dataset in your pool.
To reserve space create a new unused dataset that gets a guaranteed disk space of 10GB.
The dataset itself should not be used. In case you would run out of space you can shrink the reservation to reclaim enough disk space to cleanup the other data from the pool:


<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
# zfs set refreservation=none zroot/reserved
# zfs create -o refreservation=10G -o mountpoint=none zroot/reserved
</syntaxhighlight>
</syntaxhighlight>


Line 178: Line 109:
== Take snapshots automatically ==
== Take snapshots automatically ==


To auto-snapshot a ZFS filesystem or a ZVol, set its <code>com.sun:auto-snapshot</code> property to <code>true</code>, like this:
See <code>services.sanoid</code> section in <code>man configuration.nix</code>.


<syntaxhighlight lang="console">
== Remote unlock ==
# zfs set com.sun:auto-snapshot=true <pool>/<fs>
=== Unlock encrypted zfs via ssh on boot ===
</syntaxhighlight>
 
(Note that by default this property will be inherited by all descendant datasets, but you can set their properties to false if you prefer.)
 
Then, to enable the auto-snapshot service, add this to your <code>configuration.nix</code>:
<syntaxhighlight lang="nix">
services.zfs.autoSnapshot.enable = true;
</syntaxhighlight>
 
And finally, run <code>nixos-rebuild switch</code> to activate the new configuration!
 
By default, the auto-snapshot service will keep the latest four 15-minute, 24 hourly, 7 daily, 4 weekly and 12 monthly snapshots.
You can globally override this configuration by setting the desired number of snapshots in your <code>configuration.nix</code>, like this:
 
<syntaxhighlight lang="nix">
services.zfs.autoSnapshot = {
  enable = true;
  frequent = 8; # keep the latest eight 15-minute snapshots (instead of four)
  monthly = 1;  # keep only one monthly snapshot (instead of twelve)
};
</syntaxhighlight>
 
You can also disable a given type of snapshots on a per-dataset basis by setting a ZFS property, like this:
 
<syntaxhighlight lang="console">
# zfs set com.sun:auto-snapshot:weekly=false <pool>/<fs>
</syntaxhighlight>
 
This would disable only weekly snapshots on the given filesystem.
 
== 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}}
{{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}}
Line 259: Line 159:
* If your network card isn't started, you'll need to add the according kernel module to the initrd as well, e.g. <syntaxhighlight lang="nix" inline>boot.initrd.kernelModules = [ "r8169" ];</syntaxhighlight>
* If your network card isn't started, you'll need to add the according kernel module to the initrd as well, e.g. <syntaxhighlight lang="nix" inline>boot.initrd.kernelModules = [ "r8169" ];</syntaxhighlight>


== Import and unlock multiple encrypted pools/dataset at boot ==
=== Import and unlock multiple encrypted pools/dataset at boot ===
If you have not only one encrypted pool/dataset but multiple ones and you want to import and unlock them at boot, so that they can be automounted using the hardware-configuration.nix, you could just amend the <code>boot.initrd.network.postCommands</code> option.
If you have not only one encrypted pool/dataset but multiple ones and you want to import and unlock them at boot, so that they can be automounted using the hardware-configuration.nix, you could just amend the <code>boot.initrd.network.postCommands</code> option.


Line 311: Line 211:
ZFS Event Daemon (zed) monitors events generated by the ZFS kernel module and runs configured tasks. It can be configured to send an email when a pool scrub is finished or a disk has failed. [https://search.nixos.org/options?query=services.zfs.zed zed options]
ZFS Event Daemon (zed) monitors events generated by the ZFS kernel module and runs configured tasks. It can be configured to send an email when a pool scrub is finished or a disk has failed. [https://search.nixos.org/options?query=services.zfs.zed zed options]


=== Alternative 1: Rebuild ZFS with Mail Support ===
=== Alternative 1: Enable Mail Notification without Re-compliation ===
The <code>zfs</code> package can be rebuilt with mail features. However, please note that this will cause Nix to recompile the entire ZFS package on the computer, and on every kernel update, which could be very time-consuming on lower-end NAS systems.
 
An alternative solution that does not involve recompliation can be found below.
 
The following override is needed as <code>zfs</code> is implicitly used in partition mounting:
 
<syntaxhighlight lang="nix">
nixpkgs.config.packageOverrides = pkgs: {
  zfsStable = pkgs.zfsStable.override { enableMail = true; };
};
</syntaxhighlight>
 
A mail sender like [[msmtp]] or [[postfix]] is required.
 
A minimal, testable ZED configuration example:
 
<syntaxhighlight lang="nix">
services.zfs.zed.enableMail = true;
services.zfs.zed.settings = {
  ZED_EMAIL_ADDR = [ "root" ];
  ZED_NOTIFY_VERBOSE = true;
};
</syntaxhighlight>
 
Above, <code>ZED_EMAIL_ADDR</code> is set to <code>root</code>, which most people will have an alias for in their mailer. You can change it to directly mail you: <code>ZED_EMAIL_ADDR = [ "you@example.com" ];</code>
 
ZED pulls in <code>mailutils</code> and runs <code>mail</code> by default, but you can override it with <code>ZED_EMAIL_PROG</code>. If using msmtp, you may need <code>ZED_EMAIL_PROG = "${pkgs.msmtp}/bin/msmtp";</code>.
 
You can customize the mail command with <code>ZED_EMAIL_OPTS</code>. For example, if your upstream mail server requires a certain FROM address: <code>ZED_EMAIL_OPTS = "-r 'noreply@example.com' -s '@SUBJECT@' @ADDRESS@";</code>
 
=== Alternative 2: Enable Mail Notification without Re-compliation ===


First, we need to configure a mail transfer agent, the program that sends email:
First, we need to configure a mail transfer agent, the program that sends email:
Line 402: Line 271:
# zpool scrub $pool
# zpool scrub $pool
</syntaxhighlight>
</syntaxhighlight>
=== Alternative 2: Rebuild ZFS with Mail Support ===
The <code>zfs</code> package can be rebuilt with mail features. However, please note that this will cause Nix to recompile the entire ZFS package on the computer, and on every kernel update, which could be very time-consuming on lower-end NAS systems.
An alternative solution that does not involve recompliation can be found above.
The following override is needed as <code>zfs</code> is implicitly used in partition mounting:
<syntaxhighlight lang="nix">
nixpkgs.config.packageOverrides = pkgs: {
  zfsStable = pkgs.zfsStable.override { enableMail = true; };
};
</syntaxhighlight>
A mail sender like [[msmtp]] or [[postfix]] is required.
A minimal, testable ZED configuration example:
<syntaxhighlight lang="nix">
services.zfs.zed.enableMail = true;
services.zfs.zed.settings = {
  ZED_EMAIL_ADDR = [ "root" ];
  ZED_NOTIFY_VERBOSE = true;
};
</syntaxhighlight>
Above, <code>ZED_EMAIL_ADDR</code> is set to <code>root</code>, which most people will have an alias for in their mailer. You can change it to directly mail you: <code>ZED_EMAIL_ADDR = [ "you@example.com" ];</code>
ZED pulls in <code>mailutils</code> and runs <code>mail</code> by default, but you can override it with <code>ZED_EMAIL_PROG</code>. If using msmtp, you may need <code>ZED_EMAIL_PROG = "${pkgs.msmtp}/bin/msmtp";</code>.
You can customize the mail command with <code>ZED_EMAIL_OPTS</code>. For example, if your upstream mail server requires a certain FROM address: <code>ZED_EMAIL_OPTS = "-r 'noreply@example.com' -s '@SUBJECT@' @ADDRESS@";</code>


[[Category:Guide]]
[[Category:Guide]]