Dlaczego liczba otwartych plików jest ograniczona w systemie Linux?

136

W tej chwili wiem, jak:

  • znajdź limit otwartych plików na proces: ulimit -n
  • policz wszystkie otwarte pliki według wszystkich procesów: lsof | wc -l
  • uzyskaj maksymalną dozwoloną liczbę otwartych plików: cat /proc/sys/fs/file-max

Moje pytanie brzmi: dlaczego istnieje limit otwartych plików w systemie Linux?

Xanpeng
źródło
2
@Rob Googled trochę i okazuje się, że to bomba widelcowa , czy można go użyć do wyjaśnienia limitu otwartych plików?
xanpeng,
6
Cóż, limity procesów i limity plików są ważne, więc rzeczy takie jak bomby widełkowe nie psują serwera / komputera wszystkim użytkownikom, tylko użytkownikowi, który to robi i tylko tymczasowo. W przeciwnym razie ktoś na wspólnym serwerze mógłby uruchomić widełkę i całkowicie powalić ją dla wszystkich użytkowników, a nie tylko siebie.
Rob
3
Miło podsumowując kilka bardzo przydatnych poleceń! : +1:
Joshua Pinter,
7
@Rob, bomba widełkowa nie ma z tym nic wspólnego, ponieważ limit plików jest na proces i za każdym razem, gdy rozwidlasz, nie otwiera nowego uchwytu pliku.
psusi

Odpowiedzi:

86

Powodem jest to, że system operacyjny potrzebuje pamięci do zarządzania każdym otwartym plikiem, a pamięć jest ograniczonym zasobem - szczególnie w systemach osadzonych.

Jako użytkownik root możesz zmienić maksymalną liczbę otwartych plików na proces (przez ulimit -n) i na system (np echo 800000 > /proc/sys/fs/file-max.).

Jofel
źródło
21
Istnieje również powód bezpieczeństwa: gdyby nie było żadnych ograniczeń, oprogramowanie użytkownika byłoby w stanie tworzyć pliki bez końca, dopóki serwer nie przestanie działać.
Coren
15
@Coren Omówione tutaj ograniczenia dotyczą tylko liczby otwartych programów obsługi plików. Ponieważ program może również zamykać programy obsługi plików, może utworzyć tyle plików i tyle, ile chce, dopóki całe dostępne miejsce na dysku nie zostanie zapełnione. Aby temu zapobiec, możesz użyć przydziałów dysku lub oddzielnych partycji. Masz rację w tym sensie, że jednym z aspektów bezpieczeństwa jest zapobieganie wyczerpaniu zasobów - i do tego istnieją ograniczenia.
jofel
1
@jofel Thanks. Wydaje mi się, że otwarte uchwyty plików są reprezentowane przez instancje pliku struct , a rozmiar tej struktury jest dość mały (poziom bajtów), więc czy mogę ustawić /.../file-maxz dość dużą wartością, dopóki pamięć nie zostanie zużyta?
xanpeng,
7
@xanpeng Nie jestem ekspertem od jądra, ale, o ile widzę, domyślnie file-maxwydaje się, że rozmiar pamięci RAM jest podzielony przez 10k. Ponieważ rzeczywista pamięć używana na moduł obsługi plików powinna być znacznie mniejsza (rozmiar struct fileplus część pamięci zależnej od sterownika), wydaje się to dość konserwatywnym ograniczeniem.
jofel
63

Należy pamiętać, że lsof | wc -lpodsumowuje wiele zduplikowanych wpisów (rozwidlone procesy mogą współużytkować uchwyty plików itp.). Liczba ta może być znacznie wyższa niż ustawiony limit /proc/sys/fs/file-max.

Aby uzyskać bieżącą liczbę otwartych plików z punktu widzenia jądra Linux, wykonaj następujące czynności:

cat /proc/sys/fs/file-nr

Przykład: na tym serwerze jest 40096 spośród maksymalnie 65536 otwartych plików, chociaż lsof zgłasza znacznie większą liczbę:

# cat /proc/sys/fs/file-max
65536
# cat /proc/sys/fs/file-nr 
40096   0       65536
# lsof | wc -l
521504
grebneke
źródło
1
Jak lsofzgłosi wiele plików dwa razy lub więcej, na przykład /dev/nullmożesz spróbować zgadnąć z:lsof|awk '{print $9}'|sort|uniq|wc -l
Yvan
możesz użyć, lsof|awk '!a[$NF]++{c++}END{print c}'aby uzyskać nieuplikowaną liczbę otwartych plików.
P ....
18

Myślę, że dzieje się tak głównie z przyczyn historycznych.

Deskryptor pliku Unix jest mała intwartość zwracana przez funkcje jak openi creat, i przeszedł do read, write, closei tak dalej.

Przynajmniej we wczesnych wersjach Uniksa deskryptor pliku był po prostu indeksem struktury tablic struktur o stałym rozmiarze na proces, w których każda struktura zawiera informacje o otwartym pliku. Jeśli dobrze pamiętam, niektóre wczesne systemy ograniczały rozmiar tej tabeli do około 20.

Bardziej nowoczesne systemy mają wyższe limity, ale zachowały ten sam ogólny schemat, w dużej mierze poza bezwładnością.

Keith Thompson
źródło
1
20 był limitem Solaris dla struktur danych PLIK w języku C. Liczba uchwytów plików była zawsze większa.
Lothar
@Lothar: Ciekawe. Zastanawiam się, dlaczego limity byłyby różne. Biorąc pod uwagę filenoi fdopenfunkcje będę oczekiwać ich być prawie zamiennie.
Keith Thompson
Plik unix to coś więcej niż tylko zwrócony uchwyt pliku (int). Istnieją bufory dyskowe i blok kontroli plików, który określa bieżące przesunięcie pliku, właściciela pliku, uprawnienia, i-węzeł itp.
ChuckCottrill
@ChuckCottrill: Tak, oczywiście. Ale większość tych informacji musi być przechowywana bez względu na to, czy dostęp do pliku uzyskuje się za pomocą intdeskryptora czy FILE*. Jeśli otworzysz więcej niż 20 plików za pośrednictwem open(), nie fdopen()powiedzie się?
Keith Thompson