]> code.delx.au - monosys/commitdiff
bsnap btrfs support
authorJames Bunton <jamesbunton@delx.net.au>
Sat, 10 Nov 2018 03:46:26 +0000 (14:46 +1100)
committerJames Bunton <jamesbunton@delx.net.au>
Sat, 10 Nov 2018 03:46:26 +0000 (14:46 +1100)
bsnap-lvm

index 464868172608ead4f8bcc02267c4b3dccb7d44fc..1f36d8e62a4fa364a86d4dd9d3f9d9c5c769a163 100755 (executable)
--- a/bsnap-lvm
+++ b/bsnap-lvm
@@ -7,36 +7,106 @@ function snap {
 
     mkdir -p /a
 
-    cat /etc/fstab | awk '{print $5 " " $1 " " $2;}' | while read -r dump dev mnt; do
-        if [ "$dump" = 1 ]; then
-            echo "bind mount $mnt"
-            mount --bind "${mnt}" "/a${mnt}"
-        elif [ "$dump" = 2 ]; then
-            read -r lvname vgname _ < <(lvdisplay --noheadings -C "$dev")
-            echo "snapshot ${vgname}/${lvname}"
-            lvcreate -L1G --snapshot --name "${lvname}snap" "${vgname}/${lvname}"
-            mount -o ro "${dev}snap" "/a${mnt}"
-        fi
-    done
+    dispatch snap < /etc/fstab
 }
 
 function unsnap {
-    tac /etc/fstab | awk '{print $5 " " $1 " " $2;}' | while read -r dump dev mnt; do
-        snapmnt="/a${mnt}"
-        snapdev="${dev}snap"
-        if [ "$dump" = 1 ]; then
-            echo "umount $snapmnt"
-            mountpoint -q "$snapmnt" && umount "$snapmnt"
-        elif [ "$dump" = 2 ]; then
-            echo "umount $snapmnt"
-            mountpoint -q "$snapmnt" && umount "$snapmnt"
-
-            echo "unsnapshot $snapdev"
-            [ -b "$(readlink -f "$snapdev")" ] && echo y | lvremove "${dev}snap"
+    tac /etc/fstab | dispatch unsnap
+
+    if [ -d "/a" ]; then
+        rmdir /a
+    fi
+}
+
+function dispatch {
+    local action="" snaptype=""
+    local dev="" mnt="" fstype="" opts="" dump=""
+
+    while read -r dev mnt fstype opts dump pass; do
+        snaptype="$(get_snaptype "$fstype" "$dump")"
+        if [ -z "$snaptype" ]; then
+            continue
         fi
+        action="${1}_${snaptype}"
+        echo "$action $mnt"
+        "$action" "$dev" "$mnt" "$opts"
     done
+}
+
+function get_snaptype {
+    local fstype="$1" dump="$2"
+    if [ "$dump" = "1" ]; then
+        echo bind
+    elif [ "$dump" = "2" ] && [ "$fstype" = "btrfs" ]; then
+        echo btrfs
+    elif [ "$dump" = "2" ]; then
+        echo lvm
+    fi
+}
+
+function snap_bind {
+    local mnt="$2"
+    mount --bind "${mnt}" "/a${mnt}"
+}
+
+function unsnap_bind {
+    local snapmnt="/a$2"
+    if mountpoint -q "$snapmnt"; then
+        umount "$snapmnt"
+    fi
+}
+
+function snap_lvm {
+    local dev="$1" mnt="$2"
+    local lvname="" vgname=""
+    read -r lvname vgname _ < <(lvdisplay --noheadings -C "$dev")
+    echo "snapshot ${vgname}/${lvname}"
+    lvcreate -L1G --snapshot --name "${lvname}snap" "${vgname}/${lvname}"
+    mount -o ro "${dev}snap" "/a${mnt}"
+}
+
+function unsnap_lvm {
+    local snapdev="${1}snap"
+    local snapmnt="/a$2"
+    if mountpoint -q "$snapmnt"; then
+        umount "$snapmnt"
+    fi
+    if [ -b "$(readlink -f "$snapdev")" ]; then
+        lvremove -f "${dev}snap"
+    fi
+}
+
+function snap_btrfs {
+    local mnt="$2" opts="$3" snapdir=""
+
+    snapdir="$(get_btrfs_snapshot_dir "$opts" "$mnt")"
+    btrfs subvolume snapshot "$mnt" "$snapdir"
+
+    mount --bind "$snapdir" "/a${mnt}"
+}
+
+function unsnap_btrfs {
+    local mnt="$2" opts="$3" snapdir=""
+
+    local snapmnt="/a$2"
+    if mountpoint -q "$snapmnt"; then
+        umount "$snapmnt"
+    fi
+
+    snapdir="$(get_btrfs_snapshot_dir "$opts" "$mnt")"
+    if [ -d "$snapdir" ]; then
+        btrfs subvolume delete "$snapdir"
+    fi
+}
 
-    rmdir /a || true
+function get_btrfs_snapshot_dir {
+    local opts="$1" mnt="$2" subvol=""
+    subvol="$(echo "$opts" | sed -nE 's/^.*\bsubvol=([^,]+)\b.*$/\1/p')"
+    if [ -z "$subvol" ]; then
+        echo "Unknown subvol for mountpoint: $mnt"
+        exit 1
+    fi
+    echo "/$(hostname -s)/${subvol}-snap"
 }
 
 if [ "$(id -u)" -ne 0 ]; then