Tại sao số lượng tệp mở bị hạn chế trong Linux?


136

Ngay bây giờ, tôi biết làm thế nào để:

  • tìm giới hạn tệp mở cho mỗi quy trình: ulimit -n
  • đếm tất cả các tệp đã mở theo tất cả các quy trình: lsof | wc -l
  • nhận được số lượng tệp mở tối đa được phép: cat /proc/sys/fs/file-max

Câu hỏi của tôi là: Tại sao có giới hạn các tệp đang mở trong Linux?


2
@Rob Googled một chút và thấy rằng đó là một quả bom ngã ba , nó có thể được sử dụng để giải thích giới hạn tệp mở không?
xanpeng

6
Chà, giới hạn quá trình và giới hạn tệp rất quan trọng để những thứ như bom ngã ba không phá vỡ máy chủ / máy tính cho tất cả người dùng, chỉ người dùng thực hiện và chỉ tạm thời. Mặt khác, một người nào đó trên một máy chủ được chia sẻ có thể thiết lập một forkbomb và hạ gục nó hoàn toàn cho tất cả người dùng, không chỉ cho chính họ.
Cướp

3
Đẹp một tóm tắt một số lệnh rất hữu ích! : +1:
Joshua Pinter

7
@Rob, một quả bom ngã ba không liên quan gì đến nó vì giới hạn tệp là trên mỗi quy trình và mỗi lần bạn rẽ nhánh nó sẽ không mở một tệp xử lý tệp mới.
psusi

Câu trả lời:


86

Lý do là hệ điều hành cần bộ nhớ để quản lý mỗi tệp đang mở và bộ nhớ là một tài nguyên hạn chế - đặc biệt là trên các hệ thống nhúng.

Là người dùng root, bạn có thể thay đổi tối đa số lượng tệp đang mở cho mỗi quy trình (thông qua ulimit -n) và trên mỗi hệ thống (ví dụ echo 800000 > /proc/sys/fs/file-max).


21
Ngoài ra còn có một lý do bảo mật: nếu không có giới hạn, một phần mềm người dùng sẽ có thể tạo các tệp vô tận cho đến khi máy chủ ngừng hoạt động.
Coren

15
@Coren Các giới hạn được thảo luận ở đây chỉ dành cho số lượng trình xử lý tệp mở. Vì một chương trình cũng có thể đóng trình xử lý tệp, nó có thể tạo bao nhiêu tệp và lớn như nó muốn, cho đến khi tất cả không gian đĩa có sẵn đã đầy. Để ngăn chặn điều này, bạn có thể sử dụng hạn ngạch đĩa hoặc phân vùng riêng biệt. Theo nghĩa của bạn, một khía cạnh của bảo mật là ngăn chặn cạn kiệt tài nguyên - và đối với điều này có những giới hạn.
jofel

1
@jofel Cảm ơn. Tôi đoán rằng các thẻ điều khiển tệp đã mở được biểu thị bằng các thể hiện của tệp struct và kích thước của cấu trúc này khá nhỏ (mức byte), vì vậy tôi có thể đặt /.../file-maxvới giá trị khá lớn miễn là không sử dụng hết bộ nhớ?
xanpeng

7
@xanpeng Tôi không phải là chuyên gia về kernel, nhưng theo như tôi thấy, mặc định cho file-maxdường như là kích thước RAM chia cho 10k. Vì bộ nhớ thực được sử dụng cho mỗi trình xử lý tệp nên nhỏ hơn nhiều (kích thước struct filecộng với một số bộ nhớ phụ thuộc trình điều khiển), điều này có vẻ như là một giới hạn khá bảo thủ.
jofel

63

Xin lưu ý rằng lsof | wc -ltổng hợp rất nhiều mục trùng lặp (quy trình rẽ nhánh có thể chia sẻ xử lý tệp, v.v.). Con số đó có thể cao hơn nhiều so với giới hạn được đặt trong /proc/sys/fs/file-max.

Để có được số lượng tệp đang mở hiện tại theo quan điểm của nhân Linux, hãy làm điều này:

cat /proc/sys/fs/file-nr

Ví dụ: Máy chủ này có 40096 trong số tối đa 65536 tệp đang mở, mặc dù lsof báo cáo số lượng lớn hơn nhiều:

# cat /proc/sys/fs/file-max
65536
# cat /proc/sys/fs/file-nr 
40096   0       65536
# lsof | wc -l
521504

1
Như lsofsẽ báo cáo nhiều tệp hai lần trở lên, chẳng hạn như /dev/null, bạn có thể thử dự đoán tốt nhất với:lsof|awk '{print $9}'|sort|uniq|wc -l
Yvan

bạn có thể sử dụng lsof|awk '!a[$NF]++{c++}END{print c}'để có được số lượng tệp không mở trùng lặp.
P ....

18

Tôi nghĩ rằng phần lớn là vì lý do lịch sử.

Một mô tả tập tin Unix là một nhỏ intgiá trị, được trả về bởi các chức năng như opencreat, và truyền cho read, write, close, và vân vân.

Ít nhất là trong các phiên bản đầu của Unix, một bộ mô tả tệp chỉ đơn giản là một chỉ mục thành một mảng cấu trúc trên mỗi quy trình có kích thước cố định, trong đó mỗi cấu trúc chứa thông tin về một tệp đang mở. Nếu tôi nhớ lại một cách chính xác, một số hệ thống ban đầu đã giới hạn kích thước của bảng này là 20 hoặc hơn.

Các hệ thống hiện đại hơn có giới hạn cao hơn, nhưng vẫn giữ nguyên sơ đồ chung, phần lớn nằm ngoài quán tính.


1
20 là giới hạn Solaris cho cấu trúc dữ liệu FILE ngôn ngữ C. Số lượng xử lý tập tin luôn luôn lớn hơn.
Lothar

@Lothar: Thú vị. Tôi tự hỏi tại sao các giới hạn sẽ khác nhau. Với các chức năng filenofdopentôi muốn chúng gần như có thể hoán đổi cho nhau.
Keith Thompson

Một tệp unix không chỉ là tệp xử lý (int) được trả về. Có bộ đệm đĩa và khối điều khiển tệp xác định phần bù tệp hiện tại, chủ sở hữu tệp, quyền, inode, v.v.
ChuckCottrill

@ChuckCottrill: Vâng, tất nhiên. Nhưng hầu hết các thông tin đó phải được lưu trữ cho dù một tệp được truy cập thông qua một intmô tả hoặc a FILE*. Nếu bạn có hơn 20 tệp được mở qua open(), sẽ fdopen()thất bại?
Keith Thompson
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.