An exercise on ZFS clones
This is an exercise I made, just to remind myself of how snapshots and clones work in ZFS. Also, how to properly get rid of them when you’re short of diskspace, or the dataset listing is too long, etc.
First, we have the shell script that demonstrates the rise and fall of the initial dataset, and the intermediary snapshots and clones.
#!/bin/sh set -x zfs create zroot/clones zfs list -rt all zroot/clones zfs create zroot/clones/a zfs list -rt all zroot/clones zfs snapshot zroot/clones/a@b zfs list -rt all zroot/clones zfs clone zroot/clones/a@b zroot/clones/b zfs list -rt all zroot/clones zfs snapshot zroot/clones/b@c zfs list -rt all zroot/clones zfs clone zroot/clones/b@c zroot/clones/c zfs list -rt all zroot/clones zfs snapshot zroot/clones/c@d zfs list -rt all zroot/clones zfs clone zroot/clones/c@d zroot/clones/d zfs list -rt all zroot/clones zfs snapshot zroot/clones/d@e zfs list -rt all zroot/clones zfs clone zroot/clones/d@e zroot/clones/e zfs list -rt all zroot/clones zfs promote zroot/clones/b zfs list -rt all zroot/clones zfs promote zroot/clones/c zfs list -rt all zroot/clones zfs promote zroot/clones/d zfs list -rt all zroot/clones zfs promote zroot/clones/e zfs list -rt all zroot/clones zfs destroy -v zroot/clones/a zfs list -rt all zroot/clones zfs destroy -v zroot/clones/b zfs list -rt all zroot/clones zfs destroy -v zroot/clones/c zfs list -rt all zroot/clones zfs destroy -v zroot/clones/d zfs list -rt all zroot/clones zfs destroy -v zroot/clones/e@b zfs list -rt all zroot/clones zfs destroy -v zroot/clones/e@c zfs list -rt all zroot/clones zfs destroy -v zroot/clones/e@d zfs list -rt all zroot/clones zfs destroy -v zroot/clones/e@e zfs list -rt all zroot/clones zfs destroy -v zroot/clones/e zfs list -rt all zroot/clones zfs destroy -v zroot/clones
Here we go into more detail. First, let’s create a sandbox to play in.
zfs create zroot/clones zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 96K 15.4G 96K legacy
Now, we create the initial dataset. This would typically be the dataset created by FreeBSD Installer, e.g. zroot/ROOT/default
.
zfs create zroot/clones/a zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 192K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy
It’s time to create a snapshot of the current dataset.
zfs snapshot zroot/clones/a@b zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 192K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K -
Next, we create a clone with the previous snapshot as its origin.
zfs clone zroot/clones/a@b zroot/clones/b zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 200K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K - zroot/clones/b 8K 15.4G 96K legacy
Let’s create a snapshot of the first clone.
zfs snapshot zroot/clones/b@c zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 200K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K - zroot/clones/b 8K 15.4G 96K legacy zroot/clones/b@c 0 - 96K -
This is our second clone.
zfs clone zroot/clones/b@c zroot/clones/c zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 208K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K - zroot/clones/b 8K 15.4G 96K legacy zroot/clones/b@c 0 - 96K - zroot/clones/c 8K 15.4G 96K legacy
Another snapshot.
zfs snapshot zroot/clones/c@d zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 208K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K - zroot/clones/b 8K 15.4G 96K legacy zroot/clones/b@c 0 - 96K - zroot/clones/c 8K 15.4G 96K legacy zroot/clones/c@d 0 - 96K -
Our third clone.
zfs clone zroot/clones/c@d zroot/clones/d zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 216K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K - zroot/clones/b 8K 15.4G 96K legacy zroot/clones/b@c 0 - 96K - zroot/clones/c 8K 15.4G 96K legacy zroot/clones/c@d 0 - 96K - zroot/clones/d 8K 15.4G 96K legacy
The last snapshot in this exercise.
zfs snapshot zroot/clones/d@e zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 216K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K - zroot/clones/b 8K 15.4G 96K legacy zroot/clones/b@c 0 - 96K - zroot/clones/c 8K 15.4G 96K legacy zroot/clones/c@d 0 - 96K - zroot/clones/d 8K 15.4G 96K legacy zroot/clones/d@e 0 - 96K -
The last clone in this exercise.
zfs clone zroot/clones/d@e zroot/clones/e zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/a 96K 15.4G 96K legacy zroot/clones/a@b 0 - 96K - zroot/clones/b 8K 15.4G 96K legacy zroot/clones/b@c 0 - 96K - zroot/clones/c 8K 15.4G 96K legacy zroot/clones/c@d 0 - 96K - zroot/clones/d 8K 15.4G 96K legacy zroot/clones/d@e 0 - 96K - zroot/clones/e 8K 15.4G 96K legacy
Now, we want to clean up this mess, with the goal of having only zroot/clones/e
. We start by promoting the first clone created. Notice the initial snapshot now belongs to the first clone.
zfs promote zroot/clones/b zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/a 0 15.4G 96K legacy zroot/clones/b 104K 15.4G 96K legacy zroot/clones/b@b 8K - 96K - zroot/clones/b@c 0 - 96K - zroot/clones/c 8K 15.4G 96K legacy zroot/clones/c@d 0 - 96K - zroot/clones/d 8K 15.4G 96K legacy zroot/clones/d@e 0 - 96K - zroot/clones/e 8K 15.4G 96K legacy
You can reverse the promotion of zroot/clones/b
by promoting zroot/clones/a
, the snapshot zroot/clones/b@b
becomes zroot/clones/a@b
. At this point we could destroy zroot/clones/a
and zroot/clones/b@b
, in that order, and gain some diskspace. We’ll continue until zroot/clones/e
is an independent dataset.
Let’s promote the second clone. The snapshots keep bubbling downwards.
zfs promote zroot/clones/c zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/a 0 15.4G 96K legacy zroot/clones/b 0 15.4G 96K legacy zroot/clones/c 112K 15.4G 96K legacy zroot/clones/c@b 8K - 96K - zroot/clones/c@c 8K - 96K - zroot/clones/c@d 0 - 96K - zroot/clones/d 8K 15.4G 96K legacy zroot/clones/d@e 0 - 96K - zroot/clones/e 8K 15.4G 96K legacy
Now we promote the third clone. Bubble, bubble, bubble, …
zfs promote zroot/clones/d zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/a 0 15.4G 96K legacy zroot/clones/b 0 15.4G 96K legacy zroot/clones/c 0 15.4G 96K legacy zroot/clones/d 120K 15.4G 96K legacy zroot/clones/d@b 8K - 96K - zroot/clones/d@c 8K - 96K - zroot/clones/d@d 8K - 96K - zroot/clones/d@e 0 - 96K - zroot/clones/e 8K 15.4G 96K legacy
Here we promote the fourth and last clone. Notice that all snapshots now belong to the newest clone.
zfs promote zroot/clones/e zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/a 0 15.4G 96K legacy zroot/clones/b 0 15.4G 96K legacy zroot/clones/c 0 15.4G 96K legacy zroot/clones/d 0 15.4G 96K legacy zroot/clones/e 128K 15.4G 96K legacy zroot/clones/e@b 8K - 96K - zroot/clones/e@c 8K - 96K - zroot/clones/e@d 8K - 96K - zroot/clones/e@e 8K - 96K -
It’s time to get rid of the initial dataset.
zfs destroy -v zroot/clones/a will destroy zroot/clones/a zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/b 0 15.4G 96K legacy zroot/clones/c 0 15.4G 96K legacy zroot/clones/d 0 15.4G 96K legacy zroot/clones/e 128K 15.4G 96K legacy zroot/clones/e@b 8K - 96K - zroot/clones/e@c 8K - 96K - zroot/clones/e@d 8K - 96K - zroot/clones/e@e 8K - 96K -
Here goes the first clone.
zfs destroy -v zroot/clones/b will destroy zroot/clones/b zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/c 0 15.4G 96K legacy zroot/clones/d 0 15.4G 96K legacy zroot/clones/e 128K 15.4G 96K legacy zroot/clones/e@b 8K - 96K - zroot/clones/e@c 8K - 96K - zroot/clones/e@d 8K - 96K - zroot/clones/e@e 8K - 96K -
Now we rid us of the second clone.
zfs destroy -v zroot/clones/c will destroy zroot/clones/c zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/d 0 15.4G 96K legacy zroot/clones/e 128K 15.4G 96K legacy zroot/clones/e@b 8K - 96K - zroot/clones/e@c 8K - 96K - zroot/clones/e@d 8K - 96K - zroot/clones/e@e 8K - 96K -
And the third clone.
zfs destroy -v zroot/clones/d will destroy zroot/clones/d zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 224K 15.4G 96K legacy zroot/clones/e 128K 15.4G 96K legacy zroot/clones/e@b 8K - 96K - zroot/clones/e@c 8K - 96K - zroot/clones/e@d 8K - 96K - zroot/clones/e@e 8K - 96K -
To really reclaim disk space, the snapshots will have to go. Off with the first snapshot.
zfs destroy -v zroot/clones/e@b will destroy zroot/clones/e@b will reclaim 8K zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 216K 15.4G 96K legacy zroot/clones/e 120K 15.4G 96K legacy zroot/clones/e@c 8K - 96K - zroot/clones/e@d 8K - 96K - zroot/clones/e@e 8K - 96K -
Now the second snapshot.
zfs destroy -v zroot/clones/e@c will destroy zroot/clones/e@c will reclaim 8K zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 208K 15.4G 96K legacy zroot/clones/e 112K 15.4G 96K legacy zroot/clones/e@d 8K - 96K - zroot/clones/e@e 8K - 96K -
The third snapshot.
zfs destroy -v zroot/clones/e@d will destroy zroot/clones/e@d will reclaim 8K zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 200K 15.4G 96K legacy zroot/clones/e 104K 15.4G 96K legacy zroot/clones/e@e 8K - 96K -
And finally the fourth and last snapshot.
zfs destroy -v zroot/clones/e@e will destroy zroot/clones/e@e will reclaim 8K zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 192K 15.4G 96K legacy zroot/clones/e 96K 15.4G 96K legacy
As part of this exercise, we destroy the newest clone, which is now a truly independent dataset.
zfs destroy -v zroot/clones/e will destroy zroot/clones/e zfs list -rt all zroot/clones NAME USED AVAIL REFER MOUNTPOINT zroot/clones 96K 15.4G 96K legacy
Let’s get rid of the sandbox as well.
zfs destroy -v zroot/clones will destroy zroot/clones
Thank you, and good night.