important fixes
authorIan Kelling <ian@iankelling.org>
Thu, 3 Oct 2024 10:10:24 +0000 (06:10 -0400)
committerIan Kelling <ian@iankelling.org>
Thu, 3 Oct 2024 10:10:24 +0000 (06:10 -0400)
filesystem/usr/local/bin/btrbk-run
filesystem/usr/local/bin/mount-latest-subvol

index 36872fe772b2db0a9e79e9ad368b5183ff3b89eb..9af45e293787de364c2afcf8eb48e43eee2b3e54 100755 (executable)
@@ -606,8 +606,8 @@ if [[ ! -v targets && ! $source ]]; then
     if ! $kd_spread && [[ $HOSTNAME != x3 ]]; then
       add-x3-target
     fi
-    if [[ $HOSTNAME != kd ]]; then
-      targets+=(kd.b8.nz)
+    if [[ $HOSTNAME != frodo ]]; then
+      targets+=(frodo.b8.nz)
     fi
     wireless_home_hosts=(
       # out of comission for now
index 019d16a251a231788f1638d6b350abdbed8988cf..602ca527f3c2bc18ee0cae19d5af9378549a992f 100755 (executable)
@@ -78,6 +78,17 @@ m() {
   "$@"
 }
 
+# warn on command fail
+w() {
+  local ret
+  ret=0
+  "$@" || ret=$?
+  if (( ret != 0 )); then
+    d "WARNING: exit code $ret of: $*" >&2
+    return $ret
+  fi
+}
+
 # mkdir + mount from fstab.
 mnt() {
   local dir
@@ -151,9 +162,11 @@ get-btrfs-root-mountpoint() {
   fi
 }
 
-# Input vars: $vol, PWD=$root_dir (from get-btrfs-root-mountpoint)
+# Input vars: $vol, $root_dir (from get-btrfs-root-mountpoint)
+# Note: we cd $root_dir.
 expire-leaf-vols() {
   local leaf_vols count leaf_limit_time  leaf_new_limit_time leaf
+  cd $root_dir
   leaf_vols=($vol.leaf.*)
   count=${#leaf_vols[@]}
   leaf_limit_time=$(( EPOCHSECONDS - 60*60*24*60 )) # 60 days
@@ -162,9 +175,9 @@ expire-leaf-vols() {
   # This goes backwards from oldest. leaf_new_limit_time is to avoid
   # deleting very recent leafs.
   for leaf in ${leaf_vols[@]}; do
-    leaf_time=$(date -d ${leaf#$vol.leaf.} +%s)
+    leaf_time=$(date -d ${leaf#"$vol".leaf.} +%s)
     if (( leaf_limit_time > leaf_time || ( leaf_new_limit_time > leaf_time && count > 30 ) )); then
-      b btrfs sub del $leaf
+      w b btrfs sub del $leaf || return 0
     fi
     count=$((count-1))
   done
@@ -176,7 +189,7 @@ expire-leaf-vols() {
 #
 # Input vars: $root_dir (from get-btrfs-root-mountpoint)
 dedupe-btrbk() {
-  local parentid subvol parent_sub i lines
+  local parentid subvol parent_sub i lines tmpstr
   local -a bsubs
   subvol="$1"
   parentid=$(btrfs sub show $subvol | awk '$1 == "Parent" && $2 == "UUID:" {print $3}')
@@ -195,12 +208,18 @@ dedupe-btrbk() {
   # in testing, same subvol is 136 bytes. allow some overhead. 32 happens sometimes under systemd.
   # $ errno 32
   # EPIPE 32 Broken pipe
-  lines=$(btrfs send --no-data -p $parent_sub $subvol | btrfs receive --dump | head -n 100 | wc -l || [[ $? == 141 || ${PIPESTATUS[0]} == 32 ]])
-  if [[ $lines == 0 ]]; then
+  warnret=0
+  tmpstr=$(btrfs send --no-data -p $parent_sub $subvol | btrfs receive --dump | head -n 100 || [[ $? == 141 || ${PIPESTATUS[0]} == 32 ]]) || warnret=$?
+  if (( warnret != 0 )); then
+    d "WARNING: dedupe-btrbk: btrfs-send returned:$warnret, giving up on deduping leaf subvol"
+    return 0
+  fi
+  mapfile -t lines <<<"$tmpstr"
+  if [[ ${#lines[@]} == 2 && ${lines[0]} == "At subvol"* && ${lines[1]} == snapshot* ]]; then
     # example output of no differences:
     # snapshot        ./qrtest                        uuid=c41ff6b7-0527-f34d-95ac-190eecf54ff5 transid=2239 parent_uuid=64949e1b-4a3e-3945-9a8e-cd7b7c15d7d6 parent_transid=2239
-    echo suspected identical: $parent_sub $subvol
-    b btrfs sub del $subvol
+    echo identical: $parent_sub $subvol
+    w b btrfs sub del $subvol || return 0
   fi
 }
 
@@ -210,7 +229,7 @@ dedupe-btrbk() {
 #
 # Note: we cd $root_dir.
 mv-vol-to-leaf() {
-  local leaf
+  local leaf date
 
   cd $root_dir
 
@@ -220,15 +239,15 @@ mv-vol-to-leaf() {
 
   # no leaf volumes for qd
   if [[ $vol == qd ]]; then
-    b btrfs sub del qd
+    w b btrfs sub del qd || return 0
     return 0
   fi
 
-  dedupe-btrbk $root_dir/$vol
-
-  leaf=$vol.leaf.$(date +%Y-%m-%dT%H:%M:%S%z)
+  date=$(date +%Y-%m-%dT%H:%M:%S%z)
+  leaf=$vol.leaf.$date
   b mv $vol $leaf
-  b btrfs property set -ts $leaf ro true
+  w b btrfs property set -ts $leaf ro true ||:
+  w dedupe-btrbk $root_dir/$leaf || return 0
 }
 
 # Input vars: $vol
@@ -405,24 +424,30 @@ prune-vols() {
 # got remounted with a different filesystem.
 #
 # Input vars: ${pruned_vols[@]}
-bind-mismatch-fix() {
-  local vol d_id b b_id found_mismatch
+#
+# Set leftover vars: $root_dir
+mount-mismatch-fix() {
+  local vol vol_id mp mp_id found_mismatch
   local -a to_umount
   for vol in ${pruned_vols[@]}; do
     set-d-binds
+    get-btrfs-root-mountpoint
     found_mismatch=false
-    d_id=$(stat -c%d $d)
-    for b in ${binds[@]}; do
-      if mountpoint -q $b; then
-        b_id=$(stat -c%d $b)
-        if [[ $d_id != "$b_id" ]]; then
-          found_mismatch=false
-          to_umount+=($b)
+    vol_id=$(stat -c%d $root_dir/$vol)
+    for mp in $d ${binds[@]}; do
+      if mountpoint -q $mp; then
+        # %d = "device number", which is different between
+        # %subvols. TODO: probably change this to UUID. Try to find out
+        # %if device id is unique on this host or what.
+        mp_id=$(stat -c%d $mp)
+        if [[ $vol_id != "$mp_id" ]]; then
+          found_mismatch=true
+          to_umount+=($mp)
         fi
       fi
     done
     if $found_mismatch; then
-      d "WARNING: fixing bind mount(s): ${to_umount[*]}, pointing to old subvol."
+      d "WARNING: fixing mount(s):${to_umount[*]}, pointing to old subvol."
       umount-kill ${to_umount[@]}
       m mnt ${to_umount[@]}
     fi
@@ -452,7 +477,7 @@ plan-umounts() {
       umount_vols+=($vol)
       for dir in ${binds[@]} $d; do
         if mountpoint -q $dir; then
-          to_umount=($dir)
+          to_umount+=($dir)
         fi
       done
     else
@@ -486,10 +511,7 @@ amy-root2-latest() {
       if ! kill-dir TERM TERM TERM INT INT HUP HUP TERM TERM TERM INT INT HUP HUP; then
         if $force; then  kill-dir KILL; fi
       fi
-      if ! b btrfs sub del $dir; then
-        echo "$0: ERROR: failed to delete subvolume $dir" >&2
-        ret=1
-      fi
+      w b btrfs sub del $dir || return 0
     fi
 
     b btrfs sub snapshot $fresh_snap $dir
@@ -510,7 +532,6 @@ umount-then-mount-latest() {
     if $umount_ret; then
       fresh_snap=$(cat /nocow/btrfs-stale/$vol 2>/dev/null)
       get-btrfs-root-mountpoint
-      cd $root_dir
       mv-vol-to-leaf
       expire-leaf-vols
       b btrfs sub snapshot $fresh_snap $vol
@@ -557,15 +578,17 @@ fi
 ret=0
 mkdir -p /var/log/btrbk
 
-setup-root2
 setup-fstab
 prune-vols
-bind-mismatch-fix
+w mount-mismatch-fix ||:
 plan-umounts
 if (( ${#umount_vols[@]} >= 1 )); then
   umount-then-mount-latest
 fi
-amy-root2-latest
+
+# i don't want to be stuck trying to fix these if they fail for some reason
+w setup-root2 ||:
+w amy-root2-latest ||:
 
 if (( ret >= 1 )); then
   echo "$0: exit status $ret. see error(s) above" >&2