Archivi tag: zombie process

auto_clean_zombies: event handler per Nagios in grado di ripulire il sistema dai processi zombie

In questo post ho illustrato il codice di uno scrip da me realizzato, in grado di ripulire il sistema dai processi zombie. Ora vedremo come fare ad integrare, sotto forma di event handler, il predetto scrip con Nagios. Per prima cosa è necessario creare l’event handler vero e proprio (che funge da wrapper), il quale richiamerà lo scrip clean_zombies in caso di necessità:

#!/bin/bash

case "$1" in
OK)
        ;;
WARNING)
        ;;
UNKNOWN)
        ;;
CRITICAL)
       case "$2" in
                SOFT)
                        case "$3" in
                        3)
                                echo -n "Cleaning zombie processes (3rd soft critical state)..."
                                usr/bin/sudo /root/scrips/clean_zombies
                                ;;
                                esac
                        ;;
                HARD)
                        echo -n "Cleaning zombie processes (3rd soft critical state)..."
                        usr/bin/sudo /root/scrips/clean_zombies
                        ;;
                esac
                ;;
        esac

exit 0

Successivamente occorre creare un apposito comando all’interno del file /etc/nagios/object/commands.cfg:

# 'auto_clean_zombies' command definition
define command {
        command_name      auto_clean_zombies
        command_line      /usr/lib64/nagios/plugins/eventhandlers/auto_clean_zombies $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$
        }

A questo punto possiamo assegnare l’event handler al servizio Total Processes definito nel file di configurazione dell’host per il quale si intende monitorare il numero dei processi:

define service{
        use                            local-service         
        host_name                      localhost
        service_descripion             Total Processes
        event_handler                  auto_clean_zombies
        check_command                  check_local_procs!280!400!RSZDT
        }

Inoltre, affinchè l’untente nagios possa lanciare il suddetto scrip senza che vi sia la necessità di inserire la password di autenticazione, occorre editare il file /etc/sudoers nel seguente modo:

nagios   ALL=NOPASSWD:   /root/scrips/clean_zombies

Ricarichiamo la configurazione di Nagios:

[root@linuxbox ~]# service nagios reload

ed abbiamo finito. Alla prossima.

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.