X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;ds=inline;f=mount-latest-subvol;h=433c7c2a06c4ed7c2a465476d1670ac375a3b514;hb=e6cd2e555df3af0cf23da016b833529a34ffc84c;hp=d6af39259c7460ab24cd35f78caaf6cac54d07aa;hpb=40dd151ec6ba75633c74568da59e35a45351f194;p=distro-setup
diff --git a/mount-latest-subvol b/mount-latest-subvol
index d6af392..433c7c2 100644
--- a/mount-latest-subvol
+++ b/mount-latest-subvol
@@ -1,35 +1,42 @@
#!/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.
-
-script=$(readlink -f -- "$BASH_SOURCE")
+
+# On Ian's computers, mount received subvolumes after btrbk.
+# Copyright (C) 2024 Ian Kelling
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+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
+set -e; . /usr/local/lib/bash-bear; set +e
+shopt -s nullglob
usage() {
cat < 0 )); then
+ all_vols+=(ar)
+ fi
+fi
+
##### end command line parsing ########
ret=0
@@ -187,6 +206,9 @@ fi
root_dev=$(awk '$2 == "/" {print $1}' /etc/mtab)
mapper-dev root_dev
+o_dev=$(awk '$2 == "/mnt/o" {print $1}' /etc/mtab)
+mapper-dev o_dev
+
# root2_dev=$(awk '$2 == "/mnt/root2" {print $1}' /etc/mtab)
# mapper-dev root2_dev
@@ -198,6 +220,8 @@ if cryptsetup status $root_dev &>/dev/null; then
crypt_dev=$root_dev
else # if we are in a recovery boot, find the next best crypt device
mopts=,noauto
+ # 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
@@ -210,7 +234,7 @@ fi
# dont tax the cpus of old laptops
-if ((`nproc` > 2)); then
+if (( $(nproc) > 2)); then
mopts+=,compress=zstd
fi
@@ -218,43 +242,59 @@ fstab </dev/null; then
+ if ! awk '$3 == "btrfs" {print $2}' /etc/fstab | grep -xF $d &>/dev/null; then
continue
fi
@@ -280,7 +320,7 @@ for vol in q a o i; 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[@]})
@@ -290,6 +330,7 @@ for vol in q a o i; do
##### end building up list of bind mounts ######
+
# if latest is already mounted, make sure binds are mounted and move on
m check-subvol-stale $d
# populated by check-subvol-stale if stale
@@ -299,7 +340,7 @@ for vol in q a o i; 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
@@ -308,10 +349,33 @@ for vol in q a o i; do
continue
fi
- if [[ $vol == q ]]; then
- # allow to fail, user might not be logged in
- x sudo -u $(id -nu 1000) XDG_RUNTIME_DIR=/run/user/1000 systemctl --user stop arbtt ||:
+
+ ##### begin checking for loopback mounts ####
+ found_loop=false
+ for l in $(losetup -ln|awk '{print $6}'); do
+ for dir in $d ${binds[@]}; do
+ if [[ $l == $dir* ]]; then
+ echo "$0: found loopback mount $l. giving up on unmounting $dir"
+ ret=1
+ found_loop=true
+ break
+ fi
+ done
+ if $found_loop; then
+ break
+ fi
+ done
+ if $found_loop; then
+ continue
fi
+ ##### end end checking loopback mounts ####
+
+
+ ## not using arbtt at the moment
+ # if [[ $vol == q ]]; then
+ # ## allow to fail, user might not be logged in
+ # x sudo -u $(id -nu 1000) XDG_RUNTIME_DIR=/run/user/1000 systemctl --user stop arbtt ||:
+ # fi
umount_ret=true
unmounted=()
for dir in $(echo $d ${binds[*]}\ |tac -s\ ); do
@@ -354,19 +418,18 @@ for vol in q a o i; do
### end getting root_dir
cd $root_dir
- if [[ -e $vol ]]; then
- leaf=$vol.leaf.$(date +%Y-%m-%dT%H:%M:%S%z)
- m mv $vol $leaf
- 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
+ if [[ -e $vol ]]; then
+ if [[ $vol == qd ]]; then
+ m btrfs sub del qd
+ else
+ leaf=$vol.leaf.$(date +%Y-%m-%dT%H:%M:%S%z)
+ m mv $vol $leaf
+ m btrfs property set -ts $leaf ro true
+
+ ### begin check if leaf is different, delete it if not ###
parentid=$(btrfs sub show $leaf | awk '$1 == "Parent" && $2 == "UUID:" {print $3}')
- bsubs=(/mnt/root/btrbk/$vol.*)
- bsub=
+ 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
@@ -375,50 +438,34 @@ for vol in q a o i; do
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
+ 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 ###
+
+ ## begin expire leaf vols ##
+ 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 * 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 > 30 ) )); then
+ x btrfs sub del $leaf
+ fi
+ count=$((count-1))
+ done
fi
- ### end check if leaf is different, delete it if not ###
-
- ## begin expire leaf vols ##
- leaf_vols=($vol.leaf.*)
- count=${#leaf_vols[@]}
- leaf_limit_time=$(( $(date +%s) - 60*60*24*60 )) # 60 days
- leaf_new_limit_time=$(( $(date +%s) - 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.
- 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
- x btrfs sub del $leaf
- fi
- count=$((count-1))
- done
## end expire leaf vols ##
fi
#### end dealing with leaf vols ####
@@ -430,10 +477,13 @@ for vol in q a o i; do
for dir in $d ${binds[@]}; do
m mnt $dir
done
- if [[ $vol == q ]]; then
- # maybe this will fail if X is not running
- x sudo -u $(id -nu 1000) XDG_RUNTIME_DIR=/run/user/1000 systemctl --user start arbtt ||:
- fi
+
+ ## arbtt disabled for now
+ # if [[ $vol == q ]]; then
+ # # maybe this will fail if X is not running
+ # x sudo -u $(id -nu 1000) XDG_RUNTIME_DIR=/run/user/1000 systemctl --user start arbtt ||:
+ # fi
+
stale_dir=/nocow/btrfs-stale
rm -f $stale_dir/$d
done
@@ -463,6 +513,9 @@ for dir in /mnt/r7/amy/{root/root,boot/boot}_ubuntubionic /mnt/{root2/root,boot2
rm -f /nocow/btrfs-stale/$vol
done
+if (( ret >= 1 )); then
+ echo "$0: exit status $ret. see error above"
+fi
exit $ret