flock (2) против fcntl (2) по NFS

19

В документации Perl 5.x говорится, что при реализации flock (..) будет использоваться один из следующих собственных вызовов, начиная с 1 и работая до 3, если он недоступен:

  1. стадо (2)
  2. Fcntl (2)
  3. lockf (3)

Все в порядке. Тем не менее, вы, возможно, заметили их заявление об отказе от использования flock (2) поверх NFS. В документе предлагается использовать флаг -Ud_flock, чтобы Perl использовал flock (2). Страница руководства flock (2) (на Redhat) содержит аналогичный отказ от проблем с NFS.

У меня вопрос, почему!?!? Кажется, я не могу найти подробную статью или объяснение, почему flock (2) небезопасен по сравнению с NFS.

Я написал несколько тестовых скриптов на C и Perl, как на Redhat (где используется flock (2)), так и на Solaris (где используется fcntl (2)). Я запустил strace / truss, чтобы убедиться, что Perl действительно использует flock (2) и fcntl (2) соответственно. Я не мог воспроизвести любые проблемы, когда блокировка не была выполнена! Что дает??

Jmoney38
источник

Ответы:

3

Леннарт Поэттеринг недавно немного покопался в поведении блокировки файловой системы linux, которая не рисует особенно радужную картину для блокировки через NFS (особенно в отношении продолжения, на которое он ссылается в нижней части поста).

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

Ivatar
источник
1
Это именно тот тип информации, который я искал. Спасибо! После нескольких недель расследования, это очень похожее решение, к которому я пришел, но здорово прочитать статью, которая подтверждает мои подозрения (и предлагает другие). Ссылка из комментариев на этой странице была также хорошей ссылкой и хорошей статьей о POSIX и его истории): samba.org/samba/news/articles/low_point/tale_two_stds_os2.html
Jmoney38
15

Я почти уверен, что вы смотрите на проблемы прошлого. Напомним, что руководство по Perl5 было выпущено в 1994 году, и это было просто редактирование руководства по Perl4 с 1991 года. В те дни, вероятно, можно было сказать о часто называемой файловой системе Nightmare, что «не так хорошо, как медведь танцует, поражает, но то, что танцует вообще ".

NFS2 в эпоху 1991 года медленно выползал из Sun на другие платформы и был относительно сырым. Модель безопасности по существу не существовала (root на клиентском компьютере мог читать все содержимое монтирования NFS), и блокировка - через nfs.lockd - была этой стороной эксперимента. Было бы глупо ожидать, что семантика стада будет работать должным образом, если вообще существует между двумя различными, предположительно, совместимыми реализациями. Коаксиальный кабель был доминирующим PHY Ethernet в то время, когда многие пользователи сети никогда не испытывали недовольства по поводу использования (что вы имеете в виду, что забыли включить согласующий резистор 50𝛀?), Если это позволит вам лучше контролировать состояние интрасетей.

Ларри Уолл и его команда имели все основания делать пессимистичные предположения о правильности блокировок NFS в то время, и это своего рода защитное программирование, которое будущие сторонники кода не хотят удалять, поскольку доказать отсутствие дефекта так трудно удаление старого кода, который повторно вводится во взаимодействие с устаревшей системой, о которой вы даже не слышали.

С тех пор NFS значительно улучшилась, и lockd вовремя перешла на функцию ядра Linux 2.6. Для семейства систем 2003+ блокировке файлов NFS, вероятно, можно доверять, особенно если она хорошо протестирована в вашем приложении на многих платформах, на которых оно может работать.

Все вышеперечисленное было взято из памяти и, вероятно, может быть подтверждено исследованиями (например, http://nfs.sourceforge.net/ ), но доказательства, как они говорят, находятся в замке, и если вы его не проверяли Предполагается, что он сломан.

MSW
источник
Это отличный анализ. На самом деле, я пришел к тому же выводу до сих пор. После того, как вы опубликовали эту ссылку, я перечитал страницу исходного кода nfs, и наконец нашел то, что искал! Вот углубленный анализ прямо изо рта лошади!
Jmoney38
2
К сожалению, я нажимаю Enter ... перейти к nfs.sourceforge.net , раздел D10 в нижней части обсуждает эту проблему подробно.
Jmoney38
3

Еще один, прямо из FAQ по Linux-NFS: nfs.sf.net

Я пытаюсь использовать блокировки flock () / BSD для блокировки файлов, используемых на нескольких клиентах, но файлы становятся поврежденными. Как придешь? A. flock () / BSD блокировки действуют только локально на клиентах Linux NFS до 2.6.12. Используйте блокировки fcntl () / POSIX, чтобы гарантировать, что блокировки файлов видны другим клиентам.

Вот несколько способов сериализации доступа к файлу NFS.

Используйте API блокировки fcntl () / POSIX. Этот тип блокировки обеспечивает блокировку диапазона байтов для нескольких клиентов по протоколу NLM или через NFSv4. Используйте отдельный файл блокировки и создайте жесткие ссылки на него. См. Описание в разделе O_EXCL справочной страницы creat (2). Стоит отметить, что до ранних версий 2.6 ядра, создаваемые O_EXCL, не были атомарными на клиентах Linux NFS. Не используйте O_EXCL создает и ожидает атомарного поведения среди нескольких клиентов NFS, если вы не используете ядро ​​новее, чем 2.6.5.

Известно, что Perl по умолчанию использует блокировку flock () / BSD. Это может сломать программы, перенесенные из других операционных систем, таких как Solaris, которые ожидают, что блокировки flock / BSD будут работать как блокировки POSIX.

В Linux использование блокировки файлов вместо жесткой ссылки дает дополнительное преимущество, заключающееся в наведении контрольной точки клиентского кэша на сервер. Когда блокировка файла получена, клиент очистит кэш страницы для этого файла, чтобы при любых последующих чтениях были получены новые данные с сервера. Когда блокировка файла снята, любые изменения в файле на этом клиенте передаются обратно на сервер до снятия блокировки, чтобы другие клиенты, ожидающие блокировки этого файла, могли видеть изменения.

Клиент NFS в 2.6.12 обеспечивает поддержку блокировок flock () / BSD для файлов NFS, эмулируя блокировки в стиле BSD в терминах блокировок диапазона байтов POSIX. Другие клиенты NFS, использующие тот же механизм эмуляции или использующие блокировки fcntl () / POSIX, увидят те же блокировки, что и клиент Linux NFS.

В локальных файловых системах Linux блокировки POSIX и BSD невидимы друг для друга. Таким образом, из-за этой эмуляции приложения, работающие на NFS-сервере Linux, по-прежнему будут видеть файлы, заблокированные клиентами NFS, заблокированными с помощью блокировки fcntl () / POSIX, независимо от того, использует ли приложение на клиенте BSD-стиль или POSIX- замок стиля. Если серверное приложение использует блокировки flock () BSD, оно не увидит блокировки, используемые клиентами NFS.

Никхил Мулли
источник
Так два ли клиента NFS с ядром 3.13. * Видят flock () друг друга?
reinierpost
Если я правильно понимаю, ответ - нет. Если я что-то пропустил, flockне имеет, не делает и не будет блокировать через nfs монтирует.
Даниэль Фаррелл
Это делает, по крайней мере, на NFS4.
RJH
3

Это устарело сейчас. NFS4 поддерживает блокировку внутри протокола (не требуется демон lockd или механизм обратного вызова RPC), а flock()метод Perl работает нормально - мы используем его в работе.

Очень старые версии ядра реализованы flock(системный вызов) как запрет на NFS, и другие вещи, такие как блокировка диапазона байтов, не поддерживаются должным образом. Вот откуда истерия.

rjh
источник
Большое спасибо за подсказку. Монтаж с NFS4 решил мою проблему. Вслед access.redhat.com/documentation/en-us/red_hat_enterprise_linux/... получить FSTAB конфигурации право.
maraspin