From 9424bfd8607da65ebc0c91d4071ecce36e25b6a0 Mon Sep 17 00:00:00 2001 From: Julien Moutinho <julm@sourcephile.fr> Date: Wed, 12 May 2021 16:12:55 +0200 Subject: [PATCH] zfs: improve offline backup --- hosts/oignon/backup.nix | 24 ++++++++++++++---------- hosts/patate/backup/zfs-backup.nix | 22 +++++++++++++--------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/hosts/oignon/backup.nix b/hosts/oignon/backup.nix index 8017af6..13c8db5 100644 --- a/hosts/oignon/backup.nix +++ b/hosts/oignon/backup.nix @@ -97,8 +97,8 @@ systemd.services."zfs-local-backup-home@" = { serviceConfig = rec { Type = "oneshot"; PrivateTmp = true; - CacheDirectory = [ "zfs-usb-backup-%I" ]; - RuntimeDirectory = [ "zfs-usb-backup-%I" ]; + CacheDirectory = [ "zfs-usb-backup/%I" ]; + RuntimeDirectory = [ "zfs-usb-backup/%I" ]; User = "julm"; Group = "users"; SyslogIdentifier = "zfs-local-backup-home@%i"; @@ -114,6 +114,10 @@ systemd.services."zfs-local-backup-home@" = { ExecStart = pkgs.writeShellScript "zfs-local-backup-home" '' set -eu DESTPOOL=$1 + # sanoid is quite conservative: + # by setting hourly=24, a snapshot must be >24 hours old + # and there must been >24 total hourly snapshots, + # or nothing is pruned. install -D -m 400 /dev/stdin /tmp/sanoid/sanoid.conf <<EOF [template_remote] autoprune=true @@ -121,18 +125,18 @@ systemd.services."zfs-local-backup-home@" = { process_children_only=false [$DESTPOOL/${User}/backup/${hostName}/home] - hourly=12 + hourly=6 daily=31 - monthly=0 + monthly=3 recursive=true use_template=remote EOF set -x ${pkgs.sanoid}/bin/sanoid \ - --cache-dir /var/cache/zfs-usb-backup-"$DESTPOOL" \ + --cache-dir /var/cache/zfs-usb-backup/"$DESTPOOL" \ --configdir /tmp/sanoid \ --prune-snapshots \ - --run-dir /run/zfs-usb-backup-"$DESTPOOL" \ + --run-dir /run/zfs-usb-backup/"$DESTPOOL" \ --verbose for dataset in ${hostName}/home; do @@ -154,17 +158,17 @@ systemd.services."zfs-local-backup-home@" = { DESTPOOL=$1 set -eux # Only if the zpool still exists to avoid uninterruptible hanging - if zpool status "$DESTPOOL"; then + if zpool status -v "$DESTPOOL"; then # Scrub the zpool 1 minute (in the background) zpool scrub "$DESTPOOL" sleep 60 fi - if zpool status "$DESTPOOL"; then + while zpool status -v "$DESTPOOL"; do zpool scrub -p "$DESTPOOL" || true sleep 20 # Export the zpool (to avoid a forced import later on) - zpool export "$DESTPOOL" - fi + zpool export "$DESTPOOL" || true + done systemctl --no-block stop zfs-term@"$DESTPOOL" '' + " %I"; }; diff --git a/hosts/patate/backup/zfs-backup.nix b/hosts/patate/backup/zfs-backup.nix index 412c498..baf699e 100644 --- a/hosts/patate/backup/zfs-backup.nix +++ b/hosts/patate/backup/zfs-backup.nix @@ -61,8 +61,8 @@ systemd.services."zfs-local-backup-home@" = { serviceConfig = rec { Type = "oneshot"; PrivateTmp = true; - CacheDirectory = [ "zfs-usb-backup-%I" ]; - RuntimeDirectory = [ "zfs-usb-backup-%I" ]; + CacheDirectory = [ "zfs-usb-backup/%I" ]; + RuntimeDirectory = [ "zfs-usb-backup/%I" ]; User = "sevy"; Group = "users"; SyslogIdentifier = "zfs-local-backup-home@%i"; @@ -78,6 +78,10 @@ systemd.services."zfs-local-backup-home@" = { ExecStart = pkgs.writeShellScript "zfs-local-backup-home" '' set -eu DESTPOOL=$1 + # sanoid is quite conservative: + # by setting hourly=24, a snapshot must be >24 hours old + # and there must been >24 total hourly snapshots, + # or nothing is pruned. install -D -m 400 /dev/stdin /tmp/sanoid/sanoid.conf <<EOF [template_remote] autoprune=true @@ -87,16 +91,16 @@ systemd.services."zfs-local-backup-home@" = { [$DESTPOOL/${User}/backup/${hostName}/home] hourly=12 daily=31 - monthly=0 + monthly=6 recursive=true use_template=remote EOF set -x ${pkgs.sanoid}/bin/sanoid \ - --cache-dir /var/cache/zfs-usb-backup-"$DESTPOOL" \ + --cache-dir /var/cache/zfs-usb-backup/"$DESTPOOL" \ --configdir /tmp/sanoid \ --prune-snapshots \ - --run-dir /run/zfs-usb-backup-"$DESTPOOL" \ + --run-dir /run/zfs-usb-backup/"$DESTPOOL" \ --verbose for dataset in ${hostName}/home; do @@ -119,17 +123,17 @@ systemd.services."zfs-local-backup-home@" = { DESTPOOL=$1 set -eux # Only if the zpool still exists to avoid uninterruptible hanging - if zpool status "$DESTPOOL"; then + if zpool status -v "$DESTPOOL"; then # Scrub the zpool 1 minute (in the background) zpool scrub "$DESTPOOL" sleep 60 fi - if zpool status "$DESTPOOL"; then + while zpool status -v "$DESTPOOL"; do zpool scrub -p "$DESTPOOL" || true sleep 20 # Export the zpool (to avoid a forced import later on) - zpool export "$DESTPOOL" - fi + zpool export "$DESTPOOL" || true + done systemctl --no-block stop zfs-term@"$DESTPOOL" '' + " %I"; }; -- 2.47.2