X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=mount-latest-subvol;h=4c1ee2f6b1ca1ae1239062d5fe329f2b20bb983a;hb=89fc59d6e4bbeb1778c6aaaee776122dcf790871;hp=93a085a8e20e764e85d43153480f1a58b924507d;hpb=103a2e153f844343c359882079936b2521c82f15;p=distro-setup diff --git a/mount-latest-subvol b/mount-latest-subvol index 93a085a..4c1ee2f 100644 --- a/mount-latest-subvol +++ b/mount-latest-subvol @@ -13,15 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -script=$(readlink -f -- "$BASH_SOURCE") +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file cd / -[[ $EUID == 0 ]] || exec sudo -E "$script" "$@" +[[ $EUID == 0 ]] || exec sudo -E "$this_file" "$@" source /usr/local/lib/err usage() { cat </dev/null; then crypt_dev=$root_dev else # if we are in a recovery boot, find the next best crypt device mopts=,noauto - do_o=false + # todo: I think I had an idea to not setup /o in this case, + # but never finished implementing it for dev in $(dmsetup ls --target crypt | awk '{print $1}'); do dev=/dev/mapper/$dev if awk '{print $1}' /etc/mtab | grep -Fx $dev &>/dev/null; then @@ -221,7 +224,7 @@ fi # dont tax the cpus of old laptops -if ((`nproc` > 2)); then +if (( $(nproc) > 2)); then mopts+=,compress=zstd fi @@ -235,7 +238,7 @@ shopt -s nullglob # ownership, and ssh doesn\'t allow any group writable parent # directories, so we are forced to use a directory structure similar # to home directories -f=(/mnt/root/btrbk/q.*); f=${f[0]} +fa=(/mnt/root/btrbk/q.*); f=${fa[0]} if [[ -e $f ]]; then fstab </dev/null; then + if ! awk '$3 == "btrfs" {print $2}' /etc/fstab | grep -xF $d &>/dev/null; then continue fi @@ -308,7 +306,7 @@ for vol in ${all_vols[@]}; do # eg. when r=/q/p, for lines like # /q/p /p none bind 0 0 # output /p - new_roots+=($(sed -rn "s#^$r/\S+\s+(\S+)\s+none\s+(\S+,|)bind[[:space:],].*#\1#p" /etc/fstab)) + new_roots+=("$(sed -rn "s#^$r/\S+\s+(\S+)\s+none\s+(\S+,|)bind[[:space:],].*#\1#p" /etc/fstab)") done (( ${#new_roots} )) || break binds+=(${new_roots[@]}) @@ -327,7 +325,7 @@ for vol in ${all_vols[@]}; do for b in ${binds[@]}; do if mountpoint -q $b; then bid=$(stat -c%d $b) - if [[ $did != $bid ]]; then + if [[ $did != "$bid" ]]; then umount-kill $b fi fi @@ -389,47 +387,26 @@ for vol in ${all_vols[@]}; do m btrfs property set -ts $leaf ro true ### begin check if leaf is different, delete it if not ### - if [[ -e /a/opt/btrfs-snapshots-diff/btrfs-snapshots-diff.py ]]; then - source /a/bin/distro-functions/src/package-manager-abstractions - #pi python-jmespath # dependency of btrfs-snapshots-diff - # todo: need python3 port of btrfs-snapshots-diff, py2 no exist on nabia - parentid=$(btrfs sub show $leaf | awk '$1 == "Parent" && $2 == "UUID:" {print $3}') - bsubs=(btrbk/$vol.*) - bsub= - # go in reverse order as its more likely to be at the end - for ((i=${#bsubs[@]}-1; i>=0; i--)); do - if [[ $parentid == $(btrfs sub show ${bsubs[i]} | awk '$1 == "UUID:" {print $2}') ]]; then - bsub=${bsubs[i]} - break - fi - done - if [[ $bsub ]]; then - tmp=$(mktemp) - # in testing, same subvol is 136 bytes. allow some overhead. 32 happens sometimes under systemd. - # $ errno 32 - # EPIPE 32 Broken pipe - btrfs send --no-data -p $bsub $leaf | head -c 1000 > $tmp || [[ $? == 141 || ${PIPESTATUS[0]} == 32 ]] - if (( $(stat -c%s $tmp) < 1000)); then - # example output for an empty diff: - # Found a valid Btrfs stream header, version 1 - # o.leaf.2019-05-15T14:00:50-0400;snapshot: uuid=ba045ea30737dd449003f1ee40ec12d0, ctrasid=109533, clone_uuid=3c7e3544e486834aa71d89e5b8f30056, clone_ctransid=109533 - lines=$(/a/opt/btrfs-snapshots-diff/btrfs-snapshots-diff.py -s -f $tmp | \ - grep -vxF "Found a valid Btrfs stream header, version 1" | \ - grep -cv "^[^;]*;snapshot: ") ||: - if [[ $lines == 0 ]]; then - # rotate in case we find a bug, weve got 2 old ones - tmpleaf=($vol.tmpleaf2.*) - if (( ${#tmpleaf[@]} )); then - x btrfs sub del ${tmpleaf[@]} - fi - tmpleaf=($vol.tmpleaf1.*) - if (( ${#tmpleaf[@]} )); then - x mv ${tmpleaf[0]} $vol.tmpleaf2.${tmpleaf[0]#$vol.tmpleaf1.} - fi - echo suspected identical: $bsub $leaf - x mv $leaf $vol.tmpleaf1.${leaf#$vol.leaf.} - fi - fi + parentid=$(btrfs sub show $leaf | awk '$1 == "Parent" && $2 == "UUID:" {print $3}') + bsubs=(btrbk/$vol.*) + bsub= # base subvolume + # go in reverse order as its more likely to be at the end + for ((i=${#bsubs[@]}-1; i>=0; i--)); do + if [[ $parentid == $(btrfs sub show ${bsubs[i]} | awk '$1 == "UUID:" {print $2}') ]]; then + bsub=${bsubs[i]} + break + fi + done + if [[ $bsub ]]; then + # 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 $bsub $leaf | btrfs receive --dump | head -n 100 | wc -l || [[ $? == 141 || ${PIPESTATUS[0]} == 32 ]]) + if [[ $lines == 0 ]]; 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: $bsub $leaf + x btrfs sub del $leaf fi fi ### end check if leaf is different, delete it if not ### @@ -438,12 +415,12 @@ for vol in ${all_vols[@]}; do leaf_vols=($vol.leaf.*) count=${#leaf_vols[@]} leaf_limit_time=$(( EPOCHSECONDS - 60*60*24*60 )) # 60 days - leaf_new_limit_time=$(( EPOCHSECONDS - 60*60*24 )) # 1 day - # this goes backwards from oldest. leaf_new_limit_time is just in case - # the order gets screwed up or something. + leaf_new_limit_time=$(( EPOCHSECONDS - 60*60*24 * 5 )) # 5 days this + # goes backwards from oldest. leaf_new_limit_time is a safety + # measure to ensure we don't delete very recent leafs. for leaf in ${leaf_vols[@]}; do - leaf_time=$(date -d ${leaf#$vol.leaf.} +%s) - if (( leaf_limit_time > leaf_time || ( leaf_new_limit_time > leaf_time && count > 15 ) )); then + leaf_time=$(date -d ${leaf#"$vol".leaf.} +%s) + if (( leaf_limit_time > leaf_time || ( leaf_new_limit_time > leaf_time && count > 30 ) )); then x btrfs sub del $leaf fi count=$((count-1))