#!/usr/bin/env bash # Gemeinsame Abbau-Funktion fuer Benchmark-Testserver. # # WARUM ES DIESE DATEI GIBT: die Benchmark-Skripte benutzten # `pgrep -x llama-server` zum Aufraeumen. Das trifft aber AUCH die Produktion — # PropellerAs Backend (:8290) und gemma-de (:8270) sind ebenfalls # llama-server-Prozesse. Am 16.08. hat run_extra.sh damit den kompletten # Primaerstack abgeraeumt, waehrend der Chat lief. # # Unterscheidungsmerkmal ist die systemd-Zugehoerigkeit, nicht der Port: # Produktion laeuft IMMER unter /system.slice/.service, Testserver werden # per nohup aus einer Benutzer-Shell gestartet und landen in einer # user.slice / scope. Wer hier etwas aendert, prueft vorher mit # for p in $(pgrep -x llama-server); do head -1 /proc/$p/cgroup; done # # FALLE, die uns am 17.08. vier Stunden Leerlauf gekostet hat: das Muster war # erst `*.service*` — und der Pfad einer Benutzer-Shell lautet # 0::/user.slice/user-1001.slice/user@1001.service/tmux-spawn-...scope # Da steht `user@1001.service` mittendrin, also galt der Testserver als # geschuetzte Produktion und ueberlebte den Abbau. Er hielt 33 GB VRAM fest, # PropellerAs Backend konnte nicht laden, gemma-de haengte in start-pre. # Richtig ist der Pfad-PRAEFIX /system.slice/, nicht die Endung .service. # # Zusaetzlich als zweiter Riegel: die bekannten Produktionsports werden # explizit ausgenommen, falls jemand ein Backend doch mal von Hand startet. PRODUKTIONSPORTS="${PRODUKTIONSPORTS:-8290 8270 8275 8210}" # Gibt die PIDs aus, die gefahrlos beendet werden duerfen. testserver_pids() { local p cg cmd port geschuetzt for p in $(pgrep -x llama-server 2>/dev/null); do cg=$(head -1 "/proc/$p/cgroup" 2>/dev/null) || continue case "$cg" in */system.slice/*) continue ;; esac cmd=$(tr '\0' ' ' < "/proc/$p/cmdline" 2>/dev/null) geschuetzt=0 for port in $PRODUKTIONSPORTS; do case "$cmd" in *"--port $port"*) geschuetzt=1 ;; esac done [ "$geschuetzt" = 1 ] && continue echo "$p" done } # Beendet ausschliesslich Testserver. Produktion bleibt unangetastet. # # Meldet, WAS beendet wurde und was ueberlebt hat. Die stille Variante hat den # 17.08. verschluckt: der Abbau fand nichts, sagte nichts, und der Testserver # blockierte den halben Vormittag den VRAM. stop_testserver() { local pid i uebrig for pid in $(testserver_pids); do echo " Testserver beenden: PID $pid ($(tr '\0' ' ' < /proc/$pid/cmdline 2>/dev/null | grep -o -- '--port [0-9]*'))" kill -TERM "$pid" 2>/dev/null done for i in $(seq 1 25); do [ -z "$(testserver_pids)" ] && break; sleep 1; done for pid in $(testserver_pids); do echo " haert killen: PID $pid"; kill -9 "$pid" 2>/dev/null; done sleep 3 # Gegenprobe: laeuft noch ein llama-server ausserhalb von /system.slice, ist # der Abbau gescheitert — dann fehlt dem Produktivstack nachher der VRAM. uebrig="" for pid in $(pgrep -x llama-server 2>/dev/null); do case "$(head -1 /proc/$pid/cgroup 2>/dev/null)" in */system.slice/*) ;; *) uebrig="$uebrig $pid" ;; esac done [ -n "$uebrig" ] && echo " ACHTUNG: Nicht-Produktions-llama-server ueberlebt:$uebrig" return 0 }