Come fare come “-p netstat”, ma più veloce?
Domanda
Sia "netstat -p" e "lsof -i -n -P" sembra readlinking tutti i processi il df di, come stat /proc/*/fd/*
.
Come fare in modo più efficiente?
Il mio programma vuole sapere quale processo si connette ad esso. Attraversando di nuovo tutti i processi e sembra ancora troppo inefficaci.
Modi suggerendo iptables cose o patch del kernel sono benvenuti anche.
Soluzione
Date un'occhiata a questa risposta , dove sono menzionati vari metodi e programmi che eseguono presa a mappature di processo. Si potrebbe anche provare diverse tecniche aggiuntive per migliorare le prestazioni:
- caching dei descrittori di file in
/proc
, e le informazioni in/proc/net
. Questo viene fatto dai programmi di cui nella risposta collegato, ma è solo valida se il processo dura più di pochi secondi. - Si potrebbe provare a
getpeername()
, ma questo si affida conoscendoti dei possibili punti finali e quali processi che mappano. Le vostre domande suggerisce che si sta collegando prese a livello locale, si potrebbe provare a utilizzare Unix socket che permettono di ricevere le credenziali di un peer, quando lo scambio di messaggi passandoSO_PASSCRED
persetsockopt()
. Date un'occhiata a questi esempi (sono piuttosto brutto, ma la migliore che ho trovato). - Date un'occhiata a
fs/proc/base.c
nel kernel di Linux. Questo è il cuore delle informazioni fornite dal risultato di una readlink su un descrittore di file in/proc/PID/fd/FD
. Una parte significativa del sovraccarico è il passaggio delle richieste su e giù il livello VFS, numerosi bloccaggio che si verifica in tutte le strutture di dati del kernel che forniscono le informazioni fornite, e lo stringyfying e destringyfying al kernel e la vostra fine rispettivamente. Si potrebbe adattare parte del codice in questo file per generare queste informazioni senza molti degli strati intermedi, in particolare riducendo al minimo il bloccaggio a una volta al processo, o semplicemente una volta per la scansione di tutto il set di dati che stai cercando.
Il mio consiglio personale è quello di solo forza bruta per ora, idealmente attraversare i processi in /proc
in ordine numerico inverso, in quanto i processi più recenti e interessanti avranno PID più elevati, e tornare non appena hai individuato i risultati che 're dopo. In questo modo una volta per ogni connessione in entrata è relativamente a buon mercato, in realtà dipende da come le prestazioni critica l'applicazione è. Troverete sicuramente la pena di esclusione chiamata netstat
e analizzare direttamente il nuovo collegamento da /proc/net/PROTO
, quindi individuare la presa in /proc/PID/fd
. Se tutto il tuo traffico è localhost, basta passare alle prese Unix e ottenere direttamente le credenziali. Scrivi nuova chiamata di sistema o modulo proc che scarica enormi quantità di dati relativi descrittori di file che avevo salvo per l'ultima.