#!/bin/bash
+# Copyright (C) 2016 Ian Kelling
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# usage: $0 SUBVOL_MOUNTPOINT...
+#
+# In git, this is not not executable because it's meant to be installed
+# using ./install-my-scripts
+#
+# If latest subvols $@ are not mounted, exit 1, print message, and touch
+# /nocow/btrfs-stale/$subvol
+#
+# Either SUBVOL_MOUNTPOINT is a snapshot of the latest, or
+# the latest snapshot is snapshot of SUBVOL_MOUNTPOINT.
[[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
shopt -s nullglob
+if [[ ! $@ ]]; then
+ echo "$0: error: expected mountpoint argument"
+fi
+
ret=0
for d; do
vol=${d##*/}
cd /mnt/root/btrbk
- snaps=($vol.20*)
+ snaps=($vol.20*) # Assumes we are in the 21st century.
if [[ ! $snaps ]]; then
# no snapshots yet
continue
done | sort -r | head -n 1 | awk '{print $2}'
)
if [[ ! $last_snap ]]; then
- echo "$d stale"
+ # should not happen.
+ echo "$0: error: could not find latest snapshot for $d among ${snaps[@]}"
ret=1
continue
fi
- stale=true
- if btrfs sub show $d|sed '0,/^\t*Snapshot(s):/d;s/^\s*//' | \
+
+ # check that $d has $last_snap as a snapshot,
+ # or else $d is a snapshot of $last_snap. In the second
+ # case, we use a uuid comparison, which if I remember from the
+ # docs, is a bit more robust, perhaps to renames.
+ if btrfs sub show $d 2>/dev/null | sed '0,/^\s*Snapshot(s):/d;s/^\s*//' | \
grep -xF btrbk/$last_snap &>/dev/null; then
stale=false
else
- last_uuid=$(btrfs sub show $last_snap| awk '$1 == "UUID:" {print $2}')
- if btrfs sub show $d| grep "^\s*Parent UUID:\s*$last_uuid$" &>/dev/null; then
+ last_snap_uuid=$(btrfs sub show $last_snap| awk '$1 == "UUID:" {print $2}')
+ if btrfs sub show $d| grep "^\s*Parent UUID:\s*$last_snap_uuid$" &>/dev/null; then
+ stale=false
+ fi
+ fi
+
+ # check if $d is a snapshot of any of the btrbk backups other than the latest
+ if [[ ! $stale ]]; then
+ for f in ${snaps[@]}; do
+ if [[ $f == $last_snap ]]; then continue; fi
+ uuid=$(btrfs sub show $f| awk '$1 == "UUID:" {print $2}')
+ if btrfs sub show $d| grep "^\s*Parent UUID:\s*$uuid$" &>/dev/null; then
+ stale=true
+ echo "$d stale: it's a snapshot of $f"
+ break
+ fi
+ done
+ fi
+ # check if $d generation is later than last_snap
+ if [[ ! $stale ]]; then
+ last_snap_gen=$(btrfs sub show $last_snap| awk '$1 == "Generation:" {print $2}')
+ d_gen=$(btrfs sub show $d| awk '$1 == "Generation:" {print $2}')
+ if (( d_gen < last_snap_gen )); then
stale=false
+ else
+ echo "$d stale: it's generation, $d_gen, is earlier than the last snapshot's, $last_snap_gen"
+ stale=true
fi
fi
+
+
stale_dir=/nocow/btrfs-stale
stale_file=$stale_dir/$vol
if $stale; then
mkdir -p $stale_dir
printf "%s\n" $last_snap > $stale_file
- echo "$d stale"
ret=1
continue
else
fi
done
exit $ret
-
-# todo: figure out what to do when there are no
-# snapshots yet. I guess that should be
-# yes to being stale? see the implications
-# in the other script.