]> code.delx.au - monosys/blob - hacks/lib-ext-backup
notes: fix raspi install notes, also @home -> @username
[monosys] / hacks / lib-ext-backup
1 #!/bin/bash
2
3 function cryptsetup_open {
4 for DEVICE in /dev/disk/by-partlabel/ext*backup*; do
5 if ! [ -L "$DEVICE" ]; then
6 continue
7 fi
8 DISKNAME="$(basename "$DEVICE")"
9 CRYPTNAME="crypt-$DISKNAME"
10 if [ -L "/run/ext-backup-crypt/$CRYPTNAME" ]; then
11 continue
12 fi
13 echo "> cryptsetup luksOpen $DEVICE $CRYPTNAME"
14 cryptsetup luksOpen "$DEVICE" "$CRYPTNAME" --key-file "/etc/lukskeys/${DISKNAME}"
15 mkdir -p /run/ext-backup-crypt/
16 ln -sf "/dev/mapper/$CRYPTNAME" /run/ext-backup-crypt/
17 done
18 }
19
20 function cryptsetup_close {
21 for CRYPTDEVICE in /dev/mapper/crypt-ext*backup*; do
22 if ! [ -L "$CRYPTDEVICE" ]; then
23 continue
24 fi
25 CRYPTNAME="$(basename "$CRYPTDEVICE")"
26 echo "> cryptsetup luksClose $CRYPTNAME"
27 cryptsetup luksClose "$CRYPTNAME"
28 rm -f "/run/ext-backup-crypt/$CRYPTNAME"
29 done
30 }
31
32 function pool_import {
33 echo "> zpool import -d /run/ext-backup-crypt -a"
34 zpool import -d /run/ext-backup-crypt -a
35
36 ZPOOLNAME="$(zpool list -H -o name|grep 'ext.*backup'|head -n1)"
37 if [ -z "$ZPOOLNAME" ]; then
38 echo "Error! Could not find pool!"
39 return 1
40 fi
41
42 echo "> Found: $ZPOOLNAME"
43 }
44
45 function pool_export {
46 echo "> zpool export $ZPOOLNAME"
47 for _ in $(seq 60); do
48 zpool export "$ZPOOLNAME" && break
49 sleep 1
50 done
51 }
52
53 function pool_setup {
54 zpool set failmode=wait "$ZPOOLNAME"
55 zfs set mountpoint="/mnt/$ZPOOLNAME" "$ZPOOLNAME"
56 chmod 0700 "/mnt/$ZPOOLNAME"
57 zfs set compression=lz4 "$ZPOOLNAME"
58 zfs set devices=off "$ZPOOLNAME"
59 zfs set exec=off "$ZPOOLNAME"
60 zfs set setuid=off "$ZPOOLNAME"
61 zfs set xattr=sa "$ZPOOLNAME"
62 zfs set acltype=posixacl "$ZPOOLNAME"
63 }
64
65 function pool_maybe_scrub {
66 local now
67 local last_scrub
68 local last_scrub_days_ago
69 now="$(date +%s)"
70 last_scrub="$(zpool status "$ZPOOLNAME"|sed -nE 's/scan: scrub repaired.* on (.*)/\1/p')"
71 last_scrub_days_ago=$(((now - $(date --date="${last_scrub:-1970-01-01}" +%s)) / 86400))
72
73 if [ $last_scrub_days_ago -lt 7 ]; then
74 return
75 fi
76
77 echo "> zpool scrub $ZPOOLNAME"
78 zpool scrub "$ZPOOLNAME"
79
80 while zpool status "$ZPOOLNAME" | awk '/state: ONLINE|scan: scrub in progress/ {x++} END {exit x-2}'; do
81 echo -n .
82 sleep 60
83 done
84 echo " done"
85
86 if zpool list -H -o health "$ZPOOLNAME" | grep -qv ONLINE; then
87 zpool status -v "$ZPOOLNAME"
88 return 1
89 fi
90 }
91
92 function syncoidw {
93 echo "> syncoid $1"
94 syncoid "$@" --identifier "$ZPOOLNAME"
95 }
96
97 function snapshot_cleanup {
98 echo "> Cleaning snapshots"
99 sanoid --configdir=/etc/sanoid/ext-backup --verbose --prune-snapshots
100
101 zfs list -t snapshot -H -o name -r "$ZPOOLNAME" \
102 | grep -F @syncoid_ \
103 | grep -Fv "@syncoid_$ZPOOLNAME" \
104 | xargs -rn1 zfs destroy -v
105 }
106
107 function snapshot_convert_to_bookmarks {
108 local fs
109 local snap
110
111 for fs in "$@"; do
112 for snap in $(zfs list -H -o name -t snapshot -r "$fs"); do
113 echo "> zfs bookmark $snap"
114 zfs bookmark "$snap" "${snap/@/#}"
115 zfs destroy "$snap"
116 done
117 done
118 }
119
120 function main {
121 zfs get all -s local -H > /root/zfs-props.txt
122 cryptsetup_open
123 pool_import
124 pool_setup
125 snapshot_sync
126 snapshot_cleanup
127 pool_maybe_scrub
128 pool_export
129 cryptsetup_close
130 }