Tại sao chiều dài đường dẫn ổ cắm giới hạn trong một trăm ký tự?


18

Trên các tên đường dẫn hệ thống Unix thường hầu như không có giới hạn độ dài (4096 ký tự trên Linux) ... ngoại trừ các đường dẫn tệp ổ cắm được giới hạn trong khoảng 100 ký tự (107 ký tự trên Linux ).

  • Câu hỏi đầu tiên: tại sao giới hạn thấp như vậy?

Tôi đã kiểm tra xem có vẻ như có thể khắc phục giới hạn này bằng cách thay đổi thư mục làm việc hiện tại và tạo trong các thư mục khác nhau một số tệp ổ cắm bằng cùng một đường dẫn ./myfile.sock: các ứng dụng khách dường như kết nối chính xác với các quy trình máy chủ dự kiến ​​mặc dù lsofhiển thị tất cả trong số họ nghe trên cùng một đường dẫn tập tin ổ cắm.

  • Là cách giải quyết này đáng tin cậy hay tôi chỉ là may mắn?
  • Hành vi này có dành riêng cho Linux không hoặc cách giải quyết này có thể áp dụng cho các Unix khác không?

Giới hạn thậm chí còn thấp hơn (104) trên các hệ thống OpenBSD hiện tại hoặc Mac OS X 10.11.
thrig

Điều quan trọng là nó phải thấp hơn 108, vì mục đích tương thích :)

AFAIK đó là 108 ký tự trên Linux. Vui lòng kiểm tra /usr/include/$arch-linux-gnu/sys/un.h trên máy của bạn.
schaiba

@schaiba: 108 byte, có nghĩa là chuỗi 107 ký tự kết thúc bằng dấu kết thúc null.
WhiteWinterWolf

Câu trả lời:


18

Khả năng tương thích với các nền tảng khác hoặc tương thích với các công cụ cũ hơn để tránh tràn ngập trong khi sử dụng snprintf()strncpy().

Michael Kerrisk giải thích trong cuốn sách của mình tại trang 1165 - Chương 57, Sockets: tên miền Unix:

SUSv3 không chỉ định kích thước của trường sun_path. Việc triển khai BSD sớm đã sử dụng 108 và 104 byte và một triển khai hiện đại (HP-UX 11) sử dụng 92 byte. Các ứng dụng di động nên mã hóa giá trị thấp hơn này và sử dụng snprintf () hoặc strncpy () để tránh tràn bộ đệm khi ghi vào trường này.

Các anh chàng Docker thậm chí còn làm cho nó vui, bởi vì một số ổ cắm dài 110 ký tự:

Đây là lý do tại sao LINUX sử dụng ổ cắm 108 char. Điều này có thể được thay đổi? Tất nhiên. Và đây là lý do tại sao ở nơi đầu tiên, giới hạn này được tạo ra trên các Hệ điều hành cũ hơn:

Trích dẫn câu trả lời:

Đó là để phù hợp với không gian có sẵn trong cấu trúc dữ liệu kernel tiện dụng.

Trích dẫn "Thiết kế và triển khai hệ điều hành 4.4BSD" của McKusick et. al. (trang 369):

Các phương tiện quản lý bộ nhớ xoay quanh cấu trúc dữ liệu gọi là mbuf. Mbuf, hoặc bộ nhớ đệm, dài 128 byte, với 100 hoặc 108 byte không gian này được dành riêng để lưu trữ dữ liệu.

Các hệ điều hành khác (ổ cắm miền unix):


1
SUSv3 XNET im lặng vì không có sự đồng thuận về vấn đề này.
fpmurphy

Bạn có bất kỳ liên kết để chứng minh quan điểm của bạn?

Cảm ơn câu trả lời này. Có đáng tin cậy khi sử dụng một số tệp ổ cắm có tên giống hệt nhau liên quan đến các thư mục làm việc khác nhau (ví dụ: tạo tệp ổ cắm có tên ./my.socketthư mục bên dưới A/và một tệp ổ cắm khác cũng được đặt tên ./my.socketbên dưới thư mục B/)? lsofkhông phân biệt giữa hai tệp ổ cắm, tuy nhiên nó dường như vẫn hoạt động nhưng tôi tự hỏi liệu đây có phải là vì tôi may mắn không. Đây sẽ là một cách giải quyết tốt để tạo các tệp ổ cắm bên dưới một đường dẫn dài hơn kích thước cho phép.
WhiteWinterWolf

Tìm kiếm ổ cắm unix trên máy chủ của tôi, dường như mang tên đường dẫn đầy đủ: lsof -U| grep amavis(dòng mới)amavis-se 2708 zimbra 17u unix 0xffff8806c0a95400 0t0 310330411 /opt/zimbra/data/tmp/amavisd-zmq.sock

Vâng, tôi biết điều này là bất thường, do đó câu hỏi của tôi ở đây;)! Đối với những gì tôi đã thử nghiệm, tên tương đối hoạt động, nhưng nó vẫn có vẻ kỳ lạ đối với tôi ... nhưng nó hoạt động. Ứng dụng của tôi không phải là toàn hệ thống, vì vậy các tệp ổ cắm được lưu trữ với tất cả dữ liệu ứng dụng khác trong một vị trí do người dùng kiểm soát, được ưu tiên mạnh mẽ nhưng với một đường dẫn có khả năng quá dài hoặc tôi có thể lộn xộn /tmpvới hàng tấn thư mục được đặt tên duy nhất chứa một tệp ổ cắm duy nhất (hoàn toàn xấu, nhưng di động và an toàn).
WhiteWinterWolf

5

Về lý do tại sao, nwildner đã viết một câu trả lời tuyệt vời .

Ở đây tôi sẽ chỉ tập trung vào cách sử dụng và đường dẫn tương đối.

Trong nội bộ, trong khi tệp socket cũng có thể được tra cứu theo tên (tôi đoán), chúng thường được tra cứu bằng inode. Trong Linux, việc tra cứu này được đảm bảo bởi chức năng unix_find_socket_byinode()được xác định trong net / unix / af_unix.c .

Điều này có thể dễ dàng kiểm tra như sau:

  • Tạo hai thư mục A /B / .
  • Trong mỗi thư mục, tạo một quá trình lắng nghe trên các tệp ổ cắm có cùng tên. Với socatbạn sẽ sử dụng một lệnh như:
$ socat UNIX-LISTEN:./my.sock -
  • Bây giờ trao đổi các tệp ổ cắm bằng cách di chuyển A / my.sock sang B / và ngược lại.
  • Từ giờ trở đi, nếu ứng dụng khách kết nối với A / my.sock, nó sẽ liên lạc với máy chủ B và nếu kết nối với B / my.sock, nó sẽ liên lạc với máy chủ A (lưu ý rằng khi giao tiếp kết thúc, quá trình máy chủ có thể xóa một cách hợp pháp những gì nó nghĩ là tập tin ổ cắm của chính nó).

Tôi đã kiểm tra hành vi này trên một số ít hệ thống Unix (Linux Debian, FreeBSD và OpenIndiana để có được sự đa dạng), vì vậy hành vi này dường như ít phổ biến rộng rãi, nếu không phải là tiêu chuẩn.

Đường dẫn tuyệt đối thường được sử dụng như một quy ước giữa máy khách và máy chủ xử lý, vì quá trình máy khách có thể không biết cách thiết lập giao tiếp ban đầu với máy chủ.

Tuy nhiên, nếu giao tiếp ban đầu này không phải là vấn đề, thì có vẻ an toàn khi sử dụng các đường dẫn tương đối để tạo tệp ổ cắm, cho phép tránh các vấn đề về độ dài đường dẫn khi vị trí tệp ổ cắm không được điều khiển trực tiếp bởi quá trình máy chủ.

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.