zfsonlinux / zfs-auto-snapshot

ZFS Automatic Snapshot Service for Linux
GNU General Public License v2.0
848 stars 244 forks source link

Auto snapshot keep applies to ALL labels. Restrict to only specified labels is provided #21

Open ArakniD opened 10 years ago

ArakniD commented 10 years ago

The script would keep only the number of snapshots specified by the command line, always, applying to all labels.

I have labels such that;

Monthly = zfs-auto-snap_01 Daily = zfs-auto-snap_02

etc.

This is so Windows can view ALL snapshots because it decodes the DTS with SMB config of

vfs objects = shadowcopy2 shadow: snapdir = .zfs/snapshot shadow: sort = desc shadow: format = zfs-auto-snap%S-%Y-%m-%d-%H%M shadow: localtime = yes

new line below.

SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -o name -s name|grep $opt_prefix${opt_label:+$opt_sep$opt_label} |awk '{ print substr( $0, length($0) - 14, length($0) ) " " $0}' |sort -r -k1,1 -k2,2|awk '{ print substr( $0, 17, length($0) )}') \

With this mod, I can set-up to keep 6 monthly's, 4 weekly, 7 days, and then 4 hourly's for 2 days etc..

ljluestc commented 1 year ago
#!/bin/bash

filesystem="pool/dataset"  # Replace with your ZFS filesystem
desired_snapshots=("Monthly:6" "Daily:7")  # Replace with your desired snapshot counts per label

# Function to delete excessive snapshots for a given label
delete_excessive_snapshots() {
  local label=$1
  local count=$2

  # Get the snapshots for the specified label
  snapshots=$(zfs list -H -t snapshot -o name -s name "$filesystem" | grep "$label")

  # Check if the number of snapshots exceeds the desired count
  snapshot_count=$(echo "$snapshots" | wc -l)
  if ((snapshot_count > count)); then
    # Calculate the number of snapshots to delete
    delete_count=$((snapshot_count - count))

    # Delete the excessive snapshots
    echo "Deleting $delete_count snapshots for label $label:"
    echo "$snapshots" | head -n $delete_count | xargs -r -d '\n' zfs destroy
  else
    echo "No excessive snapshots found for label $label."
  fi
}

# Iterate over the desired snapshot counts
for desired_snapshot in "${desired_snapshots[@]}"; do
  label=$(echo "$desired_snapshot" | cut -d ':' -f 1)
  count=$(echo "$desired_snapshot" | cut -d ':' -f 2)
  delete_excessive_snapshots "$label" "$count"
done