Während der klassische SystemV-Init Prozesse immer geforked hat (Daemonized) und diese dann meistens die PID ihren Hauptprozesses in eine Datei geschrieben haben, bietet Systemd auch die Möglichkeit, Prozesse im eigenen Kontext (foreground) zu starten.
In diesem Modus erstellen einige Prozesse kein PIDFile mehr.
Setzt man jetzt z.B. monit ein, um seine Prozesse zu überwachen, fehlt einem diese Datei.
Glücklicherweise lässt sich das PIDFile, mit der Hilfe von systemd automatisch erstellen.
Als erstes brauchen wir dazu ein Skript, das die PID für die Unit bei systemd abfragt und diese dann in das PIDFile schreibt.
/usr/local/sbin/systemd-pidfile
#!/usr/bin/env bash
if [[ "x${1}" == "x" ]]
then
echo "systemd unit name required"
exit 2
fi
UNITNAME="${1%%.service}"
if [[ "${UNITNAME}" == "${1}" ]]
then
echo "use %n as parameter in unit file"
exit 2
fi
TEMPLATE="${UNITNAME%%@*}"
INSTANCE="${UNITNAME##*@}"
if [[ -d "/run/${TEMPLATE}" ]]
then
PIDFILE="/run/${TEMPLATE}/${UNITNAME}.pid"
else
PIDFILE="/run/${UNITNAME}.pid"
fi
export $(systemctl -p MainPID show ${1})
if [[ $MainPID == 0 ]]
then
if [[ -f "$PIDFILE" ]]
then
rm -rf "$PIDFILE"
fi
exit 0
else
echo $MainPID > $PIDFILE
exit 0
fi
Das Skript lassen wir dann über das unit-File des Prozesses starten.
Ich verwende hier als Beispiel die rspamd-Unit. Für andere Prozesse bitte entsprechend anpassen.
Als erstes erstellen wir ein Konfigurationsverzeichnis.
mkdir /etc/systemd/system/rspamd.service.d
Und erstellen dann die Konfigurationsdatei.
cat <<EOF >/etc/systemd/system/rspamd.service.d/pidfile.conf
[Service]
ExecStartPost=/usr/local/sbin/systemd-pidfile %n
ExecStopPost=/usr/local/sbin/systemd-pidfile %n
EOF
%n wird dabei durch den UNIT-Namen (hier: rspamd.service) ersetzt.
Jetzt wird bei jedem Start von rspamd ein PidFile erstellt und nach dem Stoppen wieder gelöscht, so das wir rspamd jetzt auch mit monit überwachen können.
Download: systemd-pidfile.zip