disadattamento del protocollo di disponibilità
Come implica Wieland, Type
il servizio è importante. Tale impostazione indica quale protocollo di prontezza systemd prevede che il servizio parlerà. Si simple
presume che un servizio sia immediatamente pronto. Un forking
servizio viene considerato pronto dopo che il suo processo iniziale crea un figlio e poi esce. Un dbus
servizio viene considerato pronto quando viene visualizzato un server sul bus desktop. E così via.
Se non si ottiene che il protocollo di disponibilità dichiarato nell'unità di servizio corrisponda a quello che fa il servizio, allora le cose vanno male. I disallineamenti del protocollo di disponibilità fanno sì che i servizi non vengano avviati correttamente o (più di solito) vengano (erroneamente) diagnosticati da systemd come non funzionanti. Quando un servizio viene visto come mancato avvio di systemd assicura che ogni processo aggiuntivo orfano del servizio che potrebbe essere stato lasciato in esecuzione come parte dell'errore (dal suo punto di vista) viene interrotto al fine di riportare il servizio correttamente inattivo stato.
Stai facendo esattamente questo.
Prima di tutto, le cose semplici: sh -c
non corrispondono Type=simple
o Type=forking
.
Nel simple
protocollo, il processo iniziale è presa per essere il processo di servizio. Ma in realtà un sh -c
wrapper esegue l'effettivo programma di servizio come processo figlio . Quindi MAINPID
va storto e ExecReload
smette di funzionare, per cominciare. Quando si usa Type=simple
, si deve usare sh -c 'exec …'
o non usare sh -c
in primo luogo. Quest'ultimo è più spesso il corso corretto di quanto alcuni pensano.
sh -c
non corrisponde Type=forking
neanche. Il protocollo di prontezza per un forking
servizio è abbastanza specifico. Il processo iniziale deve biforcare un figlio e quindi uscire. systemd applica un timeout a questo protocollo. Se il processo iniziale non si interrompe entro il tempo assegnato, non è possibile essere pronti. Se il processo iniziale non termina entro il tempo assegnato, anche questo è un errore.
l'orrore inutile che è ossec-control
Il che ci porta a cose complesse: quella ossec-control
sceneggiatura.
Si scopre che si tratta di uno rc
script di System 5 che esegue il fork tra 4 e 10 processi, che a loro volta si spostano ed escono anch'essi. È uno di quegli rc
script di System 5 che tenta di gestire un intero set di processi server in un singolo script, con for
loop, condizioni di gara, sleep
s arbitrari per cercare di evitarli, modalità di errore che possono soffocare il sistema in uno stato semi-avviato, e tutti gli altri orrori che hanno portato la gente a inventare cose come AIX System Resource Controller e daemontools due decenni fa. E non dimentichiamo lo script di shell nascosto in una directory binaria che riscrive al volo, per implementare idiosincratici enable
e disable
verbi.
Quindi quando ti /bin/sh -c '/var/ossec/bin/ossec-control start'
succede è che:
- systemd fork quello che si aspetta sia il processo di servizio.
- Questa è la shell, che forchette
ossec-control
.
- Che a sua volta biforcano tra 4 e 10 nipoti.
- I nipoti si biforcano tutti e escono a turno.
- I pronipoti si biforcano tutti e escono in parallelo.
ossec-control
uscite.
- Esce la prima shell.
- I processi di servizio sono stati i grandi-ottimo- nipoti, ma perché in questo modo di incontri di lavoro né il
forking
né il simple
protocollo di prontezza, systemd considera il servizio nel suo complesso ad aver fallito e si chiude di nuovo verso il basso.
Niente di tutto questo orrore è effettivamente necessario sotto systemd. Nessuno di questi.
un'unità di servizio modello systemd
Invece, si scrive un'unità modello molto semplice :
[Unità]
Descrizione = Il server OSSEC HIDS% i
Dopo = network.target
[Servizio]
Tipo = semplice
ExecStartPre = / usr / bin / env / var / ossec / bin /% p-% i -t
ExecStart = / usr / bin / env / var / ossec / bin /% p-% i -f
[Installare]
WantedBy = multi-user.target
Salva questo come /etc/systemd/system/ossec@.service
.
I vari servizi effettivi sono istanze di questo modello, denominato:
ossec@dbd.service
ossec@agentlessd.service
ossec@csyslogd.service
ossec@execd.service
ossec@agentd.service
ossec@logcollector.service
ossec@syscheckd.service
ossec@maild.service
ossec@analysisd.service
ossec@remoted.service
ossec@monitord.service
Quindi abilitare e disabilitare la funzione proviene direttamente dal sistema di gestione del servizio (con bug RedHat 752774 corretto), senza la necessità di script di shell nascosti.
systemctl abilita ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analysisd ossec @ logcollector ossec @ remote ossec @ syscheckd ossec @ monitord
Inoltre, systemd è in grado di conoscere e tracciare direttamente ogni servizio effettivo. Può filtrare i loro log con journalctl -u
. Può sapere quando un singolo servizio è fallito. Sa quali servizi dovrebbero essere abilitati e in esecuzione.
A proposito: Type=simple
e l' -f
opzione è proprio qui come in molti altri casi. Pochissimi servizi in natura segnalano effettivamente la loro prontezza a forza di exit
, e questi non sono neanche questi casi. Ma questo è ciò che forking
significa il tipo. I servizi allo stato brado in genere si limitano a biforcarsi ed uscire a causa di un errore che ha ricevuto la saggezza che questo è ciò che i demoni dovrebbero fare. In realtà non lo è. Non lo è più dagli anni '90. È tempo di recuperare.
Ulteriori letture