flock (2) kontra fcntl (2) nad NFS

19

Dokumentacja Perla 5.x stwierdza, że ​​jego implementacja flock (..) użyje jednego z następujących rodzimych wywołań, zaczynając od 1 i pracując w kierunku 3, jeśli jest niedostępna:

  1. stado (2)
  2. fcntl (2)
  3. lockf (3)

W porządku. Być może zauważyłeś jednak ich wyłączenie odpowiedzialności, że flock (2) nie powinien być używany w systemie plików NFS. Dokument sugeruje użycie flagi -Ud_flock, aby zmusić Perla do użycia flock (2). Strona podręcznika flock (2) (w Redhat) zawiera podobne oświadczenie dotyczące problemów z NFS.

Moje pytanie brzmi: dlaczego!?!? Nie mogę znaleźć szczegółowego artykułu ani wyjaśnienia DLACZEGO stado (2) jest niebezpieczne w przypadku NFS.

Napisałem kilka skryptów testowych w C i Perlu, zarówno na Redhat (gdzie używany jest flock (2)), jak i na Solarisie (gdzie używany jest fcntl (2)). Uruchomiłem strace / kratownicę, aby upewnić się, że Perl rzeczywiście używa odpowiednio flock (2) i fcntl (2). Nie mogłem powielić żadnych problemów, w których zamek nie był honorowany! Co daje??

Jmoney38
źródło

Odpowiedzi:

3

Niedawno Lennart Poettering zagłębił się w zachowanie blokowania systemu plików w systemie Linux, co nie maluje szczególnie różowego obrazu do blokowania NFS (szczególnie kontynuacja, do której prowadzi na dole posta).

http://0pointer.de/blog/projects/locking.html

Ivatar
źródło
1
Właśnie takiego rodzaju informacji szukałem. Dziękuję Ci! Po kilku tygodniach dochodzenia jest to bardzo podobne rozwiązanie, do którego doszedłem, ale wspaniale jest przeczytać artykuł, który potwierdza moje podejrzenia (i sugeruje inne). Link z komentarzy na tej stronie był również dobrym odnośnikiem oraz dobrym artykułem o POSIX i jego historii): samba.org/samba/news/articles/low_point/tale_two_stds_os2.html
Jmoney38
15

Jestem pewien, że patrzysz na starsze obawy. Przypomnijmy, że instrukcja Perl5 została wydana w 1994 roku i że była to tylko edycja instrukcji Perl4 z 1991 roku. W tamtych czasach prawdopodobnie można powiedzieć o często nazywanym Nightmare File System, że „nie tak dobrze, jak niedźwiedź tańczy” zadziwia, ale w ogóle tańczy ".

NFS2 w epoce 1991 powoli wylewał się ze Słońca na inne platformy i był stosunkowo surowy. Model bezpieczeństwa zasadniczo nie istniał (root na maszynie klienta mógł odczytać pełną zawartość montowania NFS), a blokowanie - poprzez nfs.lockd - było tą stroną eksperymentalną. Głupotą byłoby oczekiwać, że semantyka stad będzie działać poprawnie, jeśli w ogóle między dwiema rzekomo interoperacyjnymi implementacjami. Koncentryczny był dominującym PHY Ethernet w czasie, którego wielu użytkowników sieci nigdy nie odczuwało niezadowolenia z używania (co masz na myśli, że zapomniałeś założyć rezystor terminujący 50𝛀?), Jeśli to daje ci lepszą kontrolę nad stanem intranetów.

Larry Wall i jego ekipa mieli wszelkie powody, by pesymistyczne założenia dotyczące poprawności blokad NFS w tym czasie, i jest to rodzaj programu obronnego, którego nie znoszą przyszli dżokeje kodu, ponieważ tak trudno jest udowodnić brak usterki przez usuwając stary kod, który został ponownie wprowadzony do interoperacyjności ze starszym systemem, o którym nigdy nawet nie słyszałeś.

Od tego czasu NFS znacznie się poprawił, a lockd migrował z czasem do funkcji jądra Linux 2.6. W przypadku kolekcji systemów 2003+ prawdopodobnie można zaufać blokowaniu plików NFS, zwłaszcza jeśli zostanie dobrze przetestowane w aplikacji na wielu platformach, na których może ona działać.

Wszystkie powyższe zostały skopiowane z pamięci i prawdopodobnie mogłyby zostać potwierdzone przez badania (np. Http://nfs.sourceforge.net/ ), ale dowód - jak mówią - jest w blokadzie, a jeśli go nie przetestowałeś , zakłada się, że jest zepsuty.

msw
źródło
To świetna analiza. Do tej pory doszedłem do tego samego wniosku. Przeczytałem ponownie stronę nfs sourceforge po opublikowaniu tego linku i wreszcie znalazłem to, czego szukam! Oto szczegółowa analiza bezpośrednio z pyska konia!
Jmoney38
2
Ups, nacisnąłem Enter ... przejdź do nfs.sourceforge.net , sekcja D10 w dolnej części szczegółowo omawia ten problem.
Jmoney38
3

Kolejny, prosto z Linux-NFS FAQ: nfs.sf.net

Próbuję użyć blokad flock () / BSD, aby zablokować pliki używane na wielu klientach, ale pliki ulegają uszkodzeniu. Dlaczego? A. Blokady flock () / BSD działają tylko lokalnie na klientach Linux NFS przed wersją 2.6.12. Użyj blokad fcntl () / POSIX, aby upewnić się, że blokady plików są widoczne dla innych klientów.

Oto kilka sposobów serializacji dostępu do pliku NFS.

Użyj interfejsu API blokującego fcntl () / POSIX. Ten rodzaj blokowania zapewnia blokowanie zakresu bajtów na wielu klientach za pośrednictwem protokołu NLM lub NFSv4. Użyj osobnego pliku blokady i utwórz do niego twarde linki. Zobacz opis w sekcji O_EXCL strony podręcznika kreacji (2). Warto zauważyć, że do wczesnych jąder 2.6 tworzenie O_EXCL nie było atomowe na klientach Linux NFS. Nie używaj O_EXCL tworzy i oczekuje zachowania atomowego wśród wielu klientów NFS, chyba że używasz jądra nowszego niż 2.6.5.

Jest to znany problem polegający na tym, że Perl domyślnie używa blokowania flock () / BSD. Może to uszkodzić programy przeniesione z innych systemów operacyjnych, takich jak Solaris, które oczekują, że blokady flock / BSD będą działać jak blokady POSIX.

W systemie Linux stosowanie blokowania plików zamiast twardego łącza ma dodatkową zaletę polegającą na sprawdzaniu pamięci podręcznej klienta na serwerze. Po uzyskaniu blokady pliku klient opróżni pamięć podręczną strony dla tego pliku, aby wszelkie kolejne odczyty otrzymywały nowe dane z serwera. Po zwolnieniu blokady pliku wszelkie zmiany pliku na tym kliencie są usuwane z powrotem na serwer przed zwolnieniem blokady, aby inni klienci oczekujący na zablokowanie tego pliku mogli zobaczyć zmiany.

Klient NFS w wersji 2.6.12 zapewnia obsługę blokad flock () / BSD w plikach NFS poprzez emulowanie blokad typu BSD pod względem blokowania zakresu bajtów POSIX. Inni klienci NFS, którzy używają tego samego mechanizmu emulacji lub używają blokad fcntl () / POSIX, zobaczą te same blokady, które widzi klient NFS w systemie Linux.

W lokalnych systemach plików Linux blokady POSIX i BSD są niewidoczne dla siebie. Zatem dzięki tej emulacji aplikacje działające na serwerze NFS z systemem Linux nadal będą widzieć pliki zablokowane przez klientów NFS jako zablokowane za pomocą blokady fcntl () / POSIX, niezależnie od tego, czy aplikacja na kliencie używa stylu BSD, czy POSIX blokada stylu. Jeśli aplikacja serwera używa blokad BSD flock (), nie zobaczy blokad używanych przez klientów NFS.

Nikhil Mulley
źródło
Czy więc dwaj klienci NFS z jądrem 3.13. * Widzą nawzajem flock ()?
reinierpost
Jeśli dobrze rozumiem, odpowiedź brzmi „nie”. Chyba że coś mi umknęło, flocknie ma, nie ma i nie zablokuje się na wierzchowcach nfs.
Daniel Farrell,
Tak jest, przynajmniej na NFS4.
rjh
3

To jest już nieaktualne. NFS4 obsługuje blokowanie w protokole (nie jest wymagany blokowany demon ani mechanizm wywołania zwrotnego RPC), a flock()metoda Perla działa dobrze - używamy go w produkcji.

Bardzo stare wersje jądra zaimplementowane flock(syscall) jako brak operacji w NFS, a inne rzeczy, takie jak blokowanie zakresu bajtów, nie były poprawnie obsługiwane. Stąd pochodzi histeria.

rjh
źródło
Wielkie dzięki za podpowiedź. Montowanie za pomocą NFS4 rozwiązało mój problem. Obserwowani access.redhat.com/documentation/en-us/red_hat_enterprise_linux/... dostać fstab prawo konfiguracji.
maraspin