diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 80aec1bba0f..05fd160f20b 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -12,6 +12,7 @@ let
cfgSpl = config.boot.spl;
cfgZfs = config.boot.zfs;
cfgSnapshots = config.services.zfs.autoSnapshot;
+ cfgSnapFlags = cfgSnapshots.flags;
inInitrd = any (fs: fs == "zfs") config.boot.initrd.supportedFilesystems;
inSystem = any (fs: fs == "zfs") config.boot.supportedFilesystems;
@@ -45,6 +46,8 @@ let
dataPools = unique (filter (pool: !(elem pool rootPools)) allPools);
+ snapshotNames = [ "frequent" "hourly" "daily" "weekly" "monthly" ];
+
in
{
@@ -139,6 +142,25 @@ in
'';
};
+ flags = mkOption {
+ default = "-k -p";
+ example = "-k -p --utc";
+ type = types.str;
+ description = ''
+ Flags to pass to the zfs-auto-snapshot command.
+
+ Run zfs-auto-snapshot (without any arguments) to
+ see available flags.
+
+ If it's not too inconvenient for snapshots to have timestamps in UTC,
+ it is suggested that you append --utc to the list
+ of default options (see example).
+
+ Otherwise, snapshot names can cause name conflicts or apparent time
+ reversals due to daylight savings, timezone or other date/time changes.
+ '';
+ };
+
frequent = mkOption {
default = 4;
type = types.int;
@@ -237,7 +259,9 @@ in
environment.etc."zfs/zed.d".source = "${zfsUserPkg}/etc/zfs/zed.d/*";
system.fsPackages = [ zfsUserPkg ]; # XXX: needed? zfs doesn't have (need) a fsck
- environment.systemPackages = [ zfsUserPkg ];
+ environment.systemPackages = [ zfsUserPkg ]
+ ++ optional enableAutoSnapshots autosnapPkg; # so the user can run the command to see flags
+
services.udev.packages = [ zfsUserPkg ]; # to hook zvol naming, etc.
systemd.packages = [ zfsUserPkg ];
@@ -305,60 +329,41 @@ in
})
(mkIf enableAutoSnapshots {
- systemd.services."zfs-snapshot-frequent" = {
- description = "ZFS auto-snapshotting every 15 mins";
- after = [ "zfs-import.target" ];
- serviceConfig = {
- Type = "oneshot";
- ExecStart = "${zfsAutoSnap} frequent ${toString cfgSnapshots.frequent}";
- };
- restartIfChanged = false;
- startAt = "*:15,30,45";
- };
+ systemd.services = let
+ descr = name: if name == "frequent" then "15 mins"
+ else if name == "hourly" then "hour"
+ else if name == "daily" then "day"
+ else if name == "weekly" then "week"
+ else if name == "monthly" then "month"
+ else throw "unknown snapshot name";
+ numSnapshots = name: builtins.getAttr name cfgSnapshots;
+ in builtins.listToAttrs (map (snapName:
+ {
+ name = "zfs-snapshot-${snapName}";
+ value = {
+ description = "ZFS auto-snapshotting every ${descr snapName}";
+ after = [ "zfs-import.target" ];
+ serviceConfig = {
+ Type = "oneshot";
+ ExecStart = "${zfsAutoSnap} ${cfgSnapFlags} ${snapName} ${toString (numSnapshots snapName)}";
+ };
+ restartIfChanged = false;
+ };
+ }) snapshotNames);
- systemd.services."zfs-snapshot-hourly" = {
- description = "ZFS auto-snapshotting every hour";
- after = [ "zfs-import.target" ];
- serviceConfig = {
- Type = "oneshot";
- ExecStart = "${zfsAutoSnap} hourly ${toString cfgSnapshots.hourly}";
- };
- restartIfChanged = false;
- startAt = "hourly";
- };
-
- systemd.services."zfs-snapshot-daily" = {
- description = "ZFS auto-snapshotting every day";
- after = [ "zfs-import.target" ];
- serviceConfig = {
- Type = "oneshot";
- ExecStart = "${zfsAutoSnap} daily ${toString cfgSnapshots.daily}";
- };
- restartIfChanged = false;
- startAt = "daily";
- };
-
- systemd.services."zfs-snapshot-weekly" = {
- description = "ZFS auto-snapshotting every week";
- after = [ "zfs-import.target" ];
- serviceConfig = {
- Type = "oneshot";
- ExecStart = "${zfsAutoSnap} weekly ${toString cfgSnapshots.weekly}";
- };
- restartIfChanged = false;
- startAt = "weekly";
- };
-
- systemd.services."zfs-snapshot-monthly" = {
- description = "ZFS auto-snapshotting every month";
- after = [ "zfs-import.target" ];
- serviceConfig = {
- Type = "oneshot";
- ExecStart = "${zfsAutoSnap} monthly ${toString cfgSnapshots.monthly}";
- };
- restartIfChanged = false;
- startAt = "monthly";
- };
+ systemd.timers = let
+ timer = name: if name == "frequent" then "*:15,30,45" else name;
+ in builtins.listToAttrs (map (snapName:
+ {
+ name = "zfs-snapshot-${snapName}";
+ value = {
+ wantedBy = [ "timers.target" ];
+ timerConfig = {
+ OnCalendar = timer snapName;
+ Persistent = "yes";
+ };
+ };
+ }) snapshotNames);
})
];
}