J'ai un processus (dbus-daemon) qui a de nombreuses connexions ouvertes sur les sockets UNIX. L'une de ces connexions est fd # 36:
=$ ps uw -p 23284
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
depesz 23284 0.0 0.0 24680 1772 ? Ss 15:25 0:00 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
=$ ls -l /proc/23284/fd/36
lrwx------ 1 depesz depesz 64 2011-03-28 15:32 /proc/23284/fd/36 -> socket:[1013410]
=$ netstat -nxp | grep 1013410
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
unix 3 [ ] STREAM CONNECTED 1013410 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
=$ netstat -nxp | grep dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1013953 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1013825 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1013726 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1013471 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1013410 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1012325 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1012302 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1012289 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1012151 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011957 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011937 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011900 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011775 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011771 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011769 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011766 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011663 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011635 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011627 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011540 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011480 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011349 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011312 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011284 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011250 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011231 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011155 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011061 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011049 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011035 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1011013 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1010961 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
unix 3 [ ] STREAM CONNECTED 1010945 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
Sur la base des connexions numériques, je suppose que dbus-daemon est en fait un serveur. Ce qui est OK. Mais comment puis-je trouver le processus qui lui est connecté - à l'aide de la connexion qui est le 36e descripteur de fichier dans dbus-launcher? J'ai essayé lsof et même greps sur/proc/net/unix mais je ne peux pas trouver un moyen de trouver le processus client.
Tout récemment, je suis tombé sur un problème similaire. J'ai été choqué de découvrir qu'il y a des cas où cela pourrait ne pas être possible. J'ai déterré un commentaire du créateur de lsof (Vic Abell) où il a souligné que cela dépend fortement de l'implémentation de socket unix. Parfois, les informations dites de "point de terminaison" pour le socket sont disponibles et parfois non. Malheureusement, c'est impossible sous Linux comme il le fait remarquer.
Sous Linux, par exemple, où lsof doit utiliser/proc/net/unix, tous les sockets de domaine UNIX ont un chemin lié, mais aucune information de noeud final. Souvent, il n'y a pas de chemin limité. Cela rend souvent impossible de déterminer l'autre point de terminaison, mais c'est le résultat de l'implémentation du système de fichiers Linux/proc.
Si vous regardez/proc/net/unix vous pouvez voir par vous-même que (au moins sur mon système) il a absolument raison. Je suis toujours choqué, car je trouve cette fonctionnalité essentielle lors du suivi des problèmes de serveur.
Cette réponse est pour Linux uniquement. Basé sur ne réponse à partir de l'échange de pile Unix et Linux, je identifié avec succès l'autre extrémité d'une socket de domaine unix utilisant des structures de données dans le noyau, accessible à l'aide de gdb
et /proc/kcore
. Vous devez activer le CONFIG_DEBUG_INFO
et CONFIG_PROC_KCORE
options du noyau.
Vous pouvez utiliser lsof
pour obtenir l'adresse du noyau de la socket, qui prend la forme d'un pointeur, par ex. 0xffff8803e256d9c0
. Ce numéro est en fait l'adresse de la structure de mémoire dans le noyau ou le type struct unix_sock
. Cette structure a un champ appelé peer
qui pointe à l'autre extrémité du socket. Ainsi, les commandes
# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer
imprime l'adresse de l'autre extrémité de la connexion. Vous pouvez grep la sortie de lsof -U
pour que ce numéro identifie le processus et le numéro de descripteur de fichier de cette autre extrémité.
Certaines distributions semblent fournir des symboles de débogage du noyau dans un package séparé, qui remplacerait le fichier vmlinux
dans la commande ci-dessus.
En fait, ss
de iproute2
(remplacement de netstat, ifconfig, etc.) peut afficher ces informations.
Voici un exemple montrant un socket de domaine unix ssh-agent auquel un processus ssh
s'est connecté:
$ Sudo ss -a --unix -p
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
u_str ESTAB 0 0 /tmp/ssh-XxnMh2MdLBxo/agent.27402 651026 * 651642 users:(("ssh-agent",pid=27403,fd=4)
u_str ESTAB 0 0 * 651642 * 651026 users:(("ssh",pid=2019,fd=4))
Les sockets Unix généralement sont des numéros attribués par paires et sont généralement consécutifs. Donc, la paire pour vous serait probablement 1013410 +/- 1. Voyez lequel de ces deux existe et devinez le coupable.
J'ai écrit un outil qui utilise le MvG méthode gdb pour obtenir de manière fiable des informations sur les pairs de socket, les symboles de débogage du noyau ne sont pas nécessaires.
Pour obtenir le processus connecté à une socket donnée, passez-lui le numéro d'inode:
# socket_peer 1013410
3703 Thunderbird
Pour connaître tous les processus à la fois, utilisez netstat_unix
, il ajoute une colonne à la sortie de netstat:
# netstat_unix
Proto RefCnt Flags Type State I-Node PID/Program name Peer PID/Program name Path
unix 3 [ ] STREAM CONNECTED 6825 982/Xorg 1497/compiz /tmp/.X11-unix/X0
unix 3 [ ] STREAM CONNECTED 6824 1497/compiz 982/Xorg
unix 3 [ ] SEQPACKET CONNECTED 207142 3770/chromium-brows 17783/UMA-Session-R
unix 3 [ ] STREAM CONNECTED 204903 1523/pulseaudio 3703/Thunderbird
unix 3 [ ] STREAM CONNECTED 204902 3703/Thunderbird 1523/pulseaudio
unix 3 [ ] STREAM CONNECTED 204666 1523/pulseaudio 3703/Thunderbird
...
Essayez netstat_unix --dump
si vous avez besoin d'une sortie facile à analyser.
Voir https://github.com/lemonsqueeze/unix_sockets_peers pour plus de détails.
Pour info, le inode + 1/-1 hack n'est pas fiable. Cela fonctionne la plupart du temps mais échouera ou (pire) retournera la mauvaise prise si vous n'avez pas de chance.
Dans ce fichier, vous pouvez ajouter d'autres éléments à des fins de débogage.
Emplacement du fichier: /etc/dbus-1/system.conf
À des fins de débogage, vous pouvez modifier votre system.conf pour autoriser l'écoute:
remplacer la section politique par:
<policy context="default">
<!-- Allow everything to be sent -->
<allow send_destination="*" eavesdrop="true"/>
<!-- Allow everything to be received -->
<allow eavesdrop="true"/>
<!-- Allow anyone to own anything -->
<allow own="*"/>
<!-- XXX: Allow all users to connect -->
<allow user="*"/> </policy>
Supprimez la ligne incluse: system.d
<includedir>system.d</includedir>
Source: http://old.nabble.com/dbus-send-error-td29893862.html
Le moyen le plus simple de comprendre ce qui se passe dans le bus est d'exécuter le dbus-monitor
programme, fourni avec le package D-Bus
Vous pouvez également essayer d'utiliser dbus-cleanup-sockets
pour nettoyer les prises restantes.
La commande suivante vous montrera quel processus est connecté combien de fois aux sockets dbus en fonction de la sortie netstat
:
Sudo netstat -nap | grep dbus | grep CONNECTED | awk '{print $8}' | sort | uniq -c
(testé sur Ubuntu)
Façon hardcore: Cette commande trouvera manuellement les processus de/proc et affichera ceux qui utilisent le plus de connexions (tous les types de sockets):
ls -lR */fd/* | grep socket | sed -r "s@([0-9{1}]+)/fd/@_\1_@g" | awk -F_ '{print $2}' | uniq -c | sort -n | awk '{print $1" "$2; print system("ps "$2"|tail -n1")}'
Exemple de sortie:
(compter, PID et la ligne suivante contient des détails sur le processus)
25 3732
3732 ? Ss 0:38 /usr/bin/wineserver
89 1970
1970 ? Ss 0:02 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
(testé sur Ubuntu)
S'amuser.
Voir également les articles associés pour la référence: