解決策 1:
この回答は Linux のみを対象としています。
Linux 3.3 の更新: Zulakis が別の回答 (+1 that) で書いたように、iproute2 の ss を使用して、ローカル エンドとピアを識別するソケット接続ごとに i ノード番号のペアを取得できます。これは、UNIX_DIAG_PEER
を持つ sock_diag(7) と同じ機構に基づいているようです。 ピアを識別する属性。 Unix &Linux Stack Exchange での Totor による回答は、カーネルと iproute2 の関連するコミットへのリンクであり、UNIX_DIAG
の必要性についても言及しています。 カーネル構成設定。
Linux pre 3.3 の元の回答は次のとおりです。
Unix &Linux Stack Exchange からの回答に基づいて、gdb
を使用してアクセスしたカーネル内データ構造を使用して、UNIX ドメイン ソケットのもう一方の端を特定することに成功しました。 と /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
接続のもう一方の端のアドレスを出力します。 lsof -U
の出力を grep できます
一部のディストリビューションでは、カーネル デバッグ シンボルを別のパッケージとして提供しているようで、これが vmlinux
の代わりになります。
解決策 2:
ごく最近、私は同様の問題に出くわしました。これが不可能な場合があることを知ってショックを受けました。 lsof の作成者 (Vic Abell) からのコメントを掘り下げました。彼は、これは unix ソケットの実装に大きく依存していると指摘しました。ソケットのいわゆる「エンドポイント」情報が利用できる場合と利用できない場合があります。残念ながら、彼が指摘するように Linux では不可能です。
<ブロック引用>たとえば、lsof が /proc/net/unix を使用する必要がある Linux では、すべての UNIX ドメインソケットにバインドされたパスがありますが、エンドポイント情報はありません。多くの場合、バインドされたパスはありません。これにより、他のエンドポイントを特定できなくなることがよくありますが、これは Linux /proc ファイル システムの実装の結果です。
/proc/net/unix を見ると、(少なくとも私のシステムでは) 彼が絶対に正しいことがわかります。サーバーの問題を追跡する際に、このような機能が不可欠であるため、私はまだショックを受けています.
解決策 3:
実は ss
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:
Unix ソケット 通常 ペアで番号が割り当てられ、通常は連続しています。したがって、ペアはおそらく 1013410+/-1 になります。この 2 つのうちどちらが存在するかを確認し、犯人を推測してください。
解決策 5:
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 ハックは信頼できません。ほとんどの場合は機能しますが、運が悪いと失敗するか、(さらに悪いことに) 間違ったソケットを返します。