Hi. I use the FreedomBox with btrfs, and it is configured to use snapper to take regular file system snapshots. But as you can see from <URL: https://bugs.debian.org/876514 >, this can bring down the system if the btrfs file system fill up. Could snapper be changed to restrict the amount of snapshots kept in each category based on amount of free space on the file system, to avoid filling up the disk with snapshots? It would be great if snapper also provided a way to easily figure out how much disk space a given snapshot uses. Btw, are you aware of <URL: https://tracker.debian.org/pkg/zfsnap >, which uses an interesting way to name snapshots (with timestamp and duration), which make it quite easy to administrate the snapshots from the command line. Perhaps something similar could be done by snapper?
Hi, Unfortunately, no. However, you can limit snapshots by "numbers". One btrfs guy says it's hard to do such behavior since btrfs snapshots share same blocks as those snapshot data, so not sure how to keep amount of disk by deleting old snapshots. Said above, most of snapshots share same blocks, it's hard I guess. Could you give me some examples, please?
[Hideki Yamane] Any hope to have such feature implemented, as snapper in its current form is dangerous as long as btrfs start blocking processes when the disk is full. :( One way would be to not take snapshots if df show less than X % free space. Another would be to start removing old snapshots until df show more than X % free space before doing any snapshots. The point is that for me it is better to not take snapshots than to bring down the entire service. :) A way to do this is documented in <URL: https://raw.githubusercontent.com/agronick/btrfs-size/master/btrfs-size.sh >.
Hi, I've run into the same problem. btrfs partition was full of snapper snapshots and has made the system unbootable. what about decrease default number of snapshots? I see in Debian wiki it's recommended not to have more than 12 snapshots [1]. 1. https://wiki.debian.org/Btrfs
severity 876675 important tags 876675 + patch thanks The biggest reason why snapper fills up disk with snapshots is because the number algorithm does not cleanup automatically. When apt snapshots are taken by this package's apt hooks, number algorithm is used. However, unlike timeline algorithms that are periodically cleaned up by snapperd, numeric snapshots are not (even after saying number cleanup to 'yes'). Even after configuring snapperd to keep very few apt snapshots, this still fills up the disk eventually. The solution to this part is to trigger a number cleanup after every snapshot. The fix is available as part of patch in https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=880144 . Hence, adding patch tag. Please consider accepting the simple patch to fix both bugs. Bumping priority as this as it effects all FreedomBox machines that use snapper. Thanks,
[Sunil Mohan Adapa]
I suspect you talk about the second patch in bug #880144, ie this:
diff --git a/debian/80snapper b/debian/80snapper
index 0007402..ddf1f8b 100644
--- a/debian/80snapper
+++ b/debian/80snapper
@@ -1,3 +1,3 @@
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=770938
- DPkg::Pre-Invoke { "if [ -x /usr/bin/snapper -a -e /etc/snapper/configs/root ]; then rm /var/tmp/snapper-apt || true ; snapper create -d apt -c number -t pre -p > /var/tmp/snapper-apt || true ; fi"; };
- DPkg::Post-Invoke { "if [ -x /usr/bin/snapper -a -e /var/tmp/snapper-apt ]; then snapper create -d apt -c number -t post --pre-number=`cat /var/tmp/snapper-apt` || true ; fi"; };
+ DPkg::Pre-Invoke { "if [ -e /etc/default/snapper ]; then . /etc/default/snapper; fi; if [ -x /usr/bin/snapper -a ! x$DISABLE_APT_SNAPSHOT = 'xyes' -a -e /etc/snapper/configs/root ]; then rm /var/tmp/snapper-apt || true ; snapper create -d apt -c number -t pre -p > /var/tmp/snapper-apt || true ; snapper cleanup number || true ; fi"; };
+ DPkg::Post-Invoke { "if [ -e /etc/default/snapper ]; then . /etc/default/snapper; fi; if [ -x /usr/bin/snapper -a ! x$DISABLE_APT_SNAPSHOT = 'xyes' -a -e /var/tmp/snapper-apt ]; then snapper create -d apt -c number -t post --pre-number=`cat /var/tmp/snapper-apt` || true ; snapper cleanup number || true ; fi"; };
It has already been applied in the snapper git repository. Did it
help with this issue too?
control: tags -1 -patch Hi, I've found that snapper has two useful configuration now. See https://manpages.debian.org/unstable/snapper/snapper-configs.5.en.html If it works correctly, snapper should care free space when taking a snapshot. Then, we can close this bug as avoiding full of snapshots eat your disks. Now I've confirmed that the number clean algorithm works well. I've tested it and stuck, then reset and btrfs corrupted... ;(
Its number is decided by snapper upstream, so if you have a question about it, please ask them. And I doubt whether it's true as Nicholas noted "Need to find the source for this on linux-btrfs".
Hi,
If you wish to check the diskspace used by the btrfs subvolume, you are
suppose to use qgroup thing as mentiond. That is not safe to use.
But if the objective is to avoid filling up the disk. may be abit
simpler approach may help. Let me explain.
FYI:
If the base of Btrfs is at $BTRFS_BASE, somthing like the following
should be OK as shell code. (__echo is a shell function)
The idea is set limit for minimum absolute disk size and minumum free
desk space percentage. I am testing idea with free 10% (FMIN=10) disk
space with the following code.
```
# disk size sanity check without quota consideration
BSS_STAT_TOTAL=$(stat -f -c %b "$BTRFS_BASE")
# Even on 4k block system, disk with 200 blocks is less than 1MB
if [ "$BSS_STAT_TOTAL" -le 200 ]; then
__echo 0 "Total disk size: $BSS_STAT_TOTAL blocks (too small,
minimum required 200)"
__echo 0 "skip snapshot: BASE=$BTRFS_BASE TIME=${NOW_TSTR}
TYPE=${BSS_TYPE}"
exit 1
fi
BSS_STAT_UNIT=$((BSS_STAT_TOTAL/100))
BSS_STAT_FREE=$(stat -f -c %f "$BTRFS_BASE")
BSS_FREE_UNIT=$((BSS_STAT_FREE/BSS_STAT_UNIT))
if [ "$BSS_FREE_UNIT" -le "$BSS_FMIN" ]; then
__echo 0 "Free disk space: $BSS_FREE_UNIT% (too small, minimum
required FMIN=$BSS_FMIN%)"
__echo 0 "skip snapshot: BASE=$BTRFS_BASE TIME=${NOW_TSTR}
TYPE=${BSS_TYPE}"
exit 1
else
__echo 2 "Free disk space: $BSS_FREE_UNIT% (enough, minimum
required FMIN=$BSS_FMIN%)"
fi
# make snapshot
$NOOP $SUDO mkdir -p "$BSS_DIR_BASE" >/dev/null
while [ -d "$BSS_DIR_BASE/${NOW_TSTR}.${BSS_TYPE}" ]; do
sleep "1s"
NOW_TSTR=$(date -u --iso=second)
done
__echo 2 "make snapshot: BASE=$BTRFS_BASE TIME=${NOW_TSTR}
TYPE=${BSS_TYPE}"
# shellcheck disable=SC2086
$NOOP $BSV snapshot -r "$BTRFS_BASE"
"$BSS_DIR_BASE/${NOW_TSTR}.${BSS_TYPE}"
```
(This is what I do here for my own needs here and playing with data
aging parameters.)
I think snapper can do the similar.
Hi,
If you wish to check the diskspace used by the btrfs subvolume, you are
suppose to use qgroup thing as mentiond. That is not safe to use.
But if the objective is to avoid filling up the disk. may be abit
simpler approach may help. Let me explain.
FYI:
If the base of Btrfs is at $BTRFS_BASE, somthing like the following
should be OK as shell code. (__echo is a shell function)
The idea is set limit for minimum absolute disk size and minumum free
desk space percentage. I am testing idea with free 10% (FMIN=10) disk
space with the following code.
```
# disk size sanity check without quota consideration
BSS_STAT_TOTAL=$(stat -f -c %b "$BTRFS_BASE")
# Even on 4k block system, disk with 200 blocks is less than 1MB
if [ "$BSS_STAT_TOTAL" -le 200 ]; then
__echo 0 "Total disk size: $BSS_STAT_TOTAL blocks (too small,
minimum required 200)"
__echo 0 "skip snapshot: BASE=$BTRFS_BASE TIME=${NOW_TSTR}
TYPE=${BSS_TYPE}"
exit 1
fi
BSS_STAT_UNIT=$((BSS_STAT_TOTAL/100))
BSS_STAT_FREE=$(stat -f -c %f "$BTRFS_BASE")
BSS_FREE_UNIT=$((BSS_STAT_FREE/BSS_STAT_UNIT))
if [ "$BSS_FREE_UNIT" -le "$BSS_FMIN" ]; then
__echo 0 "Free disk space: $BSS_FREE_UNIT% (too small, minimum
required FMIN=$BSS_FMIN%)"
__echo 0 "skip snapshot: BASE=$BTRFS_BASE TIME=${NOW_TSTR}
TYPE=${BSS_TYPE}"
exit 1
else
__echo 2 "Free disk space: $BSS_FREE_UNIT% (enough, minimum
required FMIN=$BSS_FMIN%)"
fi
# make snapshot
$NOOP $SUDO mkdir -p "$BSS_DIR_BASE" >/dev/null
while [ -d "$BSS_DIR_BASE/${NOW_TSTR}.${BSS_TYPE}" ]; do
sleep "1s"
NOW_TSTR=$(date -u --iso=second)
done
__echo 2 "make snapshot: BASE=$BTRFS_BASE TIME=${NOW_TSTR}
TYPE=${BSS_TYPE}"
# shellcheck disable=SC2086
$NOOP $BSV snapshot -r "$BTRFS_BASE"
"$BSS_DIR_BASE/${NOW_TSTR}.${BSS_TYPE}"
```
(This is what I do here for my own needs here and playing with data
aging parameters.)
I think snapper can do the similar.