systemd forking vs simple?

24

J'écris mon premier systemdfichier d'unité.

Pour Type, il y a quelques choix: forking, simple, etc. J'ai lu la documentation Redhat sur ce sujet (tableau 9.9), mais je ne suis pas sûr que je devrais utiliser l'option.

Des directives?

leeyuiwah
la source

Réponses:

46

Lorsque vous démarrez le service manuellement à partir de la ligne de commande (sans utiliser la nohupcommande préfixe ou le &suffixe pour l'exécuter en arrière-plan, ou en d'autres termes, exécutez simplement la commande que vous mettriez sur la ExecStart=ligne du .servicefichier), que se passe-t-il?

a) Si le service démarre et continue de fonctionner et que l'invite ne revient pas tant que vous n'avez pas appuyé sur Ctrl-C ou arrêté le service d'une autre manière: alors Type = simplec'est le bon choix.

b) Si l'invite revient mais que le service continue de fonctionner en arrière-plan (c'est-à-dire que le service se démonifie tout seul), alors Type = forkingc'est le bon choix.

c) Si le service fait son travail et revient à l'invite sans laisser quoi que ce soit en cours d'exécution (c'est-à-dire que le service ajuste simplement certains paramètres du noyau, envoie une commande à autre chose ou fait quelque chose de similaire), alors Type = oneshotc'est probablement le bon choix. Dans ce cas, ExecStartle service pourrait être la commande de "définir" quelque chose, et ExecStopserait la commande correspondante pour le "désarmer". Ce type bénéficie généralement de RemainAfterExit=true, donc systemd gardera une trace de l '"état" de ce service selon que la chose a été récemment "définie" ou "non définie".

Les autres Typevaleurs sont des cas particuliers. Par exemple, si le service utilise une connexion D-Bus, cela Type = dbuspourrait être le meilleur choix. Il prend systemdconscience du fait, puis systemd suivra ce service (et tout ce qui en dépend) par la présence de ce service sur le D-Bus.

Pour l'utiliser Type = notify, le processus doit être capable de se connecter au socket Unix spécifié dans la variable d'environnement $NOTIFY_SOCKETet de signaler son état en écrivant des messages sur ce socket chaque fois que cela est nécessaire. En outre, le fichier de service doit spécifier l' NotifyAccessoption d'accorder l'accès au socket de notification, le cas échéant.

Il existe un utilitaire de ligne de commande systemd-notifyet une fonction de bibliothèque C que sd_notify(3)vous pouvez utiliser pour envoyer ces messages, mais si aucun d'entre eux ne convient à vos besoins, vous pouvez simplement implémenter votre propre expéditeur de message. Les messages requis sont très simples et ressemblent à des affectations de variables shell: par exemple, pour notifier que le service a réussi le démarrage et qu'il est prêt à répondre à toutes les demandes entrantes, le service doit envoyer la chaîne équivalente à la sortie de printf "READY=1\n"la socket. Voir man 3 sd_notifypour plus de détails sur les messages reconnus.

Remarque: de nombreuses applications de service conçues pour être portables sur de nombreux systèmes de style Unix peuvent se comporter comme b) par défaut, mais peuvent être conçues pour fonctionner comme a) en ajoutant une option (généralement décrite comme «ne pas bifurquer», «continuer à fonctionner au premier plan "," ne pas démoniser "ou similaire). Dans ce cas, si l'option n'a pas d'autres effets secondaires, il serait préférable d'ajouter l'option et d'utiliser le comportement de type a) systemd.

telcoM
la source
Supposons que je commence apache, quel type doit être utilisé?
kittygirl
2
Eh bien, comment voulez-vous le démarrer manuellement? En exécutant en apachectl starttant que root, peut-être? Essayez de le faire et voyez ce qui se passe. Choisissez ensuite a), b) ou c) dans ma réponse. Je parie que l'invite revient et Apache continue de fonctionner, donc b) serait la réponse.
telcoM
J'aime beaucoup les explications que vous avez données dans votre réponse. Pourriez-vous ajouter une autre explication en anglais clair pour le cas de Type=notify?
Yankee
Description de l' Type=notifyajout.
telcoM