Re: processi e /proc e confusione
On 16/03/2014 16:41, Alessandro T. wrote:
On 15/03/2014 16:15, Alessandro Baggi wrote:
[...]
Non capisco perchè un determinato processo non è visibile ne con ps ne
in /proc ma esiste la dir della struttura del processo alla quale si
può accedere tranquillamente.
Questa cosa mi suona molto strana. Come hai fatto questo test?
Io ho fatto così:
cd /proc ; ps axo pid | sed '1d;s/[^0-9]*//' > ~/tmp/ps.txt ; \
ls --color=none -d1 [0-9]* | sort -n > ~/tmp/ls.txt ; \
diff ~/tmp/ps.txt ~/tmp/ls.txt
186,187c186,187
< 16239
< 16240
---
16241
16242
e come vedi le differenze sono causate, verosimilmente, dalla pipe nei
due comandi.
Ciao
Ciao Alessandro,
innanzi tutto grazie per la risposta.
Chiedo scusa per la lunghezza di questo post.
Ho fatto un altri test e forse si può arrivare alla conclusione.
Premetto che la macchina in questione è una macchina casalinga.
Quei pid consecutivi che risultano dal diff, come da te detto, sono
risultanti dalle pipe.
In questo caso credo che tutto sia nella norma, in quanto i processi
sono conclusi e un "cd /proc/16239" ritorna un errore.
Il mio problema fa riferimento al fatto che il processo non è listato ne
in /proc ne in ps e un "cd /proc/pid" ha successo.
Il mio primo rilevamento è stato del tutto casuale, ovvero lanciando il
mio programma A.
Il mio programma ha letto un pid da un file.pid. Ha provato a verificare
se il pid esistesse semplicemente con un:
ret = access("/proc/pid", F_OK)
(se il metodo è sbagliato accetto vivamente consigli)
e risultava che esisteva. Al momento del lancio del programma però, il
programma B era disattivato quindi era quasi impossibile che quel pid
fosse stato gia riutilizzato, quindi era una condizione quasi
"impossibile" per quel preciso momento. Per scrupolo ho provato a
verificare con ps e con ls /proc e il processo non veniva listato.
Effettuando un cd /proc/pid e un ls ho trovato tutta la struttura del
processo e mi sono allarmato.
Ora per far capire meglio il tutto faccio un piccolo esempio.
Esempio:
Mio programma A legge il file.pid e dice che dentro ci sta il pid 1555.
Il mio programma con la chiamata access() dice che la dir "pid" esiste e
non avvia il programma B.
Se do un "ps aux | grep 1555" oppure un "ls /proc | grep 1555" non
ottengo nessun risultato. Questo dovrebbe indicare (almeno in buona
parte) che un processo non è attivo.
ma un comando come:
cat /proc/1555/cmdline
kill 1555
che vanno a buon fine su un processo che non è listato mi suona molto
strano.
All'inizio pensavo che il sistema fosse stato violato, ma su uno nuovo
di pacca, distro diversa,senza avviare X il "problema" persiste.
Nel successivo test che ho fatto per indagare su questo comportamento ha
visto coinvolti uno script.sh che lancia:
ps aux > pidlist
./programma
Tutto eseguito da root.
Il programma di test è scritto in C, è molto primitivo e incompleto
(abbiate pietà, l'ho scritto molto in fretta), rileva solo i processi
che potrebbero essere sospetti. Dato che il ps aux viene lanciato prima
dell'avvio del programma di controllo, potrebbero essere stati creati
altri processi di brevissima durata che appaiono in /proc ma non in ps
aux (in quanto lanciato prima).
Quindi potrebbero esserci dei pid validi e rimane all'utente il
controllo finale, ovvero verificare che il processo pid rilevato non
appaia in /proc ne in ps ma che sia possibile accederci.
Voglio anche precisare che il programma ha tempi di esecuzioni molto bassi:
# time ./proc_check.sh
....
real 0m0.060s
user 0m0.016s
sys 0m0.036s
Il programma cmq effettua alcune operazioni:
1) legge il numero massimo di processi che possono essere lanciati sul
sistema.
2) legge il file pidlist
3) esegue un ciclo che va da 0 a maxpid. In questo ciclo utilizzo
l'indice (c = da 0 a maxpid) come pid del processo. Per ogni ciclo,
effettuo un controllo su /proc/c con access(). Se access() ritorna che
il /proc/c non esiste allora il ciclo continua con il prossimo pid
ottenuto dal ciclo (indice c), se invece vede che esiste, effettua un
controllo sulla lista dei processi di pidlist. Se il processo viene
trovato, allora continua con il processo successivo in quanto la
condizione è normale, ma se non lo trova emette un alert che stampa il
PID che potrebbe essere infausto. A questo punto è compito dell'utente
verificare se:
1) ps aux | grep PID (non da risultato)
2) ls /proc | grep PID (non da risultato)
3) cd /proc/PID && cat cmdline (da risultato)
4) kill PID (da risultato)
Lanciando il programma vengono emessi 184 alert, riporto la parte
finale del file:
(tra i 184 alert potrebbero esserci alert per processi validi, l'user
deve controllare)
....
pid 17873 ALERT
pid 17874 ALERT
pid 17937 ALERT
pid 17938 ALERT
pid 17939 ALERT
pid 19524 ALERT
pid 19558 ALERT
pid 19559 ALERT
pid 19562 ALERT
pid 19571 ALERT
pid 19572 ALERT
pid 19574 ALERT
pid 19603 ALERT
Prendo in esame l'ultimo processo, 19603:
# ps aux | grep 19603
root 19619 0.0 0.0 7848 876 pts/3 S+ 18:45 0:00 grep 19603
# ls /proc | grep 19603
# ls /proc
non riporta il pid 19603 e provando ad accederci ottengo
root@HOSTNAME# cd /proc/19603
bash: cd: /proc/19603: File o directory non esistente
root@HOSTNAME# kill 19603
bash: kill: (19603) - Nessun processo corrispondente
Ma con il penultimo pid (19574):
root@HOSTNAME:/proc# ps aux | grep 19574
root 19836 0.0 0.0 7848 876 pts/3 S+ 18:51 0:00 grep 19574
root@HOSTNAME:/proc# ls (lista processi ma non il 19574)
root@HOSTNAME:/proc# ls -ld 19574 (lista le informazioni legate all dir
del pid con owner l'utente che l'ha avviato)
root@HOSTNAME:/proc# cd 19574 (scritto manulamente perche il
completamento con questo pid non listato non funziona)
root@HOSTNAME:/proc/19574# ls
attr cgroup comm cwd fd limits mem
mountstats numa_maps oom_score_adj root smaps statm task
autogroup clear_refs coredump_filter environ fdinfo loginuid
mountinfo net oom_adj pagemap sched stack
status wchan
auxv cmdline cpuset exe io maps
mounts ns oom_score personality sessionid stat syscall
root@HOSTNAME:/proc/19574# cat cmdline
amarokroot@HOSTNAME:/proc/19574#
root@HOSTNAME:/proc/19574# ps aux | grep amarok
1000 7689 1.3 1.7 5022948 283844 tty1 SLl mar15 20:48 amarok
root 19913 0.0 0.0 7852 868 pts/3 S+ 18:53 0:00 grep amarok
Come potete vedere, il processo amarok è 7689 mentre il nostro processo
è 19574.
Amarok è in funzione e dando un
root@HOSTNAME:/proc# kill 19574
Amarok viene chiuso e la musica finisce.
Ora come si puo vedere, amarok ha il pid a 7689 mentre è stato ucciso
con un kill al pid 19574 non rilevabile con ps e in /proc.
Ma ancora non quadra.
Il pid di amarok è molto basso [7689] mentre quello rilevato è 19574.
Questo potrebbe essere dovuto dal fatto che ho lasciato la macchina
accesa dal giorno prima e amarok era avviato ma non faceva nulla (in
sleep). Avendo avviato il play potrebbe aver creato un thread con il
quale effettua il play reale.
L'unica cosa che al momento mi viene in mente (ipotesi irreale) è che
amarok (e gli altri programmi individuati) ha dei thread e che il kernel
gestisca i thread come dei processi (creando quindi la struttura del
processo) ma non li rende visibili su /proc in modo tale che le altre
utility come ps o top non possano rilevarli come processi. L'utente non
vedendoli non puo considerarli e va ad effettuare il kill direttamente
sul processo non andando a toccare il thread (magari la politica è: il
kill deve essere effettuato sul processo e non sul thread). Questo non
vuol dire che non sia possibile effettuare il kill su quel pid.
Qualcuno ha info in merito?
(scusate di nuovo per la lunghezza, ho voluto scrivere tutto il test per
condividere questa esperienza).
Un saluto, Alessandro.
Reply to: