Utiliser DTrace pour tracer un accès disque
Posted by Daniel on 15 Mar 2010 at 09:00 | Tagged as: solaris
Dans des environnements Solaris, on rencontre de temps à autres des tentatives d'accès à des filesystems automontés qui n'existent pas, typiquement à cause de règles génériques dans une map d'automontage, ou tout simplement pour des accès à l'interface /net.
Jusqu'à Solaris 10, il était virtuellement impossible de déterminer qui était à l'origine d'un tel accès. Avec DTrace, ça devient non seulement possible, mais même franchement simple.
On va pour cela simplement tracer l'ensemble des appels systèmes de type stat, qui sont généralement utilisés dans ce type de situation pour tester l'existence d'un fichier, vérifier ses droits, etc.
Voilà un exemple de requête possible, affichant PID, PPID, nom du processus et l'argument passé à l'appel système, autrement dit le nom du fichier :
# dtrace -n 'syscall::stat*:entry { printf("--- %d --- %d --- %s - %s",pid,ppid, execname,copyinstr(arg0)); }' dtrace: description 'syscall::stat*:entry ' matched 5 probes CPU ID FUNCTION:NAME 4 4110 stat:entry --- 13973 --- 12099 --- emagent - /var/adm/utmp 4 4110 stat:entry --- 25122 --- 25107 --- bptm - /etc/resolv.conf 4 4110 stat:entry --- 25122 --- 25107 --- bptm - /etc/resolv.conf 4 4110 stat:entry --- 25122 --- 25107 --- bptm - /usr/openv/netbackup/bp.conf 4 4110 stat:entry --- 25122 --- 25107 --- bptm - /usr/openv/netbackup/bp.conf ^C
Etant donné que le processus responsable de la requête n'existe pas forcément plus de quelques instants, il vaut mieux ne pas se contenter du PID et du nom du processus, on affichera donc également son uid/gid pour savoir à qui il appartient. Et comme tout ça n'est pas forcément très lisible, on peut rajouter un petit grep au bout. Mettons que l'on cherche à tracer les tentatives d'accès à /net/inexistant :
# dtrace -n 'syscall::stat*:entry { printf("pid=%d - uid=%d - gid=%d -- %s -- %s", pid,uid,gid,execname,copyinstr(arg0)); }' | grep inexistant dtrace: description 'syscall::stat*:entry ' matched 5 probes 4 4462 stat64:entry pid=23621 - uid=1111 - gid=1111 -- bash -- /net/inexistant
Et voilà, nous avons un coupable, et même si le processus en lui-même a disparu, on sait au moins qu'on peut chercher du coté du user 1111.