incompatibilité du protocole de préparation
Comme Wieland l'a laissé entendre, Typele service est important. Ce paramètre indique quel protocole de préparation systemd attend du service qu'il parle. Un simpleservice est supposé être immédiatement prêt. Un forkingservice est censé être prêt après que son processus initial a forcé un enfant puis se termine. Un dbusservice est considéré comme prêt lorsqu'un serveur apparaît sur le bus de bureau. Et ainsi de suite.
Si vous n'obtenez pas le protocole de disponibilité déclarée dans l'unité de service pour correspondre à ce que fait le service, alors les choses tournent mal. L'inadéquation des protocoles de disponibilité empêche les services de démarrer correctement ou (plus généralement) d'être (mal) diagnostiqués par systemd comme défaillants. Lorsqu'un service est considéré comme ne démarrant pas systemd, il garantit que tous les processus supplémentaires orphelins du service qui pourraient avoir été laissés en cours d'exécution dans le cadre de l'échec (de son point de vue) sont tués afin de ramener correctement le service à l'inactif. Etat.
Tu fais exactement ça.
Tout d'abord, le truc simple: sh -cne correspond pas Type=simpleou Type=forking.
Dans le simpleprotocole, le processus initial est considéré comme le processus de service. Mais en fait, un sh -cwrapper exécute le programme de service réel en tant que processus enfant . Va donc MAINPIDmal et ExecReloadcesse de fonctionner, pour commencer. Lors de l'utilisation Type=simple, il faut utiliser sh -c 'exec …'ou ne pas utiliser sh -c en premier lieu. Ce dernier est plus souvent le bon choix que certains ne le pensent.
sh -cne correspond pas non Type=forkingplus. Le protocole de préparation d'un forkingservice est assez spécifique. Le processus initial doit bifurquer un enfant, puis quitter. systemd applique un délai d'attente à ce protocole. Si le processus initial ne se déroule pas dans le temps imparti, c'est un échec à devenir prêt. Si le processus initial ne se termine pas dans le temps imparti, c'est aussi un échec.
l'horreur inutile qui est ossec-control
Ce qui nous amène au truc complexe: ce ossec-controlscript.
Il s'avère que c'est un rcscript System 5 qui bifurque entre 4 et 10 processus, qui eux-mêmes à leur tour bifurquent et sortent également. C'est l'un de ces rcscripts System 5 qui tente de gérer tout un ensemble de processus serveur dans un seul script, avec des forboucles, des conditions de concurrence, des arbitraires sleeppour essayer de les éviter, des modes de défaillance qui peuvent étouffer le système dans un état semi-démarré, et toutes les autres horreurs qui ont poussé les gens à inventer des choses comme AIX System Resource Controller et daemontools il y a deux décennies. Et n'oublions pas le script shell caché dans un répertoire binaire qu'il réécrit à la volée, pour implémenter idiosyncrasiques enableet disableverbes.
Donc, quand vous /bin/sh -c '/var/ossec/bin/ossec-control start'ce qui se passe, c'est que:
- systemd indique ce qu'il attend du processus de service.
- C'est la coquille, qui bifurque
ossec-control.
- Cela à son tour fourche entre 4 et 10 petits-enfants.
- Les petits-enfants bifurquent tous et sortent tour à tour.
- Les arrière-petits-enfants bifurquent tous et sortent en parallèle.
ossec-control sort.
- Le premier obus sort.
- Les processus de service étaient les arrière-arrière- petits - enfants, mais parce que cette façon de travailler ne correspond ni au protocole
forking ni au simpleprotocole de préparation, systemd considère que le service dans son ensemble a échoué et le ferme.
Aucune de ces horreurs n'est réellement nécessaire sous systemd. Rien de cela.
une unité de service de modèle systemd
Au lieu de cela, on écrit une unité de modèle très simple :
[Unité]
Description = Le serveur OSSEC HIDS% i
Après = network.target
[Un service]
Type = simple
ExecStartPre = / usr / bin / env / var / ossec / bin /% p-% i -t
ExecStart = / usr / bin / env / var / ossec / bin /% p-% i -f
[Installer]
WantedBy = multi-user.target
Enregistrez ceci sous /etc/systemd/system/ossec@.service.
Les différents services réels sont des instanciations de ce modèle, nommé:
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
Ensuite, la fonction d'activation et de désactivation vient directement du système de gestion des services (avec le bogue RedHat 752774 corrigé), sans avoir besoin de scripts shell cachés.
systemctl enable ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analysisd ossec @ logcollector ossec @ remec ossec @ syscheckd ossec @ monitord
De plus, systemd apprend à connaître et à suivre directement chaque service réel. Il peut filtrer leurs journaux avec journalctl -u. Il peut savoir lorsqu'un service individuel a échoué. Il sait quels services sont censés être activés et en cours d'exécution.
Soit dit en passant: Type=simpleet l' -foption est aussi juste ici que dans de nombreux autres cas. Très peu de services dans la nature signalent en fait leur disponibilité à force de cela exit, et ce ne sont pas de tels cas ici non plus. Mais c'est ce que le forkingtype signifie. Les services à l'état sauvage dans la fourchette principale et la sortie principale en raison d'une notion de sagesse reçue erronée selon laquelle c'est ce que les démons sont censés faire. En fait, ce n'est pas le cas. Cela ne s'est pas produit depuis les années 1990. Il est temps de se rattraper.
Lectures complémentaires