FreeBSD handboek
Terug | Hoofdstuk 4. UNIX® beginselen | Volgende

# 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 ps(1) en grep(1) te gebruiken. grep(1) wordt gebruikt om in de uitvoer te zoeken en te kijken naar de string die de gebruiker opgeeft. Dit commando wordt gedraaid als een normale gebruiker en inetd(8) wordt gedraaid onder de gebruiker `root`, dus aan ps(1) moet de optie `ax` meegegeven worden.

       % ps -ax | grep inetd
         198  ??  IWs    0:00.00 inetd -wW

   Dus PID van inetd(8) is 198. In sommige gevallen kan `grep inetd` ook voorkomen in de uitvoer. Dit komt door de manier waarop ps(1) de lijst van draaiende processen moet vinden.

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.

Terug | Begin | Volgende
Processen | Omhoog | Shells