Skip to content

Instantly share code, notes, and snippets.

@WoozyMasta
Last active March 12, 2024 12:25
Show Gist options
  • Save WoozyMasta/3c3aaf8d1b1517e9ee47c6b2a96fee96 to your computer and use it in GitHub Desktop.
Save WoozyMasta/3c3aaf8d1b1517e9ee47c6b2a96fee96 to your computer and use it in GitHub Desktop.
DayZ Linux Server watchdog

DayZ Linux Server watchdog

This DayZ Watchdog script to check server availability

With the release of DayZ 1.24, a server for Linux appeared, this is undoubtedly very cool, but the implementation was in an experimental state for a very long time, which is why some problems crop up when trying to run modified community servers.

At the time of writing, there was a problem with the scheduled restart of the modified server based on an event from messages.xml. Details at https://feedback.bistudio.com/T179734

Important

These are instructions for a non-system user; for a root user you can adapt them yourself if necessary

Setup

Note

List of system utilities required for work, make sure that all are available on your system
nc, stat, grep (GNU), date, systemctl, cut, sleep

Setup script

mkdir -p ~/.local/bin/
curl -#SfLo ~/.local/bin/dayz-watchdog \
  https://gist.githubusercontent.com/WoozyMasta/3c3aaf8d1b1517e9ee47c6b2a96fee96/raw/dayz-watchdog
chmod +x ~/.local/bin/dayz-watchdog

Let's check that ~/.local/bin is in PATH and if not add it

[[ ":$PATH:" != *":$HOME/.local/bin:"* ]] && \
  printf '\n#[ -d "$HOME/.local/bin" ] && PATH="$HOME/.local/bin:$PATH"\n' >> ~/.profile

Let's run it once, as arguments we pass all the names of systemd services that we will check

dayz-watchdog dayz-server.service

Schedule run script

Download systemd service and timer

mkdir -p ~/.config/systemd/user/
curl -#SfLo ~/.config/systemd/user/dayz-watchdog.service \
  https://gist.githubusercontent.com/WoozyMasta/3c3aaf8d1b1517e9ee47c6b2a96fee96/raw/dayz-watchdog.service
curl -#SfLo ~/.config/systemd/user/dayz-watchdog.timer \
  https://gist.githubusercontent.com/WoozyMasta/3c3aaf8d1b1517e9ee47c6b2a96fee96/raw/dayz-watchdog.timer

Edit arguments in ExecStart= property

editor ~/.config/systemd/user/dayz-watchdog.service

Edit scheduller in OnCalendar= property, default is every minute

editor ~/.config/systemd/user/dayz-watchdog.service

Enable and start timer

systemctl --user daemon-reload
systemctl --user start dayz-watchdog.timer
systemctl --user enable dayz-watchdog.timer
systemctl --user status dayz-watchdog.service
journalctl --user -eu dayz-watchdog
#!/usr/bin/env bash
# DayZ watchdog
# issue: https://feedback.bistudio.com/T179734
# required: nc stat grep date systemctl cut sleep
# place in: .local/bin/dayz-watchdog
# usage: dayz-watchdog dayz-server@1 dayz-server@2 dayz-server@3 dayz-server@4
set -euo pipefail
[ $# -eq 0 ] && { >&2 echo "Need pass servce names as args"; exit 1; }
watchtime=$(date +%s)
check() {
local unit="$1" pid port
pid="$(systemctl --user show "$unit" --property MainPID | cut -d= -f2)"
# Skip PIDs younger than 5 minutes
[ "$(( watchtime - "$(stat -c %Y "/proc/$pid")" ))" -le 300 ] && return 0
port=$(grep -aoP -- '-port=\K\d+' "/proc/$pid/cmdline")
if ! nc -vzu 127.0.0.1 "$port" 2>/dev/null; then
# One more try
nc -vzu 127.0.0.1 "$port" 2>/dev/null && return 0
# As tests have shown, SIGHUP will correctly terminate a frozen process
kill -s HUP "$pid"
>&2 echo "DayZ service: $unit PID: $pid stopped by watchdog"
# Wait 30 seconds for completion, otherwise we kill forcibly
for (( i=0; i<30; i++ )); do
[ ! -d "/proc/$pid/" ] && return 0
sleep 1s
done
[ -d "/proc/$pid/" ] && kill -9 "$pid"
>&2 echo "DayZ service: $unit PID: $pid killed by watchdog"
fi
}
for unit in "$@"; do
# run only for runing services
systemctl --user is-active --quiet "$unit" && check "$unit" &
done
wait
# .config/systemd/user/dayz-watchdog.service
[Unit]
Description=Watchdog DayZ Server
Wants=dayz-watchdog.timer
[Service]
Type=oneshot
ExecStart=/home/ts4ta/.local/bin/dayz-watchdog dayz-server@1 dayz-server@2 dayz-server@3 dayz-server@4 dayz-server@5
[Install]
WantedBy=default.target
# .config/systemd/user/dayz-watchdog.timer
[Unit]
Description=Watchdog DayZ Server
Requires=dayz-watchdog.service
[Timer]
Unit=dayz-watchdog.service
Persistent=true
OnCalendar=*-*-* *:*:00
[Install]
WantedBy=timers.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment