@@ -379,21 +379,22 @@ function check_ps_blacklist() {
379379}
380380
381381# Check to make sure a service is (or isn't) running. Syntax:
382- # check_ps_service [-0] [-f] [-S|-r|-c|-s|-k] [-u <user>] [-d <daemon> | -m <match>] [ -e <action> | -E <action> ] <service>
382+ # check_ps_service [-0] [-f] [-v|-V] [- S|-r|-c|-s|-k] [-u <user>] [-d <daemon> | -m <match>] [ -e <action> | -E <action> ] <service>
383383function check_ps_service() {
384- local SERVICE OWNER MATCH DAEMON NONFATAL=0 FULLMATCH=0 RESTART=0 CYCLE=0 START=0 STOP=0 KILL=0 ACTION FOUND_ACTION
385- local THIS_PID THIS_SVC i MSG
384+ local SERVICE OWNER MATCH DAEMON NONFATAL=0 FULLMATCH=0 RESTART=0 CYCLE=0 START=0 STOP=0 KILL=0 VERIFY_SYNC=0 VERIFY_CHECK=0
385+ local ACTION FOUND_ACTION THIS_PID THIS_SVC i MSG RET
386386 local -a ARGS
387387
388388 if [[ ${#PS_PROCS[*]} -eq 0 ]]; then
389389 nhc_ps_gather_data
390390 fi
391391
392392 OPTIND=1
393- while getopts ":0Sfrcsku :d:m:e:E:" OPTION ; do
393+ while getopts ":0VSfrcskvu :d:m:e:E:" OPTION ; do
394394 case "$OPTION" in
395395 0) NONFATAL=1 ;;
396396 S) START=1 ;;
397+ V) VERIFY_CHECK=1 ;;
397398 f) FULLMATCH=1 ;;
398399 r) RESTART=1 ;;
399400 c) CYCLE=1 ;;
@@ -404,6 +405,7 @@ function check_ps_service() {
404405 m) MATCH="$OPTARG" ;;
405406 e) ACTION="$OPTARG" ;;
406407 E) FOUND_ACTION="$OPTARG" ;;
408+ v) VERIFY_SYNC=1 ;;
407409 :) die 1 "$FUNCNAME: Option -$OPTARG requires an argument." ; return 1 ;;
408410 \?) die 1 "$FUNCNAME: Invalid option: -$OPTARG" ; return 1 ;;
409411 esac
@@ -451,12 +453,62 @@ function check_ps_service() {
451453 # Logic is inverted; we DON'T want this process running, so finding it is a failure.
452454 MSG="$FUNCNAME: Service $SERVICE (process $DAEMON) ${OWNER:+owned by $OWNER }running"
453455 if [[ "$KILL" == "1" ]]; then
454- [[ "$SHELL" != ":" ]] && kill -9 $THIS_PID
455- MSG="$MSG; killed process ID $THIS_PID"
456+ if [[ "$SHELL" != ":" ]]; then
457+ kill -9 $THIS_PID
458+ RET=$?
459+ if [[ $VERIFY_SYNC -eq 1 ]]; then
460+ # VERIFY_SYNC here only means we check the return value of the kill built-in.
461+ if [[ $RET -eq 0 ]]; then
462+ log "$MSG; process ID $THIS_PID killed successfully."
463+ continue
464+ else
465+ MSG="$MSG; \"kill -9 $THIS_PID\" failed (exit code $RET)."
466+ fi
467+ elif [[ $VERIFY_CHECK -eq 1 ]]; then
468+ # VERIFY_CHECK here means we kill the PID again and make sure it's gone.
469+ # Sleep very briefly to yield CPU, hopefully ensuring signal delivery.
470+ sleep 0.01
471+ if [[ $RET -ne 0 ]]; then
472+ MSG="$MSG; \"kill -9 $THIS_PID\" failed (exit code $RET)."
473+ elif kill -0 $THIS_PID ; then
474+ MSG="$MSG; \"kill -9 $THIS_PID\" succeeded but failed to terminate process."
475+ else
476+ log "$MSG; process ID $THIS_PID terminated successfully."
477+ return 0
478+ fi
479+ else
480+ MSG="$MSG; killed process ID $THIS_PID (SIGKILL)"
481+ fi
482+ else
483+ MSG="$MSG; killed process ID $THIS_PID (test mode)"
484+ fi
456485 else
457486 # $STOP must be 1
458487 ${SHELL:-/bin/bash} -c "/sbin/service $SERVICE stop" &
459- MSG="$MSG; termination in progress"
488+ if [[ "$SHELL" == ":" ]]; then
489+ MSG="$MSG; termination in progress"
490+ elif [[ $VERIFY_SYNC -eq 1 || $VERIFY_CHECK -eq 1 ]]; then
491+ # In VERIFY mode, we must "foreground" the service action to check its return value.
492+ wait $!
493+ RET=$?
494+ if [[ $RET -ne 0 ]]; then
495+ # If the "stop" fails, both VERIFY modes do the same thing.
496+ MSG="$MSG; \"/sbin/service $SERVICE stop\" failed (exit code $RET)."
497+ elif [[ $VERIFY_CHECK -eq 1 ]]; then
498+ # VERIFY_CHECK mode requires that we also make sure the PID is really gone now.
499+ if kill -0 $THIS_PID ; then
500+ MSG="$MSG; \"/sbin/service $SERVICE stop\" succeeded but failed to stop process $THIS_PID."
501+ else
502+ log "$MSG; service $SERVICE stopped and process $THIS_PID terminated successfully."
503+ return 0
504+ fi
505+ else
506+ log "$MSG; service $SERVICE stopped successfully."
507+ return 0
508+ fi
509+ else
510+ MSG="$MSG; service termination in progress"
511+ fi
460512 fi
461513 if [[ $NONFATAL == 1 ]]; then
462514 if [[ -n "$MSG" ]]; then
0 commit comments