Làm thế nào để tìm đầu kia của kết nối ổ cắm unix?


44

Tôi có một quy trình (dbus-daemon) có nhiều kết nối mở trên các ổ cắm UNIX. Một trong những kết nối này là 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

Dựa trên các kết nối số, tôi giả định rằng dbus-daemon thực sự là máy chủ. Cái nào cũng được. Nhưng làm thế nào tôi có thể tìm thấy quá trình nào được kết nối với nó - sử dụng kết nối xử lý tệp thứ 36 trong dbus-launcher? Đã thử lsof và thậm chí greps trên / Proc / net / unix nhưng tôi không thể tìm ra cách để tìm quy trình khách hàng.


Câu trả lời:


25

Khá gần đây tôi tình cờ gặp một vấn đề tương tự. Tôi đã bị sốc khi biết rằng có những trường hợp không thể thực hiện được. Tôi đã đưa ra một nhận xét từ người tạo ra lsof (Vic Abell), nơi ông chỉ ra rằng điều này phụ thuộc rất nhiều vào việc thực hiện ổ cắm unix. Đôi khi cái gọi là thông tin "điểm cuối" cho ổ cắm có sẵn và đôi khi không. Thật không may trong Linux khi ông chỉ ra.

Ví dụ, trên Linux, trong đó lsof phải sử dụng / Proc / net / unix, tất cả các socket miền UNIX đều có đường dẫn ràng buộc, nhưng không có thông tin điểm cuối. Thường không có con đường ràng buộc. Điều đó thường làm cho không thể xác định điểm cuối khác, nhưng đó là kết quả của việc triển khai hệ thống tệp Linux / Proc.

Nếu bạn nhìn vào / Proc / net / unix bạn có thể tự mình nhìn thấy, rằng (ít nhất là trên hệ thống của tôi), anh ấy hoàn toàn đúng. Tôi vẫn bị sốc, vì tôi thấy tính năng này rất cần thiết trong khi theo dõi các sự cố máy chủ.



Lưu ý rằng /proc/net/unixSILL cho bạn biết tệp mục tiêu của tham chiếu ổ cắm tên miền ngẫu nhiên mà bạn đã đào ra /proc/.../fd/.
i336_

27

Câu trả lời này chỉ dành cho Linux. Dựa trên câu trả lời từ Unix & Linux Stack Exchange, tôi đã xác định thành công đầu kia của ổ cắm miền unix sử dụng cấu trúc dữ liệu trong kernel, được truy cập bằng gdb/proc/kcore. Bạn cần kích hoạt các tùy chọn CONFIG_DEBUG_INFOCONFIG_PROC_KCOREkernel.

Bạn có thể sử dụng lsofđể lấy địa chỉ kernel của socket, có dạng con trỏ, vd 0xffff8803e256d9c0. Con số đó thực sự là địa chỉ của cấu trúc hoặc kiểu bộ nhớ trong kernel có liên quan struct unix_sock. Cấu trúc đó có một trường được gọi là peerđiểm ở đầu kia của ổ cắm. Vì vậy, các lệnh

# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer

sẽ in địa chỉ của đầu kia của kết nối. Bạn có thể grep đầu ra của lsof -Usố đó để xác định quy trình và số mô tả tệp của đầu kia.

Một số bản phân phối dường như cung cấp các ký hiệu gỡ lỗi kernel như một gói riêng, sẽ thay thế vmlinuxtệp trong lệnh trên.


Điều này có vẻ thú vị, nhưng yêu cầu biên dịch lại kernel dường như là một quá mức cần thiết. Tôi nghĩ rằng có lẽ có thể làm điều đó, không cần kernel làm bằng tay và không sử dụng gdb, chỉ bằng cách nhìn trộm các giá trị trong kcore và thực hiện một số giải mã "thủ công" các giá trị.

3
@depesz, tất cả những gì bạn cần biết là phần bù của peerthành viên trong unix_sockcấu trúc. Trên hệ thống x86_64 của tôi, phần bù đó là 656 byte, vì vậy tôi có thể có được đầu kia bằng cách sử dụng p ((void**)0xffff8803e256d9c0)[0x52]. Bạn vẫn cần CONFIG_PROC_KCORE, rõ ràng.
MvG

12

Trên thực tế, sstừ iproute2(thay thế cho netstat, ifconfig, v.v.) có thể hiển thị thông tin này.

Dưới đây là một ví dụ hiển thị ổ cắm tên miền ssh-agent unix mà sshquá trình đã kết nối:

$ 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))

Hừm. Thật thú vị ... Tôi đã bỏ lỡ rằng các cột "Địa chỉ: Cổng" có thể được khớp, mặc dù cột "Ngang hàng" hoàn toàn vô dụng đối với các ổ cắm tên miền unix.
SamB

9

Ổ cắm Unix thường được gán số theo cặp và thường liên tiếp. Vì vậy, cặp cho bạn có thể sẽ là 1013410 +/- 1. Xem cái nào trong hai cái đó tồn tại và đoán tại thủ phạm.


8

Tôi đã viết một công cụ sử dụng phương thức gdb của MvG để lấy thông tin ngang hàng của socket một cách đáng tin cậy, các ký hiệu gỡ lỗi kernel không cần thiết.

Để có được quá trình kết nối với một ổ cắm nhất định, hãy chuyển cho nó số inode:

# socket_peer 1013410
3703 thunderbird 

Để tìm ra tất cả các quy trình cùng một lúc netstat_unix, nó thêm một cột vào đầu ra của 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       
...

Hãy thử netstat_unix --dumpnếu bạn cần đầu ra dễ phân tích.
Xem https://github.com/lemonsqueeze/unix_sockets_peers để biết chi tiết.

Để biết thông tin, hack inode + 1 / -1 không đáng tin cậy. Nó hoạt động hầu hết thời gian nhưng sẽ thất bại hoặc (tệ hơn) trả lại ổ cắm sai nếu bạn không gặp may.


1

Chỉnh sửa hệ thống của bạn.

Trong tệp này, bạn có thể thêm nhiều thứ cho mục đích gỡ lỗi.

Vị trí tập tin: /etc/dbus-1/system.conf

Đối với mục đích gỡ lỗi, bạn có thể chỉnh sửa system.conf của mình để cho phép nghe lén:

  1. thay thế phần chính sách bằng cách:

    <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>

  2. Xóa dòng bao gồm: system.d

    <includedir>system.d</includedir>

Nguồn: http://old.nabble.com/dbus-send-error-td29893862.html


Một số nội dung hữu ích khác liên quan đến ổ cắm unix

Cách đơn giản nhất để tìm hiểu những gì đang xảy ra trên xe buýt là chạy dbus-monitorchương trình, đi kèm với gói D-Bus

Ngoài ra, bạn có thể thử sử dụng dbus-cleanup-socketsđể dọn sạch các ổ cắm còn sót lại.

Lệnh sau sẽ cho bạn biết quá trình nào được kết nối với ổ cắm dbus bao nhiêu lần dựa trên netstatđầu ra:

sudo netstat -nap | grep dbus | grep CONNECTED | awk '{print $8}' | sort | uniq -c

(đã thử nghiệm trên Ubuntu)

Cách cứng: Lệnh này sẽ tìm thủ công các quy trình từ / Proc và hiển thị đang sử dụng hầu hết các kết nối (tất cả các loại ổ cắm):

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")}'

Ví dụ đầu ra:

(đếm, PID và dòng tiếp theo chứa thông tin chi tiết về quy trình)

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

(đã thử nghiệm trên Ubuntu)

Chúc vui vẻ.


Xem thêm các bài viết liên quan để tham khảo:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.