7

Question

Already I can check each snapshot of a filesystem individually, manually.

I would prefer to check all at once (all with a single command or script). Please:

  • can that be done with a script?

The answer should be good for file systems with a space within the name.

Background

From the man page for zfs(8):

zfs holds [-H] [-r] snapshot…

… -r Specifies that a hold with the given tag is applied recursively to the snapshots of all descendent file systems.


I wondered whether recent snapshots are treated as descendants of an older snapshot. No:

Last login: Sat Dec  8 09:02:26 on ttys003
macbookpro08-centrim:~ gjp22$ zfs holds -r gjp22@2012-12-08-081957
NAME                     TAG  TIMESTAMP
macbookpro08-centrim:~ gjp22$ zfs holds -r gjp22@2012-10-28-212255
NAME                     TAG                                           TIMESTAMP
gjp22@2012-10-28-212255  problem with LocalStorage for WOT for Safari  Mon Oct 29  6:44 2012
macbookpro08-centrim:~ gjp22$ zfs hold experiment gjp22@2012-12-08-081957
macbookpro08-centrim:~ gjp22$ zfs holds -r gjp22@2012-10-28-212255
NAME                     TAG                                           TIMESTAMP
gjp22@2012-10-28-212255  problem with LocalStorage for WOT for Safari  Mon Oct 29  6:44 2012
macbookpro08-centrim:~ gjp22$ zfs holds -r gjp22@2012-12-08-081957
NAME                     TAG         TIMESTAMP
gjp22@2012-12-08-081957  experiment  Sat Dec  8  9:04 2012
macbookpro08-centrim:~ gjp22$ zfs holds -r gjp22@2012-10-28-212255
NAME                     TAG                                           TIMESTAMP
gjp22@2012-10-28-212255  problem with LocalStorage for WOT for Safari  Mon Oct 29  6:44 2012
macbookpro08-centrim:~ gjp22$ 

Clarification

I do not plan to combine both checks and destruction in a single command or script. This question is essentially about the checks.

Graham Perrin
  • 635
  • 2
  • 10
  • 24

4 Answers4

9

Not sure about how this looked back in 2012 but now you can check the userrefs property:

zfs get userrefs

To list all holds in all pools:

zfs get -Ht snapshot userrefs | grep -v $'\t'0 | cut -d $'\t' -f 1 | tr '\n' '\0' | xargs -0 zfs holds

dermetfan
  • 206
  • 2
  • 6
  • I love this answer (an upvote from me) but it's not _good for file systems with a space within the name_. Tested: `FreeBSD 12.0-CURRENT #0 r320869: Mon Jul 10 13:57:55 UTC 2017 root@releng3.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC` – Graham Perrin Oct 07 '17 at 12:37
  • 2
    You're right! Edited to work with spaces. – dermetfan Oct 08 '17 at 23:11
  • Superb! https://pastebin.com/BYrA0cS4 and now … on to [#65 Remove all ZFS snapshots](https://web.archive.org/web/20160901110510/http://zackreed.me:80/articles/65-remove-all-zfs-snapshots) in the Internet Archive Wayback Machine … – Graham Perrin Oct 29 '17 at 18:15
  • `zfs get -Ht snapshot -o name userrefs | xargs zfs holds` is far simpler 5 more years later. – alaricljs Jan 25 '23 at 00:32
1

The following command will show all snapshots of [pool] (<-replace this with your pool name) that have holds

zfs list -H -o name -t snapshot -r pool | xargs -n1 zfs holds -H

the properties will be listed as property:stuff

with that information we can free the snapshots..

zfs list -H -o name -t snapshot -r pool | xargs -n1 zfs holds -H | awk '{print $1}' | xargs -n1 zfs release property:stuff

(replace 'property:stuff' with whatever is holding your dataset)

..and finally delete them

zfs destroy -r [pool]/[dataset][@snapshot]
efnats
  • 11
  • 2
1

For a pool with multiple file systems

zfs list -H -r -d 1 -t snapshot -o name nameoffilesystematroot | xargs -n1 zfs holds -H -r

Credit to calmh in irc://irc.freenode.net/#zfs but I'm not sure whether the syntax needs a little more work.

For me, with a simple file system hierarchy (only one child) and relatively few snapshots (currently seventeen of the child), the command seems to not reach a conclusion. Example:

macbookpro08-centrim:~ gjp22$ zfs list -H -r -d 1 -t snapshot -o name gjp22 | xargs zfs holds -r
load: 4.94  cmd: zfs 39152 running 17.80u 112.52s
load: 3.73  cmd: zfs 39152 running 55.01u 349.29s
load: 3.15  cmd: zfs 39152 running 167.48u 1061.47s
load: 4.59  cmd: zfs 39152 running 267.57u 1697.49s
load: 5.19  cmd: zfs 39152 running 372.19u 2355.99s
load: 5.29  cmd: zfs 39152 running 432.89u 2736.79s

Borrowing from the other answer, with attention to the child file system alone:

macbookpro08-centrim:~ gjp22$ zfs list -H -r -d 1 -t snapshot -o name gjp22/intrigue | xargs zfs holds
NAME                              TAG  TIMESTAMP
macbookpro08-centrim:~ gjp22$ 

– and that output is almost immediate.

ZFS here is ZEVO Community Edition 1.1.1.

Graham Perrin
  • 635
  • 2
  • 10
  • 24
1

For a pool with a single file system

zfs list -H -r -d 1 -t snapshot -o name nameoffilesystem | xargs zfs holds

– that is, without -r recursion to the right of the pipe.

Credit to calmh in irc://irc.freenode.net/#zfs

Working example

For a file system with no space in its name:

macbookpro08-centrim:~ gjp22$ zfs list -H -r -d 1 -t snapshot -o name gjp22 | xargs zfs holds
load: 4.82  cmd: zfs 43038 running 0.59u 3.28s
NAME                     TAG                                           TIMESTAMP
gjp22@2012-10-28-212255  problem with LocalStorage for WOT for Safari  Mon Oct 29  6:44 2012
gjp22@2012-12-08-081957  experiment                                    Sat Dec  8  9:04 2012

There was one Control-T to see how things were running.

For completeness, I should state that there is a child of gjp22. But I guess that this example (without attention to descendants) does prove the effectiveness of the command.

Non-working examples

For a file system named Pocket Time Machine (spaces within its name), neither of the following commands succeeds:

zfs list -H -r -d 1 -t snapshot -o name "tall/backups/zhandy/Pocket Time Machine" | xargs zfs holds

zfs list -H -r -d 1 -t snapshot -o name tall/backups/zhandy/Pocket\ Time\ Machine | xargs zfs holds

Output:

'tall/backups/zhandy/Pocket' is not a snapshot
'Time' is not a snapshot
cannot open 'tall/backups/zhandy/Pocket': dataset does not exist
cannot open 'Time': dataset does not exist
cannot open 'Machine@2012-09-18-210251': dataset does not exist
cannot open 'tall/backups/zhandy/Pocket': dataset does not exist
cannot open 'Time': dataset does not exist
cannot open 'Machine@2012-09-23-0330': dataset does not exist

… and so on.

This is implicitly a question within an answer, sorry … someone with good command line knowledge (not me) might be able to smarten this answer without me spinning off to a separate question. I'll seek advice in chat.

Graham Perrin
  • 635
  • 2
  • 10
  • 24
  • Discussion of this question and its current answers in The Comms Room: http://chat.stackexchange.com/transcript/message/7189404#7189404 – Graham Perrin Dec 08 '12 at 16:28
  • In Super User: [scripting to allow for white space (in the name of a ZFS dataset)](http://superuser.com/q/528942/84988) – Graham Perrin Jan 14 '13 at 09:26