X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=mount-latest-subvol;h=cddb714df7962b2fb48521800e07b471267250ff;hb=110af45c7f752203344f1578302be6c9103fd851;hp=7a179c4fd604480b50af48136d81990a25cef69b;hpb=9c77c557e60d21caceeef1e78e35b35ed968fca9;p=distro-setup diff --git a/mount-latest-subvol b/mount-latest-subvol index 7a179c4..cddb714 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,22 +238,23 @@ 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 @@ -301,7 +307,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[@]}) @@ -320,7 +326,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 @@ -376,51 +382,54 @@ for vol in ${all_vols[@]}; 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 ### - 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 - tmp=$(mktemp) - # 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 + 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=(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 ### + + ## 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=$(( 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. - 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 #### @@ -468,6 +477,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