From: Ian Kelling Date: Sat, 30 Mar 2019 18:54:08 +0000 (-0400) Subject: purge old leaf subvols X-Git-Url: https://iankelling.org/git/?p=distro-setup;a=commitdiff_plain;h=b38f62582694bd678baa77bfeab627feefbc6a40 purge old leaf subvols --- diff --git a/mount-latest-subvol b/mount-latest-subvol index 186b960..bf5ec9c 100644 --- a/mount-latest-subvol +++ b/mount-latest-subvol @@ -18,95 +18,95 @@ [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@" errcatch() { - set -E; shopt -s extdebug - _err-trap() { - err=$? - exec >&2 - set +x - echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:in \`$BASH_COMMAND' returned $err" - bash-trace 2 - echo "$0: exiting with code $err" - exit $err - } - trap _err-trap ERR - set -o pipefail + set -E; shopt -s extdebug + _err-trap() { + err=$? + exec >&2 + set +x + echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:in \`$BASH_COMMAND' returned $err" + bash-trace 2 + echo "$0: exiting with code $err" + exit $err + } + trap _err-trap ERR + set -o pipefail } bash-trace() { - local -i argc_index=0 frame i start=${1:-1} max_indent=8 indent - local source - local extdebug=false - if [[ $(shopt -p extdebug) == *-s* ]]; then - extdebug=true - fi + local -i argc_index=0 frame i start=${1:-1} max_indent=8 indent + local source + local extdebug=false + if [[ $(shopt -p extdebug) == *-s* ]]; then + extdebug=true + fi - for ((frame=0; frame < ${#FUNCNAME[@]}-1; frame++)); do - argc=${BASH_ARGC[frame]} - argc_index+=$argc - ((frame < start)) && continue - if (( ${#BASH_SOURCE[@]} > 1 )); then - source="${BASH_SOURCE[frame+1]}:${BASH_LINENO[frame]}:" - fi - indent=$((frame-start+1)) - indent=$((indent < max_indent ? indent : max_indent)) - printf "%${indent}s↳%sin \`%s" '' "$source" "${FUNCNAME[frame]}" - if $extdebug; then - for ((i=argc_index-1; i >= argc_index-argc; i--)); do - printf " %s" "${BASH_ARGV[i]}" - done - fi - echo \' - done + for ((frame=0; frame < ${#FUNCNAME[@]}-1; frame++)); do + argc=${BASH_ARGC[frame]} + argc_index+=$argc + ((frame < start)) && continue + if (( ${#BASH_SOURCE[@]} > 1 )); then + source="${BASH_SOURCE[frame+1]}:${BASH_LINENO[frame]}:" + fi + indent=$((frame-start+1)) + indent=$((indent < max_indent ? indent : max_indent)) + printf "%${indent}s↳%sin \`%s" '' "$source" "${FUNCNAME[frame]}" + if $extdebug; then + for ((i=argc_index-1; i >= argc_index-argc; i--)); do + printf " %s" "${BASH_ARGV[i]}" + done + fi + echo \' + done } errcatch tu() { - while read -r line; do - file="$1" - grep -xFq "$line" "$file" || tee -a "$file"<<<"$line" - done + while read -r line; do + file="$1" + grep -xFq "$line" "$file" || tee -a "$file"<<<"$line" + done } e() { printf "%s\n" "$*"; "$@"; } mnt() { - dir=$1 - if ! mountpoint $dir &>/dev/null; then - mkdir -p $dir - e mount $dir - fi + dir=$1 + if ! mountpoint $dir &>/dev/null; then + mkdir -p $dir + e mount $dir + fi } fstab() { - while read -r start mpoint end; do - l="$start $mpoint $end" - # kill off any lines that duplicate the mount point. - sed --follow-symlinks -ri "\%$l%b;\%^\s*\S+\s+$mpoint\s%d" /etc/fstab - tu /etc/fstab <<<"$l" - done + while read -r start mpoint end; do + l="$start $mpoint $end" + # kill off any lines that duplicate the mount point. + sed --follow-symlinks -ri "\%$l%b;\%^\s*\S+\s+$mpoint\s%d" /etc/fstab + tu /etc/fstab <<<"$l" + done } kill-dir() { - for sig; do - echo kill-dir $sig - found_pids=false - if pids=$(timeout 4 lsof -t $dir); then - found_pids=true - timeout 4 lsof -w $dir - kill -$sig $pids - fi - # fuser will find open sockets that lsof won't, for example from gpg-agent. - # note: -v shows kernel processes, which then doesn't return true when we want - if timeout 4 fuser -m $dir &>/dev/null; then - found_pids=true - fuser -$sig -mvk $dir - fi - sleep .5 - if ! $found_pids; then - return 0 - fi - done - return 1 + for sig; do + echo kill-dir $sig + found_pids=false + if pids=$(timeout 4 lsof -t $dir); then + found_pids=true + timeout 4 lsof -w $dir + kill -$sig $pids + fi + # fuser will find open sockets that lsof won't, for example from gpg-agent. + # note: -v shows kernel processes, which then doesn't return true when we want + if timeout 4 fuser -m $dir &>/dev/null; then + found_pids=true + fuser -$sig -mvk $dir + fi + sleep .5 + if ! $found_pids; then + return 0 + fi + done + return 1 } force=false if [[ $1 == -f ]]; then - force=true + force=true fi ret=0 @@ -125,7 +125,7 @@ shopt -s nullglob # to home directories f=(/mnt/root/btrbk/q.*) if [[ -e $f ]]; then - fstab </dev/null; then - continue - fi + d=/$vol + if ! awk '{print $2}' /etc/fstab | grep -xF $d &>/dev/null; then + continue + fi - ##### begin building up list of bind mounts ###### - binds=() # list of bind mounts - roots=($d) # list of bind mounts, plus the original mount - while true; do - new_roots=() - for r in ${roots[@]}; 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+bind\s.*#\1#p" /etc/fstab)) - done - (( ${#new_roots} )) || break - binds+=(${new_roots[@]}) - roots=( ${new_roots[@]} ) + ##### begin building up list of bind mounts ###### + binds=() # list of bind mounts + roots=($d) # list of bind mounts, plus the original mount + while true; do + new_roots=() + for r in ${roots[@]}; 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+bind\s.*#\1#p" /etc/fstab)) done - ##### end building up list of bind mounts ###### - + (( ${#new_roots} )) || break + binds+=(${new_roots[@]}) + roots=( ${new_roots[@]} ) + done + ##### end building up list of bind mounts ###### - # if latest is already mounted, make sure binds are mounted and move on - if e check-subvol-stale $d; then - mnt $d - for b in ${binds[@]}; do - mnt $b - done - continue - fi - fresh_snap=$( leaf_secs )); then # 60 days + e btrfs sub del $leaf + fi + done + fi + # Note, we make a few assumptions in this script, like + # $d was not a different subvol id than $vol, and + # things otherwise didn't get mounted very strangely. + e btrfs sub snapshot $fresh_snap $vol + for dir in $d ${binds[@]}; do + e mnt $dir + done + stale_dir=/nocow/btrfs-stale + rm -f $stale_dir/$d done ### disabled if [[ $HOSTNAME == kdxxxxxxxxx ]]; then - # partitioned it with fai partitioner outside of fai, - # because it\'s worth it to have 1% space reserved for boot and - # swap partitions in case I ever want to boot off those drives. - # as root: - # . /a/bin/fai/fai-wrapper - # eval-fai-classfile /a/bin/fai/fai/config/class/51-multi-boot - # fai-setclass ROTATIONAL - # export LUKS_DIR=/q/root/luks/ - # # because the partition nums existed already - # fai-setclass REPARTITION - # /a/bin/fai/fai/config/hooks/partition.DEFAULT + # partitioned it with fai partitioner outside of fai, + # because it\'s worth it to have 1% space reserved for boot and + # swap partitions in case I ever want to boot off those drives. + # as root: + # . /a/bin/fai/fai-wrapper + # eval-fai-classfile /a/bin/fai/fai/config/class/51-multi-boot + # fai-setclass ROTATIONAL + # export LUKS_DIR=/q/root/luks/ + # # because the partition nums existed already + # fai-setclass REPARTITION + # /a/bin/fai/fai/config/hooks/partition.DEFAULT - devs=( - ata-TOSHIBA_MD04ACA500_84REK6NTFS9A-part1 - ata-TOSHIBA_MD04ACA500_84R2K773FS9A-part1 - ata-TOSHIBA_MD04ACA500_8471K430FS9A-part1 - ata-TOSHIBA_MD04ACA500_8481K493FS9A-part1 - ) - first=true - for dev in ${devs[@]}; do - if $first; then - first=false - tu /etc/fstab <