X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=mount-latest-subvol;h=d7be613c763d122d0259b5a434ca4a161f599627;hb=f7a2fe0e56e14b55818245a2e3a2eb68f1cd23de;hp=73709316d39b79dac8865aef265b0496574d0fc2;hpb=9eeed9d8bd24850fe5e35d2c2f9be8608491bf70;p=distro-setup diff --git a/mount-latest-subvol b/mount-latest-subvol index 7370931..d7be613 100644 --- a/mount-latest-subvol +++ b/mount-latest-subvol @@ -1,4 +1,19 @@ #!/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: mount-latest-subvol [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@" @@ -17,7 +32,7 @@ errcatch() { set -o pipefail } bash-trace() { - local -i argc_index=0 arg frame i start=${1:-1} max_indent=8 indent + 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 @@ -53,57 +68,119 @@ tu() { e() { printf "%s\n" "$*"; "$@"; } mnt() { dir=$1 - if ! mountpoint $dir >/dev/null; then + 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 +} +kill-dir() { + found_pids=false + sig=${1:-TERM} + 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 + if $found_pids; then + sleep .5 + return 0 + fi + return 1 +} + +force=false +if [[ $1 == -f ]]; then + force=true +fi ret=0 +##### begin setup fstab for subvols we care about ###### first_root_crypt=$(awk '$2 == "/" {print $1}' /etc/mtab) -tu /etc/fstab </dev/null; then continue fi - binds=() - roots=($d) + ##### 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 - # /q/a /a none bind 0 0 + # 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[@]} ) 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 - last_snap=$(