Improve mount detection and better able to umount problem mounts
Disable xtrace (-x) during execution since it was too verbose
This commit is contained in:
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)"
|
||||||
|
}
|
||||||
|
|
||||||
# Sync the disk befoe un-mounting to be sure everything is written
|
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
|
||||||
|
|
||||||
|
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…
Reference in New Issue
Block a user