ZFS snapshot renames failing after upgrade to 9.2

krichy at tvnetwork.hu krichy at tvnetwork.hu
Fri Dec 20 09:19:38 UTC 2013


Dear Gerrit,

It is not a solution, but I use different snapshot handling mechanisms. I 
wrote a simple script which handles that, and the snapshots are named by 
its creation timestamp. I think it is more usable to see that when that 
snapshot was exactly taken, and the script thus only does snapshot 
creation, and deletion, no renames.

That scripts only limitation is that it is planned to run hourly, creating 
hourly snapshots, and when run again, it queries the existing one's list, 
and decides which to keep or remove. Thus you have to run it hourly in 
cron like:
# crontab -l
0 *     * * *   /usr/local/sbin/zfs-snapshot

Regards,


Kojedzinszky Richard
Euronet Magyarorszag Informatikai Zrt.

On Fri, 20 Dec 2013, Gerrit Kühn wrote:

> Date: Fri, 20 Dec 2013 10:05:22 +0100
> From: Gerrit Kühn <gerrit.kuehn at aei.mpg.de>
> To: krichy at tvnetwork.hu
> Cc: freebsd-fs at freebsd.org
> Subject: Re: ZFS snapshot renames failing after upgrade to 9.2
> 
> On Thu, 19 Dec 2013 20:08:22 +0100 (CET) krichy at tvnetwork.hu wrote about
> Re: ZFS snapshot renames failing after upgrade to 9.2:
>
> KH> So a simple renaming can cause your system to hang?
>
> No, it does not hang completely.
> Just the snapshots become unusable. This night, it happened again:
>
> ---
> root at shapeshifter:~ # ll /tank/git/.zfs/snapshot/
> ls: daily.6: Device busy
> total 33
> drwxr-xr-x  12 211   211    25 Dec 19 09:18 daily.0/
> drwxr-xr-x  12 211   211    25 Dec 19 00:00 daily.1/
> drwxr-xr-x  12 211   211    24 Dec 18 00:00 daily.2/
> drwxr-xr-x  12 211   211    24 Dec 17 00:00 daily.3/
> drwxr-xr-x  12 211   211    24 Dec 16 00:00 daily.4/
> drwxr-xr-x  12 211   211    24 Dec 14 00:00 daily.5/
> drwxr-xr-x  12 211   211    24 Dec 15 00:00 weekly.0/
> drwxr-xr-x  12 211   211    24 Dec  8 00:00 weekly.1/
> drwxr-xr-x  12 211   211    24 Dec  1 00:00 weekly.2/
> drwxr-xr-x  12 211   211    24 Nov 17 00:00 weekly.3/
> drwxr-xr-x  12 211   211    24 Nov 10 00:00 weekly.4/
> drwxr-xr-x   2 root  wheel   3 Oct 20 00:00 weekly.5/
> drwxr-xr-x   2 root  wheel   3 Oct  6 00:00 weekly.6/
> ---
>
> root at shapeshifter:~ # zfs list -r -t snapshot -o
> name,creation,used,referenced tank/git NAME
> CREATION                USED  REFER tank/git at weekly.6  Sun Oct  6  0:00
> 2013  42.6K  62.8K tank/git at weekly.5  Sun Oct 20  0:00 2013  42.6K  62.8K
> tank/git at weekly.4  Sun Nov 10  0:00 2013  29.5M   146G
> tank/git at weekly.3  Sun Nov 17  0:00 2013  27.1M   146G
> tank/git at weekly.2  Sun Dec  1  0:00 2013  26.3M   146G
> tank/git at weekly.1  Sun Dec  8  0:00 2013  27.3M   146G
> tank/git at daily.6   Sat Dec 14  0:00 2013  26.5M   147G
> tank/git at weekly.0  Sun Dec 15  0:00 2013  25.2M   147G
> tank/git at daily.5   Mon Dec 16  0:00 2013  24.7M   147G
> tank/git at daily.4   Tue Dec 17  0:00 2013  24.9M   147G
> tank/git at daily.3   Wed Dec 18  0:00 2013  25.7M   147G
> tank/git at daily.2   Thu Dec 19  0:00 2013  25.8M   147G
> tank/git at daily.1   Thu Dec 19  9:19 2013  25.0M   147G
> tank/git at daily.0   Fri Dec 20  0:00 2013  26.8M   147G
> ---
>
>
> As you can see, the snapshot rotating got stuck somewhere. What is
> displayed under .zfs/snapshot does not reflect what zfs is really seeing:
> daily.6 is inaccessible, and the rotation that happened so far is not
> reflected under .zfs/snapshot, either.
>
>
> cu
>  Gerrit
>
-------------- next part --------------
#!/bin/sh

unset LANG
export PATH=/bin:/sbin:/usr/bin:/usr/sbin

# configuration

datasets="root/root pool/home pool/usr"

hourly_keep=168
daily_keep=90
weekly_keep=106

# override dataset-specific keep times
root_root_hourly_keep=48
root_root_daily_keep=30
root_root_weekly_keep=8

# configuration ends

stamp=$(date +%Y%m%d%H00)

ee ()
{
	logger -t "zfs-snapshot" "executing $@"
	eval "$@"
}

get_keep ()
{
	local dset="$1"
	local period="$2"
	local r

	eval "r=\$$(echo "$dset" | sed -e "s#[/-]#_#g")_${period}_keep"
	if [ -z "$r" ]; then
		eval "r=\$${period}_keep"
	fi

	echo "$r"
}

for set in $datasets ; do
	sn="$set at auto-$stamp"
	ee zfs snapshot "$sn"
done

prev=
zfs list -t snapshot -H -o name -S name | grep -E "@auto-[0-9]{12}$" | while read name ; do
	dset=${name%@*}
	stamp=${name#*auto-}

	if [ "$dset" != "$prev" ] ; then
		h=$(get_keep "$dset" hourly)
		d=$(get_keep "$dset" daily)
		w=$(get_keep "$dset" weekly)
		prev="$dset"
	fi

	keep=0

	if [ $(date -j $stamp +%w%H%M) = 00000 ] ; then
		if [ $w -gt 0 ] ; then
			w=$((w - 1))
			keep=1
		fi
	fi

	if [ $(date -j $stamp +%H%M) = 0000 ] ; then
		if [ $d -gt 0 ] ; then
			d=$((d - 1))
			keep=1
		fi
	fi

	if [ $h -gt 0 ] ; then
		h=$((h - 1))
		keep=1
	fi

	if [ $keep -eq 0 ]; then
		ee zfs destroy "$name"
	fi
done


More information about the freebsd-fs mailing list