Commandes utiles – preap
Posted by Daniel on 12 Avr 2010 at 09:00 | Tagged as: solaris
On rencontre de temps en temps des processus appelés zombis. Rien à voir avec un film de Georges A. Romero, il s'agit d'un phénomène beaucoup plus prosaïque. Quand un processus se termine, pratiquement toutes les ressources associées sont libérées, à l'exception de l'entrée correspondante dans la table des processus de l'OS. La raison en est simple : le processus parent doit pouvoir récupérer le code de retour de son processus fils, on ne peut donc pas tout effacer brutalement.
Typiquement, la suppression de l'entrée dans la table des processus se fait donc au moment où le parent récupère ce code retour, c'est ce qu'on appelle le reaping (the Reaper étant notre Grande Faucheuse). Si le processus parent, pour une raison où pour une autre, ne lit pas ce code, l'entrée reste présente dans la table des processus. Voyons donc à quoi ces zombis ressemblent, et comment s'en débarrasser.
En soit, c'est généralement peu gênant, puisqu'à part l'entrée dans la table des processus, il n'y a plus rien : ni mémoire consommée, ni CPU utilisé. J'y vois cependant deux inconvénients :
- la table des processus a une table limitée (30000 entrées par défaut), et chaque zombi occupe une place, donc si on en génère beaucoup, cela peut devenir problématique sur un système chargé
- le zombi est vraiment, vraiment laid (et en plus il ne sent pas bon)
$ ps -edf | grep defunct daniel 7542 7541 0 - ? 0:00Ou encore :daniel 7450 7449 0 - ? 0:00 daniel 7546 7545 0 - ? 0:00 daniel 7544 7543 0 - ? 0:00
$ ps -ecl | grep Z F S UID PID PPID CLS PRI ADDR SZ WCHAN TTY TIME CMD 0 Z 59002 7450 7449 - 0 - 0 - ? 0:00Pour les supprimer, on va utiliser la commande preap :
$ preap 7450 7450: exited with status 0 $ preap 7542 7542: exited with status 0 $ preap 7544 7544: exited with status 0 $ preap 7546 7546: exited with status 0 $ ps -edf | grep defunct $Et voilà, bigrement plus efficace que le héros de Brain Dead! A noter, si vous souhaitez créer manuellement un zombi pour vos tests, vous pouvez utiliser la commande suivante, fournie par l'excellent c0t0d0s0.org :
$ nohup perl -e "if (fork()>0) {while (1) {sleep 100*100;};};"