Auto-Restart on Crash (hlds_run and Wrapper Scripts)

May 21, 2025 Daemon666 8 min read 12 vizualizări

A CS 1.6 server process will eventually die on its own — a bad plugin, a malformed packet, an out-of-memory kill, or the classic SegV. If nothing is watching, it stays down until you notice, and on a public server that is empty slots and lost regulars. The good news is that the stock launcher already restarts a crashed server; the job is to understand what it does and layer a supervisor on top for the cases it cannot cover.

1. Understand what hlds_run already does

On Linux you do not launch the game binary directly — you launch hlds_run, a shell wrapper that execs the real hlds_linux engine and then loops. When the engine exits with a non-zero status (a crash), hlds_run restarts it automatically. When it exits cleanly (you typed quit), it stays down. That single behavior handles the majority of crashes for free:

./hlds_run -game cstrike +ip 0.0.0.0 -port 27015 \
  +map de_dust2 +maxplayers 20 -pingboost 1

The relevant flags:

  • -pingboost 1|2|3 — alternate timing loops; 1 is the safe default, higher values reduce latency at a CPU cost.
  • -norestartdisables the auto-restart loop. If your server dies and stays dead, check that this flag is not present.
  • -autoupdate — runs the updater between restarts. Leave it off unless you actually want that on every crash, because it slows recovery.

2. Why hlds_run is not enough by itself

The wrapper restarts a crashed engine, but it cannot help if the whole hlds_run process is killed — an OOM kill, an admin closing the terminal, a reboot. If you started the server over SSH without a persistent session, closing the connection takes the server with it. You need something that keeps hlds_run itself alive and detached from your login.

3. Option A: a screen or tmux loop

The lightweight approach is a detached screen session running a small restart loop, so both the engine and the wrapper are supervised:

#!/bin/bash
# start.sh
cd /home/steam/hlds
while true; do
  ./hlds_run -game cstrike +ip 0.0.0.0 -port 27015 \
    +map de_dust2 +maxplayers 20 -pingboost 1
  echo "server exited at $(date), restarting in 3s" >> restart.log
  sleep 3
done
screen -dmS cs ./start.sh    # start detached
screen -r cs                 # re-attach later (Ctrl-A D to detach)

The sleep 3 matters: without a small delay, a server that crashes instantly on load will spin in a tight loop and hammer the CPU. This survives SSH disconnects, but not a machine reboot — for that you need a service manager.

4. Option B: a systemd unit (recommended)

On a modern Linux box, let systemd be the supervisor. It restarts on crash, starts on boot, throttles restart storms, and captures logs. Create /etc/systemd/system/cs16.service:

[Unit]
Description=CS 1.6 Server
After=network.target

[Service]
Type=simple
User=steam
WorkingDirectory=/home/steam/hlds
ExecStart=/home/steam/hlds/hlds_run -game cstrike \
  +ip 0.0.0.0 -port 27015 +map de_dust2 +maxplayers 20 -pingboost 1
Restart=always
RestartSec=3
StartLimitIntervalSec=60
StartLimitBurst=5

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now cs16
systemctl status cs16
journalctl -u cs16 -f      # live server console output

Restart=always covers clean exits and crashes alike; RestartSec=3 is the same anti-spin delay as the shell loop. The StartLimitBurst=5 means that if the server dies five times in 60 seconds it gives up and stops — that is a feature, because a server crashing on load will otherwise loop forever and you want it to fail loudly so you go read the logs.

5. Log the crash so you can fix the cause

Restarting hides the symptom; find the cause in the crash log. GoldSrc writes a core dump and often a debug.log in the game directory listing the faulting module. A plugin that crashes the server repeatedly shows up there. Enable AMXX per-map logs and run the suspect plugin with the debug flag — see plugins.ini load order and finding a crashing plugin.

Common errors

  • Server dies and stays down-norestart is in your command line, or you ran the engine binary directly instead of hlds_run. Use the wrapper.
  • Restart loop pegs one CPU core at 100% — the server crashes on load and restarts with no delay. Add RestartSec/sleep and read the crash log; do not paper over it.
  • Server dies when I log out of SSH — you launched it in your login shell. Use screen/tmux or, better, a systemd unit.
  • systemd keeps saying start request repeated too quickly — it hit StartLimitBurst. The server is failing on startup; fix the underlying fault, then systemctl reset-failed cs16.
  • Comes back on crash but not after a reboot — you did not systemctl enable the unit, or your screen loop was never wired to boot.

Verification

Prove the supervisor works by killing the server and watching it return:

pkill -f hlds_linux        # simulate a crash
journalctl -u cs16 -f      # watch it restart within RestartSec

The engine should come back within a few seconds and the server reappear in the browser. Reboot the machine once and confirm it starts unattended. For scheduled restarts (a nightly clean bounce rather than crash recovery) pair this with cron-based restarts, and make sure your configs and bans are backed up before you rely on any of it.

Contribuitori: Daemon666 ✦
Distribuie: