aboutsummaryrefslogtreecommitdiff
path: root/tests/agent/btrfs-rmdir
diff options
context:
space:
mode:
Diffstat (limited to 'tests/agent/btrfs-rmdir')
-rwxr-xr-xtests/agent/btrfs-rmdir66
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"