Improve mount detection and better able to umount problem mounts

Disable xtrace (-x) during execution since it was too verbose
pull/1/head
Jason Mehring 9 years ago
parent 00bf130052
commit d9282fceaf

@ -1,4 +1,5 @@
#!/bin/bash -e #!/bin/bash -e
# vim: set ts=4 sw=4 sts=4 et :
# #
# Written by Jason Mehring (nrgaway@gmail.com) # Written by Jason Mehring (nrgaway@gmail.com)
@ -9,7 +10,7 @@
# #
# To keep the actual mount mounted, add a '/' to end # To keep the actual mount mounted, add a '/' to end
# #
# $1: directory to umount # ${1}: directory to umount
# #
# Examples: # Examples:
# To kill all processes and mounts within 'chroot-jessie' but keep # To kill all processes and mounts within 'chroot-jessie' but keep
@ -25,55 +26,87 @@
. ./functions.sh . ./functions.sh
# $1 = full path to mount; mountPoint() {
# $2 = if set will not umount; only kill processes in mount local mount_point="${1}"
umount_kill() {
MOUNTDIR="$1"
# We need absolute paths here so we don't kill everything # We need absolute paths here so we don't kill everything
if ! [[ "${MOUNTDIR}" = /* ]]; then if ! [[ "${mount_point}" = /* ]]; then
MOUNTDIR="${PWD}/${MOUNTDIR}" mount_point="$(readlink -m .)/${mount_point}"
fi fi
# Strip any extra trailing slashes ('/') from path if they exist # Strip any extra trailing slashes ('/') from path if they exist
# since we are doing an exact string match on the path # since we are doing an exact string match on the path
MOUNTDIR=$(echo "${MOUNTDIR}" | sed s#//*#/#g) echo "$(echo "${mount_point}" | sed s#//*#/#g)"
}
mountPoints() {
local mount_point="$(mountPoint "${1}")"
echo "$(sudo grep "${mount_point}" /proc/mounts | cut -f2 -d" " | sort -r | grep "^${mount_point}")"
}
# ${1} = full path to mountpoint;
# ${2} = if set will not umount; only kill processes in mount
umount_kill() {
# Turn off xtrace; but remember its current setting
local xtrace=$(getXtrace) && set +x
# Sync the disk befoe un-mounting to be sure everything is written local mount_point="$(mountPoint "${1}")"
local kill_only="${2}"
declare -A cache
# Sync the disk before un-mounting to be sure everything is written
sync sync
warn "-> Attempting to kill any processes still running in '${MOUNTDIR}' before un-mounting" output "${red}Attempting to kill any processes still running in '${mount_point}' before un-mounting${reset}"
for dir in $(sudo grep "${MOUNTDIR}" /proc/mounts | cut -f2 -d" " | sort -r | grep "^${MOUNTDIR}") mounts="$(mountPoints "${mount_point}")"
for dir in ${mounts[@]}
do do
sudo lsof "$dir" 2> /dev/null | \ # Escape filename (convert spaces to '\ ', etc
grep "$dir" | \ dir="$(printf "${dir}")"
# Skip if already in cache
[[ ${cache["${dir}"]+_} ]] && continue || cache["${dir}"]=1
# Kill of any processes within mountpoint
sudo lsof "${dir}" 2> /dev/null | \
grep "${dir}" | \
tail -n +2 | \ tail -n +2 | \
awk '{print $2}' | \ awk '{print $2}' | \
xargs --no-run-if-empty sudo kill -9 xargs --no-run-if-empty sudo kill -9
if ! [ "$2" ] && $(mountpoint -q "$dir"); then # Umount
info "un-mounting $dir" if ! [ "${kill_only}" ]; then
sudo umount -n "$dir" 2> /dev/null || \
sudo umount -n -l "$dir" 2> /dev/null || \ # Mount point found in mtab
error "umount $dir unsuccessful!" if $(sudo /usr/bin/mountpoint -q "${dir}"); then
elif ! [ "$2" ]; then info "umount ${dir}"
# Look for (deleted) mountpoints sudo umount -n "${dir}" 2> /dev/null || \
info "not a regular mount point: $dir" sudo umount -n -l "${dir}" 2> /dev/null || \
base=$(basename "$dir") error "umount ${dir} unsuccessful!"
dir=$(dirname "$dir")
base=$(echo "$base" | sed 's/[\].*$//') # Umount entries not found within '/usr/bin/mountpoint'
dir="$dir/$base" else
sudo umount -v -f -n "$dir" 2> /dev/null || \ # Look for (deleted) mountpoints
sudo umount -v -f -n -l "$dir" 2> /dev/null || \ info "not a regular mount point: ${dir}"
error "umount $dir unsuccessful!" base="$(basename "${dir}")"
dir="$(dirname "${dir}")"
base="$(echo "${base}" | sed 's/[\].*$//')"
dir="${dir}/${base}"
sudo umount -v -f -n "${dir}" 2> /dev/null || \
sudo umount -v -f -n -l "${dir}" 2> /dev/null || \
error "umount ${dir} unsuccessful!"
fi
fi fi
done done
# Return xtrace to original state
setXtrace "${xtrace}"
} }
kill_processes_in_mount() { kill_processes_in_mount() {
umount_kill $1 "false" || : umount_kill ${1} "false" || :
} }
if [ $(basename "$0") == "umount_kill.sh" -a "$1" ]; then if [ $(basename "${0}") == "umount_kill.sh" -a "${1}" ]; then
umount_kill "$1" umount_kill "${1}"
fi fi

Loading…
Cancel
Save