# field, and we won't mount it. Need to figure out a solution that will
# fix this.
+# todo: I took out qr because I moved it to a different disk at home,
+# and dont feel like updating this script to deal with that. Make sure
+# it is getting backed up, maybe having just a backup of qr on my
+# desktop is good enough.
[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
write-config() {
+ local q_mp=false
+ local -a tmp_mps
cat >/etc/btrbk$conf_suf.conf <<EOF
ssh_identity /q/root/h
EOF
fi
- # make /q be last
+ # make /q be last.
mp_count=${#mountpoints[@]}
for (( i=0; i < mp_count - 1 ; i++ )); do
if [[ ${mountpoints[i]} == /q ]]; then
- unset "mountpoints[i]"
- mountpoints+=(/q)
+ q_mp=true
+ else
+ tmp_mps+=(${mountpoints[i]})
fi
done
+ if $q_mp; then
+ mountpoints=( "${tmp_mps[@]}" /q )
+ fi
if [[ $source ]]; then
tmp_a=($vol/btrbk/$sub.*)
- tg_snaps+=("${tmp_a[*]}")
+ tg_snaps+=("${tmp_a[@]}")
cat >>/etc/btrbk$conf_suf.conf <<EOF
volume ssh://$bbksource$vol
subvolume $sub
fi
done
+
if $conf_only; then
mexit 0
fi
get-orphan-tg-snaps() {
- orphan_tg_snaps=()
- for (( i=0; i < ${#mountpoints[@]}; i++ )); do
- orphan_start_count=${#orphan_tg_snaps[@]}
- tg_snap_count=0
- for tg_snap in ${tg_snaps[$i]}; do
- tg_snap_count=$(( tg_snap_count + 1 ))
- if [[ ! ${source_snaps[$tg_snap]} ]]; then
- orphan_tg_snaps+=("$tg_snap")
+ local mp_to_snap_regex snap
+ local -a mp_orphan_tg_snaps mp_tg_snaps
+
+ ## sanity checking
+ for (( i=0; i < ${#tg_snaps[@]}; i++ )); do
+ if [[ ! ${tg_snaps[$i]} =~ $good_path_regex ]]; then
+ die "bad var: tg_snaps[$i] '${tg_snaps[$i]}'"
+ fi
+ done
+ for snap in "${!source_snaps[@]}"; do
+ if [[ ! $snap =~ $good_path_regex ]]; then
+ die "bad source snap: '$snap'"
+ fi
+ done
+
+
+ # note: we do each mountpoint separately just so we can better sanity
+ # check that we aren't incorrectly classifying all target snaps as
+ # orphans.
+ for mp in "${mountpoints[@]}"; do
+ mp_orphan_tg_snaps=()
+ mp_tg_snaps=()
+ mp_to_snap_regex="$mp"'\.[0-9]{8}T[0-9]{6}-[0-9]{4}$'
+ for tg_snap in "${tg_snaps[@]}"; do
+ if [[ $tg_snap =~ $mp_to_snap_regex ]]; then
+ mp_tg_snaps+=("$tg_snap")
fi
done
- orphan_mp_count=$(( ${#orphan_tg_snaps[@]} - orphan_start_count ))
- # sanity checking
- tmp=$(( tg_snap_count > 1 && tg_snap_count == orphan_mp_count ))
- if (( tmp )) ; then
- if [[ $source ]]; then
- tg_host=$HOSTNAME
- else
- tg_host=$tg
+ for mp_tg_snap in "${mp_tg_snaps[@]}"; do
+ if [[ ! ${source_snaps[$mp_tg_snap]} ]]; then
+ orphan_tg_snaps+=("$tg_snap")
+ mp_orphan_tg_snaps+=("$tg_snap")
fi
- die "something went wrong checking orphans on $tg_host: for mountpoint ${mountpoints[$i]}, $orphan_mp_count. tg_snaps:${tg_snaps[*]}, source_snaps: ${!source_snaps[*]}"
- fi
+
+ ## sanity checking
+ tmp=$(( ${#mp_tg_snaps[@]} >= 1 && ${#mp_orphan_tg_snaps[@]} == ${#mp_tg_snaps[@]} ))
+ if (( tmp )) ; then
+ if [[ $source ]]; then
+ tg_host=$HOSTNAME
+ else
+ tg_host=$tg
+ fi
+ die "something went wrong checking orphans on $tg_host: for mountpoint: $mp, mp_tg_snaps: ${mp_tg_snaps[*]},
+source_snaps: ${!source_snaps[*]}"
+ fi
+ done
+
done
}
fi
else # we have targets
for tg in ${targets[@]}; do
- tmp_str=$(ssh root@$tg "shopt -s nullglob; echo $snap_list_glob")
- mapfile -t tg_snaps <<<"$tmp_str"
+ tmpstr=$(ssh root@$tg "shopt -s nullglob; echo $snap_list_glob")
+ IFS=" " read -r -a tg_snaps <<<"$tmpstr"
get-orphan-tg-snaps
- tmp=$(( ${#orphan_tg_snaps[*]} >= 1 ))
+ tmp=$(( ${#orphan_tg_snaps[@]} >= 1 ))
if (( tmp )); then
d ssh root@$tg "btrfs sub del ${orphan_tg_snaps[*]}"
fi
# note q is owned by root:1000
+good_path_regex='^[-a-zA-Z0-9/._]+$'
snap_path_regex='[a-z]/btrbk/[a-z]+\.[0-9]{8}T[0-9]{6}-[0-9]{4}$'
declare -A source_snaps
mountpoints=()
rate_limit=no
# -q and just using the syslog option seemed nice,
# but it doesn't show when a send has a parent and when it doesn't.
-verbose=true; verbose_arg="-l trace"
+verbose=false; verbose_arg=
force=false
if [[ $PPID == 1 || $INVOCATION_ID || $SYSTEMD_EXEC_PID ]]; then
# running as a service. we cant show progress in this case,
-3) conf_suf=3 ;;
-a)
# all moiuntpoints
- mountpoints=(/a /o /qr /q)
+ mountpoints=(/a /o /q)
;;
# only creates the config file, does not run btrbk
-c) conf_only=true ;;
prospective_mps+=(/o)
fi
if [[ $source_host == "$HOST2" ]]; then
- prospective_mps+=(/a /qr /q)
+ prospective_mps+=(/a /q)
fi
else
if [[ $HOSTNAME == "$MAIL_HOST" ]]; then
prospective_mps+=(/o)
fi
if [[ $HOSTNAME == "$HOST2" ]]; then
- prospective_mps+=(/a /qr /q)
+ prospective_mps+=(/a /q)
fi
if $kd_spread; then
- prospective_mps=(/a /o /qr /q)
+ prospective_mps=(/a /o /q)
fi
fi
# If the above conditions didnt add any mountpoints, and host
# status is empty, then add all mointpoints. This is a case of
# doing something like kd_spread manually.
if [[ ! ${prospective_mps[0]} && $source_host != "$HOST2" && $source_host != "$MAIL_HOST" && $HOSTNAME != "$MAIL_HOST" && $HOSTNAME != "$HOST2" ]]; then
- prospective_mps=(/a /o /qr /q)
+ prospective_mps=(/a /o /q)
fi
# note: put q last just in case its specific retention options were to