Domanda

Recentemente ho avuto un processo Linux che "trapelava" i descrittori di file:Li ha aperti e alcuni non li hanno chiusi correttamente.

Se lo avessi monitorato, potrei dire in anticipo che il processo sta raggiungendo il limite.

Esiste un modo carino, Bash\Python per verificare il rapporto di utilizzo FD per un determinato processo in un sistema Ubuntu Linux?

MODIFICARE:

Ora so come verificare quanti descrittori di file aperti ci sono;Ho solo bisogno di sapere quanti descrittori di file sono consentiti per un processo.Alcuni sistemi (come Amazon EC2) non dispongono di /proc/pid/limits file.

Grazie,

Udi

È stato utile?

Soluzione

Contare le voci in /proc/<pid>/fd/. I limiti hard e soft applicabili al processo possono essere trovati in /proc/<pid>/limits.

Altri suggerimenti

Le uniche interfacce fornite dal kernel Linux per ottenere i limiti delle risorse sono getrlimit() e /proc/ pid /limits . getrlimit() può ottenere solo limiti delle risorse del processo chiamante. /proc/ pid /limits consente di ottenere i limiti delle risorse di qualsiasi processo con lo stesso ID utente, ed è disponibile su RHEL 5.2, RHEL 4.7, Ubuntu 9.04, e qualsiasi distribuzione con un kernel 2.6.24 o successivo .

Se avete bisogno di supportare i vecchi sistemi Linux, allora si dovrà ottenere il processo stesso a chiamare getrlimit(). Naturalmente il modo più semplice per farlo è quello di modificare il programma, o una libreria che utilizza. Se si esegue il programma allora si potrebbe utilizzare LD_PRELOAD per caricare il proprio codice nel programma. Se nessuno di questi sono possibili, allora si potrebbe connettersi al processo con gdb e farlo eseguire la chiamata all'interno del processo. Si potrebbe anche fare la stessa cosa da soli, usando ptrace() per connettersi al processo, inserire la chiamata nella sua memoria, ecc, tuttavia questo è molto complicato per ottenere il diritto e non è raccomandato.

Con privilegi appropriati, gli altri modi per fare questo avrebbe comportato guardando attraverso la memoria del kernel, il caricamento di un modulo del kernel, o in altro modo modificare il kernel, ma io parto dal presupposto che questi sono fuori questione.

per vedere i primi 20 handle di file utilizzando i processi:

for x in `ps -eF| awk '{ print $2 }'`;do echo `ls /proc/$x/fd 2> /dev/null | wc -l` $x `cat /proc/$x/cmdline 2> /dev/null`;done | sort -n -r | head -n 20

l'output è nel formato file handle count, pid, cmndline per il processo

uscita di esempio

701 1216 /sbin/rsyslogd-n-c5
169 11835 postgres: spaceuser spaceschema [local] idle
164 13621 postgres: spaceuser spaceschema [local] idle
161 13622 postgres: spaceuser spaceschema [local] idle
161 13618 postgres: spaceuser spaceschema [local] idle

Si può provare a scrivere script che chiamano periodicamente lsof -p {PID} sul dato pid.

Hai chiesto per i metodi bash / Python. ulimit sarebbe la migliore approccio bash (corto di munging attraverso /proc/$pid/fd e simili a mano). Per Python, è possibile utilizzare il modulo di risorsa.

import resource

print(resource.getrlimit(resource.RLIMIT_NOFILE))
$ python test.py

(1024, 65536)

resource.getrlimit corrisponde alla chiamata getrlimit in C programma. I risultati rappresentano i valori correnti e massimi per la risorsa richiesta. Nell'esempio di cui sopra, la corrente limite (soft) è 1024. I valori sono predefiniti tipici sui sistemi Linux in questi giorni.

In CentOS 6 e al di sotto (qualsiasi cosa utilizzando GCC 3), è possibile che la regolazione dei limiti del kernel non risolve il problema. Questo è perché c'è un valore FD_SETSIZE che sia impostato al momento della compilazione in uso da GCC. Per questo, è necessario aumentare il valore e poi ricompilare il processo.

Inoltre, è possibile che si sta fuoriuscita di descrittori di file a causa di noti in libpthread se si utilizza quella libreria. Questa chiamata è stata integrata nel GCC in GCC 4 / CentOS7 / RHEL 7 e questo sembra aver risolto i problemi di threading.

involucro Python utilizzando l'eccellente pacchetto di psutil:

import psutil

for p in psutil.process_iter(attrs=['pid', 'name', 'username', 'num_fds']):
    try:
        soft, hard = p.rlimit(psutil.RLIMIT_NOFILE)
        cur = p.info['num_fds']
        usage = int(cur / soft * 100)
        print('{:>2d}% {}/{}/{}'.format(
            usage,
            p.info['pid'],
            p.info['username'],
            p.info['name'],
            ))
    except psutil.NoSuchProcess:
        pass
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top