Skip to content

Instantly share code, notes, and snippets.

@hololeap
Last active October 2, 2021 20:33
Show Gist options
  • Save hololeap/8a47c513d4a489d184d956755075d261 to your computer and use it in GitHub Desktop.
Save hololeap/8a47c513d4a489d184d956755075d261 to your computer and use it in GitHub Desktop.
Script to conditionally run `btrfs balance`, suitable as a cron job
#!/bin/bash
allocated_threshold="95" # Don't run balance if less than this much is allocated (percentage)
fs="/"
# The limit (in chunks) is set to be:
# 75% of unused allocated data (in GiB), rounded up to nearest integer
# This may need to be adjusted depending on the setup
balance_awk_formula='{printf("-dlimit=%d\n",($1 - $2) * 0.75 + 1)}'
unallocated_awk_formula='{printf("%d\n",$2 / $1 * 100)}'
df_sed_expr='s/Data,\s+\w+:\s+total=([0-9.]+)GiB,\s+used=([0-9.]+)GiB/\1 \2/p'
show_sed_expr='s/.*devid.*size\s+([0-9.]+)GiB\s+used\s+([0-9.]+)GiB.*/\1 \2/p'
btrfs="/sbin/btrfs"
awk="/usr/bin/awk"
sed=(/bin/sed -rn -e)
btrfs_df=($btrfs filesystem df --gbytes $fs)
btrfs_show=($btrfs filesystem show --gbytes $fs)
btrfs_balance=($btrfs balance start --enqueue)
allocated_percentage() {
total="$1"
allocated="$2"
echo "$total" "$allocated" | $awk "$unallocated_awk_formula"
}
balance_filter() {
allocated="$1"
used="$2"
echo "$allocated" "$used" | $awk "$balance_awk_formula"
}
df_nums() {
"${btrfs_df[@]}" | "${sed[@]}" "$df_sed_expr"
}
show_nums() {
"${btrfs_show[@]}" | "${sed[@]}" "$show_sed_expr"
}
if [[ $(allocated_percentage $(show_nums)) -ge $allocated_threshold ]]; then
"${btrfs_balance[@]}" "$(balance_filter $(df_nums))" "$fs"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment