@@ -141,6 +141,10 @@ select_canonicalize_tool() {
141141select_canonicalize_tool
142142
143143select_lsof_timeout_tool () {
144+ if command -v python3 > /dev/null 2>&1 ; then
145+ lsof_timeout_tool=" python3"
146+ return
147+ fi
144148 if command -v gtimeout > /dev/null 2>&1 ; then
145149 lsof_timeout_tool=" gtimeout"
146150 return
@@ -149,15 +153,29 @@ select_lsof_timeout_tool() {
149153 lsof_timeout_tool=" timeout"
150154 return
151155 fi
152- if command -v python3 > /dev/null 2>&1 ; then
153- lsof_timeout_tool=" python3"
154- return
155- fi
156156 lsof_timeout_tool=" "
157157}
158158
159159select_lsof_timeout_tool
160160
161+ resolve_disk_identifier () {
162+ local target=" $1 "
163+ if [[ " ${target} " =~ ^/dev/disk[0-9]+$ ]]; then
164+ printf ' %s\n' " ${target} "
165+ return 0
166+ fi
167+ if ! command -v diskutil > /dev/null 2>&1 ; then
168+ return 0
169+ fi
170+ local disk_name=" "
171+ disk_name=" $(
172+ diskutil info " ${target} " 2> /dev/null | awk -F' : *' ' /Part of Whole/ {print $2; exit}'
173+ ) "
174+ if [[ " ${disk_name} " =~ ^disk[0-9]+$ ]]; then
175+ printf ' /dev/%s\n' " ${disk_name} "
176+ fi
177+ }
178+
161179detach_target () {
162180 local target=" $1 "
163181 local pass=1
@@ -170,7 +188,11 @@ detach_target() {
170188 return 0
171189 fi
172190 if command -v diskutil > /dev/null 2>&1 ; then
173- diskutil unmountDisk force " ${target} " > /dev/null 2>&1 || true
191+ local disk_target=" "
192+ disk_target=" $( resolve_disk_identifier " ${target} " ) "
193+ if [[ " ${disk_target} " =~ ^/dev/disk[0-9]+$ ]]; then
194+ diskutil unmountDisk force " ${disk_target} " > /dev/null 2>&1 || true
195+ fi
174196 diskutil unmount force " ${target} " > /dev/null 2>&1 || true
175197 fi
176198 hdiutil detach -force " ${target} " > /dev/null 2>&1 || true
@@ -324,11 +346,22 @@ kill_mount_holders() {
324346 if [ " ${lsof_timeout_tool} " = " gtimeout" ] || [ " ${lsof_timeout_tool} " = " timeout" ]; then
325347 local lsof_output=" "
326348 local lsof_status=0
349+ local started_at=0
350+ local ended_at=0
351+ local elapsed=0
352+ started_at=" $( date +%s 2> /dev/null || echo 0) "
327353 lsof_output=" $( " ${lsof_timeout_tool} " " ${lsof_timeout_seconds} " lsof -t +D " ${mount_point} " 2> /dev/null) " || lsof_status=$?
328- if [ " ${lsof_status} " -eq 124 ] || [ " ${lsof_status} " -eq 137 ]; then
354+ ended_at=" $( date +%s 2> /dev/null || echo 0) "
355+ if [ " ${started_at} " -gt 0 ] && [ " ${ended_at} " -ge " ${started_at} " ]; then
356+ elapsed=$(( ended_at - started_at))
357+ fi
358+ if [ " ${lsof_status} " -ne 0 ] && [ " ${elapsed} " -ge " ${lsof_timeout_seconds} " ]; then
329359 echo " WARN: lsof timed out while scanning ${mount_point} ; skip mount-holder cleanup." >&2
330360 return 0
331361 fi
362+ if [ " ${lsof_status} " -ne 0 ] && [ -z " ${lsof_output} " ]; then
363+ return 0
364+ fi
332365 holder_pids=" $( printf ' %s\n' " ${lsof_output} " | awk ' NF' | sort -u) "
333366 elif [ " ${lsof_timeout_tool} " = " python3" ]; then
334367 local lsof_output=" "
@@ -358,10 +391,13 @@ if proc.stdout:
358391sys.exit(proc.returncode)
359392PY
360393 ) " || lsof_status=$?
361- if [ " ${lsof_status} " -eq 124 ] || [ " ${lsof_status} " -eq 137 ] ; then
394+ if [ " ${lsof_status} " -eq 124 ]; then
362395 echo " WARN: lsof timed out while scanning ${mount_point} ; skip mount-holder cleanup." >&2
363396 return 0
364397 fi
398+ if [ " ${lsof_status} " -ne 0 ] && [ -z " ${lsof_output} " ]; then
399+ return 0
400+ fi
365401 holder_pids=" $( printf ' %s\n' " ${lsof_output} " | awk ' NF' | sort -u) "
366402 else
367403 holder_pids=" $( lsof -t +D " ${mount_point} " 2> /dev/null | awk ' NF' | sort -u || true) "
0 commit comments