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() {
+ 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
+fi
ret=0
##### begin setup fstab for subvols we care about ######
first_root_crypt=$(awk '$2 == "/" {print $1}' /etc/mtab)
-tu /etc/fstab <<EOF
+fstab <<EOF
$first_root_crypt /a btrfs noatime,subvol=a 0 0
EOF
-case $HOSTNAME in
- treetowl|x2|frodo)
- tu /etc/fstab <<EOF
-$first_root_crypt /q btrfs noatime,subvol=q 0 0
-$first_root_crypt /o btrfs noatime,subvol=o 0 0
+
+shopt -s nullglob
+
+# ssh and probably some other things care about parent directory
+# 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.*)
+if [[ -e $f ]]; then
+ fstab <<EOF
+$first_root_crypt /q btrfs noatime,subvol=q,gid=1000 0 0
/q/p /p none bind 0 0
+EOF
+fi
+
+f=(/mnt/root/btrbk/o.*)
+if [[ -e $f ]]; then
+ fstab <<EOF
+$first_root_crypt /o btrfs noatime,subvol=o 0 0
/o/m /m none bind 0 0
EOF
- ;;
-esac
+fi
+
+if [[ $HOSTNAME == frodo ]]; then
+ fstab <<EOF
+$first_root_crypt /i btrfs noatime,subvol=i 0 0
+EOF
+fi
##### end setup fstab for subvols we care about ######
-for vol in q a o; do
+for vol in q a o i; do
d=/$vol
if ! awk '{print $2}' /etc/fstab | grep -xF $d &>/dev/null; then
continue
if e umount -R $dir; then
unmounted+=($dir)
else
- umount_ret=false
- ret=1
- echo "$0: failed to umount $dir"
- e lsof $dir
- break
+ if ! kill-dir TERM TERM TERM INT INT HUP HUP; then
+ if $force; then kill-dir KILL; fi
+ fi
+
+ if e umount -R $dir; then
+ unmounted+=($dir)
+ else
+ echo "$0: failed to umount $dir"
+ umount_ret=false
+ ret=1
+ continue
+ fi
fi
fi
done