slam_tomb(): don't parse process output and rework

In #504 list_processes() got reworked in a way to avoid parsing process
output as this had interesting side-effects.
Back then I mentioned the same behaviour existing in slam_tomb() which
should probably be changed too. This PR addresses that.
Firstly it will use list_processes() from within slam_tomb(), as this is
in principal overlapping functionality. For this list_processes() needed
to be adjusted. It now has a return value which can indicate if there
were processes.
Secondly the order of execution was changed in slam_tomb(). Before it
would process one process and work through the signals until this
process was killed. Now it will take a signal and issue a kill for all
processes found.
This commit is contained in:
Narrat 2024-08-08 12:43:21 +02:00 committed by Jaromil
parent 0ef195dff0
commit 284fb4a3cd

52
tomb
View File

@ -3004,22 +3004,24 @@ umount_tomb() {
list_processes() { list_processes() {
# $1 = (optional) name of tomb # $1 = (optional) name of tomb
# runs lsof on the mounted_tombs # runs lsof on the mounted_tombs
local mounted_tombs i local mounted_tombs i indicator lsofres
indicator=1 # != 0 means there were processes
mounted_tombs=(`list_tomb_mounts $1`) mounted_tombs=(`list_tomb_mounts $1`)
if [[ "${#mounted_tombs}" -gt 0 ]]; then if [[ "${#mounted_tombs}" -gt 0 ]]; then
if [[ -z $1 ]]; then if [[ -z $1 ]]; then
_success "Listing processes running inside all open tombs..." _success "Looking for processes running inside all open tombs..."
else else
_success "Listing processes running inside tomb '::1 tombname::'..." "$1" _success "Looking for processes running inside tomb '::1 tombname::'..." "$1"
fi fi
for i in ${mounted_tombs}; do for i in ${mounted_tombs}; do
_verbose "scanning tomb: ::1 tombmount::" $i _verbose "scanning tomb: ::1 tombmount::" $i
tombmount="${i[(ws:;:)2]}" lsofres=$(_sudo lsof +D "${i[(ws:;:)2]}")
_sudo lsof +D "${i[(ws:;:)2]}" # Check on output, as $? will always return 1 for whatever reasons
[[ -n $lsofres ]] && { indicator=0; echo $lsofres } || { _success "None found" }
done done
fi fi
return 0 return $indicator
} }
# Kill all processes using the tomb # Kill all processes using the tomb
@ -3040,7 +3042,7 @@ slam_tomb() {
_warning "or issue the command 'tomb close all' to close them all." _warning "or issue the command 'tomb close all' to close them all."
_failure "Operation aborted." } _failure "Operation aborted." }
local pnum puid pcmd powner result local pnum result lsofres
result=0 result=0
# iterate through all mounted tomb affected # iterate through all mounted tomb affected
for i in ${mounted_tombs}; do for i in ${mounted_tombs}; do
@ -3048,28 +3050,32 @@ slam_tomb() {
tombmount="${i[(ws:;:)2]}" tombmount="${i[(ws:;:)2]}"
_success "Slamming tomb ::1 tombname:: mounted on ::2 tombmount::" \ _success "Slamming tomb ::1 tombname:: mounted on ::2 tombmount::" \
${tombname} "${tombmount}" ${tombname} "${tombmount}"
# iterate through all processes running in mounted tombs list_processes "${tombname:1:-1}"
for pnum in ${(f)"$(_sudo lsof -t +D "$tombmount")"}; do [[ $? -eq 0 ]] && {
puid=$(cat /proc/${pnum}/loginuid) # iterate through 3 different signals, break on success
pcmd=$(cat /proc/${pnum}/cmdline)
powner=`_get_username $puid`
_verbose "process found: $pnum $pcmd ($powner)"
# iterate through 3 different signals to send, break on success
for s in TERM HUP KILL; do for s in TERM HUP KILL; do
_message "::1 tombname:: sending ::2 sig:: to ::3 cmd:: (::4 uid::)" \ lsofres=(`_sudo lsof -t +D "$tombmount"`)
${tombname} ${s} ${pcmd} ${powner} [[ -n $lsofres ]] && {
# iterate through all processes before switching signals
for pnum in $lsofres; do
_message "::1 tombname:: sending ::2 sig:: to open process ::3 pnum::" \
${tombname} ${s} ${pnum}
_sudo kill -$s $pnum _sudo kill -$s $pnum
done
} || { break }
# give some time to the process for a clean quit # give some time to the process for a clean quit
sleep .5 sleep .5
# stop sending other signals if kill was succesfull
[[ -r /proc/$pnum ]] || break
done done
# if process still running then signal failure }
[[ -r /proc/$pnum ]] && {
_warning "Can't kill ::1 process:: ::2 pcmd:: (::3 powner::)" \ # if there are still processes then signal failure
$pnum $pcmd $powner lsofres=(`_sudo lsof -t +D "$tombmount"`)
result=1 } [[ -n $lsofres ]] && {
for pnum in $lsofres; do
_warning "Couldn't kill ::1 pnum::" $pnum
done done
result=1
}
# if it failed killing a process, report it # if it failed killing a process, report it
[[ $result = 0 ]] && umount_tomb "${tombname:1:-1}" [[ $result = 0 ]] && umount_tomb "${tombname:1:-1}"
done done