4.8. Daemons, signalen en het stoppen van processen

Als een gebruiker een editor draait is het makkelijk om de editor te besturen, te vertellen om bestanden te openen, etc. Dit kan omdat de editor de mogelijkheden geeft om dat te doen en omdat de editor gekoppeld is aan een terminal. Sommige programma's zijn niet ontworpen om te draaien met continue gebruikersinvoer, dus als zij de kans krijgen ontkoppelen zij zich van de terminal. Een webserver reageert bijvoorbeeld de hele dag op webaanvragen en heeft eigenlijk geen input van een lokale gebruiker nodig. Programma's die email van locatie naar locatie transporteren zijn een ander voorbeeld.

Deze programma's heten daemons. Daemons waren karakters in de Griekste mythologie, goed noch slecht, ze waren dienende geesten die op grote schaal nuttige dingen deden voor de mensheid. Net zoals de huidige webservers en mailservers nuttige dingen doen. Dit is waarom de mascotte voor BSD al lang een vrolijk kijkende daemon met puntoren en een drietand is.

Er is een overeenkomst om programma's die meestal draaien als daemon te voorzien van het achtervoegsel “d”. BIND is de Berkeley Internet Name Domain (het echte programma heet named), de Apache webserver heet httpd, de printerspooldriver heet lpd, etc. Deze overeenkomst geldt niet altijd. De hoofd maildaemon voor Sendmail heet bijvoorbeeld sendmail en niet maild.

Soms is communicatie met een daemon nodig. Een manier om dit te doen is het versturen van een signaal (signals). Er zijn een verschillende signalen. Sommige hebben een specifieke bedoeling, andere worden geïntrepeteerd door de applicatie. In de documentatie van de applicatie staat hoe de applicatie signalen intrepeteert. Er kan alleen een signaal naar een proces gezonden worden waar de uitvoerende gebruiker eigenaar van is. Als met kill(1) of kill(2) een signaal naar een proces van een andere gebruiker wordt gestuurd, wordt de toegang geweigerd. De enige uitzondering hierop is de root gebruiker, die signalen naar processen van alle gebruikers kan sturen.

FreeBSD stuurt soms ook signalen naar applicaties. Als een applicatie slecht geschreven is en hij probeert geheugen te benaderen waar hij niet naartoe mag, stuurt FreeBSD het proces een Segmentation Violation signaal (SIGSEGV). Als een applicatie de systeemaanroep alarm(3) heeft gebruikt om na een bepaalde periode een alarm te ontvangen, wordt er een Alarm signaal heen gestuurd (SIGALRM), etc.

Twee signalen kunnen gebruikt worden om een proces te stoppen: SIGTERM en SIGKILL. SIGTERM is de nette manier om een proces te killen. Het proces kan het signaal afvangen, begrijpen dat de eigenaar wil dat het wordt afgesloten, wellicht logboekbestanden sluiten die geopend zijn en alle onderhanden activiteiten afhandelen. In een aantal gevallen kan een proces SIGTERM negeren: als het midden in een taak zit die niet beëindigd kan worden.

SIGKILL mag niet worden genegeerd door een proces. Dit is het “Wat je ook aan het doen bent, stop er nu mee” signaal. Na een SIGKILL stopt FreeBSD het proces meteen. [1]

Andere veelgebruikte signalen zijn SIGHUP, SIGUSR1 en SIGUSR2. Dit zijn algemeen bruikbare signalen en verschillende applicaties zullen verschillend reageren als ze verstuurd worden.

Stel dat het bestand met instellingen voor de webserver is aangepast. Dan moet aan de webserver verteld worden dat die de instellingen opnieuw moet lezen. Hiervoor zou httpd gestopt en gestart kunnen worden, maar dit resulteert in een korte onderbreking van de webserverdienst, wat ongewenst kan zijn. De meeste daemons zijn geschreven om te reageren op het SIGHUP signaal door het opnieuw inlezen van het instellingenbestand. Dus in plaats van het stoppen en herstarten van httpd kan het SIGHUP signaal gezonden worden. Omdat er geen standaard manier is om op deze signalen te reageren, reageren verschillende daemons anders. Het is verstandig eerst de documentatie van de daemon in kwestie te lezen.

Zoals onderstaand voorbeeld laat zien, worden signalen door kill(1) verzonden.

Het versturen van een signaal naar een proces

Dit voorbeeld toont hoe een signaal naar inetd(8) wordt verstuurd. Het bestand met instellingen voor inetd is /etc/inetd.conf en inetd leest dit bestand opnieuw in als er een SIGHUP wordt verstuurd.

  1. Eerst moet het proces ID worden opgezocht van het proces waar een signaal naar verzonden moeten worden. Dit kan door pgrep(1) te gebruiken.

    % pgrep -l inetd
    198  inetd -wW
    

    Dus het PID van inetd(8) is 198.

  2. Met kill(1) kan het signaal verzonden worden. Omdat inetd(8) wordt gedraaid door root moet su(1) gebruikt worden om root te worden.

    % su
    Password:
    # /bin/kill -s HUP 198
    

    Zoals zovaak met UNIX® commando's, geeft kill(1) geen uitvoer als het succesvol uitgevoerd is. Als een signaal wordt verzonden naar een proces waarvan de gebruiker niet zelf de eigenaar is, dan is de melding: “kill: PID: Operation not permitted”. Als het PID verkeerd wordt ingevuld, wordt het signaal naar het verkeerde proces verzonden, wat slecht kan zijn, of, als de gebruiker geluk heeft, wordt het verzonden naar een PID dat momenteel niet in gebruik is, waarop de foutmelding “kill: PID: No such process” verschijnt.

    Waarom /bin/kill gebruiken?: Veel shells leveren kill als ingebouwd commando. Dat betekent dat de shell het signaal direct verstuurt in plaats van door het starten van /bin/kill. Dit kan erg nuttig zijn, maar verschillende shells hebben een verschillende opdrachtregel voor het specificeren van de naam van het signaal dat verstuurd moet worden. In plaats van ze allemaal te leren, is het eenvoudiger om gewoon /bin/kill PID te gebruiken.

Andere signalen versturen werkt bijna hetzelfde door TERM of KILL op de commandoregel te vervangen door wat nodig is.

Belangrijk: Het stoppen van willekeurige processen op een systeem is meestal een slecht idee. In het bijzonder bij init(8) met proces ID 1. Het draaien van /bin/kill -s KILL 1 is een snelle manier om een systeem uit te zetten. Argumenten die aan kill(1) worden meegegeven moeten altijd twee keer gecontroleerd worden voordat op Enter gedrukt wordt.

Noten

[1]

Dit is niet geheel waar. Er zijn een aantal dingen die niet onderbroken kunnen worden. Als het proces bijvoorbeeld een bestand probeert uit te lezen dat op een andere computer in het netwerk staat en de andere computer is verdwenen (uitgezet of het netwerk heeft een fout), dan wordt er gezegd dat het proces niet “onderbroken” kan worden. Uiteindelijk loopt het proces uit de tijd, meestal na twee minuten. Zodra het uit de tijd loopt, wordt het proces alsnog gestopt.