diff options
Diffstat (limited to 'tests/agent/btrfs-rmdir')
-rwxr-xr-x | tests/agent/btrfs-rmdir | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/tests/agent/btrfs-rmdir b/tests/agent/btrfs-rmdir new file mode 100755 index 0000000..cc51dc2 --- /dev/null +++ b/tests/agent/btrfs-rmdir @@ -0,0 +1,66 @@ +#! /usr/bin/env bash + +# Remove a directory on a btrfs filesystem. Inside, subvolumes are removed +# with btrfs subvolume delete and everything else with rm. +# +# Notes: +# +# 1. <dir> should not be a subvolume (use delete directly in this case). +# +# 2. Read-only subvolumes are changed to read-write before deleting. +# +usage="usage: $0 <dir>/" + +owd="$(pwd)" +trap "{ cd '$owd'; exit 1; }" ERR +set -o errtrace # Trap in functions. + +function info () { echo "$*" 1>&2; } +function error () { info "$*"; exit 1; } + +dir="${1%/}" + +if [ -z "$dir" ]; then + error "$usage" +fi + +shopt -s nullglob dotglob + +function rm_dir () # <dir> +{ + local dir="$1" + + local p + for p in "$dir"/*; do + + if [ -d "$p" -a ! -L "$p" ]; then + + # See if this is a subvolume: btrfs subvolume list requires root + # priviliges so we use the inode number which for subvolumes is always + # 256. + # + if [ "$(stat --format=%i "$p")" -eq 256 ]; then + rm_subvol "$p" + else + rm_dir "$p" + fi + else + rm "$p" + fi + done + + rmdir "$dir" +} + +function rm_subvol () # <dir> +{ + local dir="$1" + + if [ "$(btrfs property get -ts "$dir" ro)" = "ro=true" ]; then + btrfs property set -ts "$dir" ro false >/dev/null + fi + + btrfs subvolume delete "$dir" >/dev/null +} + +rm_dir "$dir" |