clean_zombies: script bash per ripulire il sistema dai processi zombie

Tenere sotto controllo il numero di processi attivi sulla nostra macchina è certamente una buona pratica, soprattutto quando si parla di sistemi in produzione. Tale monitoraggio può essere realizzato mediante il buon vecchio Nagios, il quale provvederà ad inviarci un’opportuna notifica nel caso in cui il numero dei processi superi una determinata soglia (definibile a piacere).

bashOccorre precisare, però, che nel computo totale rientrano anche i processi zombie, i quali, per definizione, non possono essere killati (sono già in stato defunct). Ergo, per sbarazzarsene occorrerà “fermare” il processo padre (o parent process). Ora, poichè non esiste pratica più noisa dell’andare a ricercare i padri dei vari processi zombie, ho deciso di realizzare il seguente scrip bash in grado di automatizzare il task in questione (con relativo respawning del parent process):

parents=`ps -ef | grep defunct | grep -v grep | awk '{print $3}' | sort -u | wc -l`

p=1

parentidlist=`ps -ef | grep defunct | grep -v grep | awk '{print $3}' | sort -u`

if [[ ! -z "$parents" ]] && [[ "$parents" -gt 0 ]];then
        while [[ "$p" -le "$parents" ]]
        do
                parentid=`echo $parentidlist | awk -v p="$p" '{print $p}'`
                parentname=`ps -o cmd -p $parentid | grep -v CMD`

                if [[ ! -z "$parentid" ]] && [[ ! -z "$parentname" ]];then
                        echo "Terminating $parentname with PID $parentid..."
                        kill -15 "$parentid"
                        sleep 10
                        running=`ps aux | grep "$parentname" | grep -v grep`
                        if [[ -z "$running" ]];then
                                echo "Starting $parentname..."
                                eval $parentname
                        else
                                echo "Error: the process $parentname is still running, switching to the next one..."
                        fi
                fi

                let p=p+1
        done
else
        echo "No defunct process, exiting..."
        exit 1
fi

Il suddetto codice è abbastanza intuitivo. Per prima cosa individuo il numero totale e la lista dei PPID (parent process id) associati a ciascun processo in stato defunct (se esistono). A questo punto, mediante un banale ciclo while, “termino” i processi padre ricavati in precedenza, con successivo respawning degli stessi (sempre che il kill -15 aka SIGTERM sia andato in buon fine, altrimenti skip e si procede con il PPID successivo). Da notare che ho utilizzato la direttiva eval piuttosto che exec, poichè, in quest’ultimo caso, veniva forzata l’uscita dal while.

Se volete fare qualche test potete utilizzare quest’altro scrip bash (fork_zombies) che ho creato allo scopo:

#!/bin/bash

(sleep 1 & exec /bin/sleep 60)

è sufficiente lanciarne qualche istanza in background mediante il comando:

[root@linuxbox ~]# ./fork_zombies &

Nel prossimo post vedremo come integrare il suddetto scrip con Nagios (sotto forma di event handler).

Alla prossima.

clean_zombies: script bash per ripulire il sistema dai processi zombieultima modifica: 2016-05-13T16:19:52+02:00da nazarenolatella
Reposta per primo quest’articolo