From ef8f3322f390e3a35bf2117af0dfe3266db2405f Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 15 Apr 2023 02:15:42 +1000 Subject: [PATCH] Restart server if it double-forks Processes that double-fork themselves by double-forking cannot be waited upon, and cannot be properly monitored. The ARK server will sometimes restart itself by performing a fork and execve instead of just an execve (presumably because that is what it has to do under Windows). If the server restarts itself, then we need to restart it again so it can be properly monitored. --- tools/arkmanager | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index 9d1d780..1faea7f 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -980,6 +980,8 @@ function getServerPID(){ if kill -0 "$serverpid" >/dev/null 2>&1; then echo "$serverpid" return + elif kill -0 "-$serverpid" >/dev/null 2>&1; then + pgrep -g "$serverpid" && return fi fi if [ -f "${arkserverroot}/${arkserveroldpidfile}" ]; then @@ -987,6 +989,8 @@ function getServerPID(){ if kill -0 "$serverpid" >/dev/null 2>&1; then echo "$serverpid" return + elif kill -0 "-$serverpid" >/dev/null 2>&1; then + pgrep -g "$serverpid" && return fi fi } @@ -1316,13 +1320,16 @@ doRun() { notify "${notifyMsgShuttingDown:-Shutting down}" rm -f "$arkserverroot/$arkautorestartfile" if [ "$serverpid" -ne 0 ]; then - kill -INT $serverpid >/dev/null 2>&1 + kill -INT -$serverpid >/dev/null 2>&1 fi exit 0 } trap shutdown_server INT TERM + # Enable job control so server gets its own process group + set -m + # Auto-restart loop while [ $restartserver -ne 0 ]; do echo -n "$(timestamp): Running" @@ -1374,21 +1381,40 @@ doRun() { echo "$(timestamp): Restarting server" notify "${notifyMsgStoppedListening:-Server has stopped listening - restarting}" for (( i = 0; i < 5; i++ )); do - if ! kill -0 "$serverpid"; then + if ! kill -0 "-$serverpid"; then break fi - kill -INT "$serverpid" + kill -INT "-$serverpid" sleep 5 done - if kill -0 "$serverpid"; then + if kill -0 "-$serverpid"; then echo "$(timestamp): Graceful restart failed - killing server" - kill -KILL "$serverpid" + kill -KILL "-$serverpid" fi # Exit the server check loop break fi fi + elif [ "$pid" == "$(pgrep --pgroup $serverpid)" ]; then + restartserver=1 + echo "${timestamp}: Server has double-forked and cannot be effectively monitored" + echo "${timestamp}: Restarting server" + notify "${notifyMsgDoubleForked:-Server has daemonized itself - restarting}" + for (( i = 0; i < 5; i++ )); do + if ! kill -0 "-$serverpid"; then + break + fi + kill -INT "-$serverpid" + sleep 5 + done + if kill -0 "-$serverpid"; then + echo "$(timestamp): Graceful restart failed - killing server" + kill -KILL "-$serverpid" + fi + + # Exit the server check loop + break else echo "$(timestamp): Bad PID '$pid'; expected '$serverpid'" if [ "$pid" != "" ]; then