我有一个进程 (dbus-daemon),它通过 UNIX 套接字建立了许多打开的连接。其中一个连接是 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
根据连接数,我假设 dbus-daemon 实际上是服务器。这没问题。但是我如何才能找到连接到它的进程 - 使用 dbus-launcher 中的第 36 个文件句柄的连接?尝试了 lsof 甚至在 /proc/net/unix 上 greps,但我找不到找到客户端进程的方法。
答案1
最近我偶然发现了一个类似的问题。我很震惊地发现,有些情况下这是不可能的。我从 lsof 的创建者(Vic Abell)那里找到了一条评论,他指出这在很大程度上取决于 unix 套接字实现。有时套接字的所谓“端点”信息可用,有时不可用。不幸的是,正如他指出的那样,在 Linux 中这是不可能的。
例如,在 Linux 上,lsof 必须使用 /proc/net/unix,所有 UNIX 域套接字都有绑定路径,但没有端点信息。通常没有绑定路径。这通常使得无法确定另一个端点,但这是 Linux /proc 文件系统实现的结果。
如果您查看 /proc/net/unix,您就会发现(至少在我的系统上)他完全正确。我仍然感到震惊,因为我发现这种功能在跟踪服务器问题时必不可少。
答案2
此答案仅适用于Linux。
Linux 3.3 更新:作为祖拉基斯写道单独答案(+1),你可以使用党卫军从iproute2获取每个套接字连接的一对 inode 编号,用于标识本地端和对等端。这似乎基于与sock_diag(7)属性来UNIX_DIAG_PEER
标识对等体。回答经过托托尔Unix & Linux Stack Exchange 上的相关提交链接核心和iproute2并且还提到了内核配置设置的必要性UNIX_DIAG
。
以下是针对 Linux 3.3 之前版本的原始答案。
基于一个答案来自 Unix & Linux Stack Exchange,我成功识别使用内核数据结构的 unix 域套接字的另一端,使用gdb
和访问/proc/kcore
。您需要启用CONFIG_DEBUG_INFO
和CONFIG_PROC_KCORE
内核选项。
您可以使用lsof
来获取套接字的内核地址,该地址采用指针的形式,例如0xffff8803e256d9c0
。该数字实际上是相关内核内存结构或类型的地址struct unix_sock
。该结构有一个名为 的字段,peer
指向套接字的另一端。因此命令
# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer
将打印连接另一端的地址。您可以在输出中 greplsof -U
该数字,以识别另一端的进程和文件描述符编号。
一些发行版似乎将内核调试符号作为单独的包提供,它将取代vmlinux
上述命令中的文件。
答案3
实际上,ss
from iproute2
(netstat、ifconfig 等的替代品)可以显示这些信息。
以下示例展示了某个ssh
进程已连接到的 ssh-agent unix 域套接字:
$ 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))
答案4
我写了一个工具使用 MvG 的gdb 方法为了可靠地获取套接字对等信息,不需要内核调试符号。
要使进程连接到给定的套接字,请向其传递 inode 编号:
# socket_peer 1013410
3703 thunderbird
要一次找出所有进程,请使用netstat_unix
,它会在 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
...
netstat_unix --dump
如果你需要易于解析的输出,请尝试一下。
请参阅https://github.com/lemonsqueeze/unix_sockets_peers了解详情。
欲了解详情,inode +1/-1 破解不可靠。它大多数时候都能正常工作,但如果你运气不好,它就会失败,或者(更糟的是)返回错误的套接字。