Я использую PHP flock () (который использует системный flock) в системах с общей файловой системой через NFS.
Flock () не работает, когда я использую ИСКЛЮЧИТЕЛЬНУЮ блокировку БЛОКИРОВКИ для доступа к одному и тому же (общему) файлу на 2 серверах. Конечно, только один процесс должен иметь возможность получить (исключительную) блокировку, но в этом случае другой должен блокироваться. Но я вижу, что вызов flock () немедленно возвращается с ошибкой.
Если я сделаю то же самое (запустил 2 программы для получения ИСКЛЮЧИТЕЛЬНОЙ, БЛОКИРУЮЩЕЙ блокировки) на 1 сервере, это сработает.
Вопрос в том, должно ли это работать? Не рекомендуется ли вообще использовать блокировку файлов через NFS? (Информация о том, что она вообще не работает, часто относилась к устаревшей информации). Если это должно сработать, что я могу сделать, чтобы отладить или решить эту проблему?
(Я использовал Скрипт PHP, но более простую настройку теста можно выполнить с помощью команды командной строки):
Система 1:
flock -x lock.txt sleep 10
Результат: блокировка получена
Система 2 (в то время как Система 1 получила блокировку):
flock -x lock.txt sleep 10
Это немедленно возвращается с
flock: lock.txt: Нет доступных блокировок
strace flock -x lock.txt sleep 10
flock(3, LOCK_EX) = -1 ENOLCK (No locks available)
Добавьте отладочную информацию с помощью rpcdebug -m nfs all
(на клиенте)
Это журнал неудачной попытки стада.
/ var / log / сообщения
Feb 4 10:24:51 myclient kernel: NFS: initiated commit call
Feb 4 10:24:51 myclient kernel: NFS: 6791 nfs_commit_done (status 0)
Feb 4 10:24:51 myclient kernel: NFS: nfs_update_inode(0:40/916722366 fh_crc=0xa8927c2a ct=1 info=0x27e7f)
Feb 4 10:24:51 myclient kernel: NFS: commit (0:40/916722366 1358@4096) OK
Feb 4 10:24:59 myclient kernel: NFS: permission(0:41/872433655), mask=0x81, res=-10
Feb 4 10:24:59 myclient kernel: NFS call access
Feb 4 10:24:59 myclient kernel: NFS: nfs_update_inode(0:41/872433655 fh_crc=0x9e46fe1a ct=2 info=0x27e7f)
Feb 4 10:24:59 myclient kernel: NFS reply access: 0
Feb 4 10:24:59 myclient kernel: NFS: permission(0:41/872433655), mask=0x1, res=0
Feb 4 10:24:59 myclient kernel: NFS: nfs_lookup_revalidate(/lock.txt) is valid
Feb 4 10:24:59 myclient kernel: NFS: permission(0:41/915542237), mask=0x10, res=0
Feb 4 10:24:59 myclient kernel: NFS: dentry_delete(/lock.txt, 40808cc)
Feb 4 10:24:59 myclient kernel: NFS: permission(0:41/872433655), mask=0x81, res=0
Feb 4 10:24:59 myclient kernel: NFS: nfs_lookup_revalidate(/lock.txt) is valid
Feb 4 10:24:59 myclient kernel: NFS: revalidating (0:41/915542237)
Feb 4 10:24:59 myclient kernel: NFS call getattr
Feb 4 10:24:59 myclient kernel: NFS reply getattr: 0
Feb 4 10:24:59 myclient kernel: NFS: nfs_update_inode(0:41/915542237 fh_crc=0x35293470 ct=1 info=0x27e7f)
Feb 4 10:24:59 myclient kernel: NFS: nfs3_forget_cached_acls(0:41/915542237)
Feb 4 10:24:59 myclient kernel: NFS: (0:41/915542237) revalidation complete
Feb 4 10:24:59 myclient kernel: NFS: dentry_delete(/lock.txt, 40808cc)
Feb 4 10:24:59 myclient kernel: NFS: nfs_weak_revalidate: inode 872433655 is valid
Feb 4 10:24:59 myclient kernel: NFS: permission(0:41/872433655), mask=0x81, res=0
Feb 4 10:24:59 myclient kernel: NFS: revalidating (0:41/915542237)
Feb 4 10:24:59 myclient kernel: NFS call getattr
Feb 4 10:24:59 myclient kernel: NFS reply getattr: 0
Feb 4 10:24:59 myclient kernel: NFS: nfs_update_inode(0:41/915542237 fh_crc=0x35293470 ct=1 info=0x27e7f)
Feb 4 10:24:59 myclient kernel: NFS: (0:41/915542237) revalidation complete
Feb 4 10:24:59 myclient kernel: NFS: nfs_lookup_revalidate(/lock.txt) is valid
Feb 4 10:24:59 myclient kernel: NFS call access
Feb 4 10:24:59 myclient kernel: NFS: nfs_update_inode(0:41/915542237 fh_crc=0x35293470 ct=1 info=0x27e7f)
Feb 4 10:24:59 myclient kernel: NFS reply access: 0
Feb 4 10:24:59 myclient kernel: NFS: permission(0:41/915542237), mask=0x24, res=0
Feb 4 10:24:59 myclient kernel: NFS: open file(/lock.txt)
Feb 4 10:24:59 myclient kernel: NFS: llseek file(/lock.txt, 0, 1)
Feb 4 10:24:59 myclient kernel: NFS: flock(/lock.txt, t=1, fl=82)
Feb 4 10:24:59 myclient kernel: NFS: flush(/lock.txt)
Feb 4 10:24:59 myclient kernel: NFS: release(/lock.txt)
Feb 4 10:24:59 myclient kernel: NFS: dentry_delete(/lock.txt, 40808cc)
RHEL
uname -r
3.10.0-1062.9.1.el7.x86_64
nfsstat –s
Server rpc stats:
calls badcalls badclnt badauth xdrcall
0 0 0 0 0
Client rpc stats:
calls retrans authrefrsh
588092 0 588092
Client nfs v3:
null getattr setattr lookup access readlink
0 0% 350667 59% 0 0% 1714 0% 231693 39% 5 0%
read write create mkdir symlink mknod
748 0% 2243 0% 0 0% 3 0% 0 0% 0 0%
remove rmdir rename link readdir readdirplus
0 0% 0 0% 0 0% 0 0% 0 0% 110 0%
fsstat fsinfo pathconf commit
0 0% 10 0% 5 0% 889 0%
варианты крепления:
rw, nosuid, noexec, noatime, nodiratime, context = system_u: object_r: httpd_sys_rw_content_t: s0, vers = 3, rsize = 131072, wsize = 131072, namlen = 255, hard, proto = tcp, timeo = 600, retrans = 2, sec = sys, mountaddr = someip, mountvers = 3, mountport = 300, mountproto = udp, local_lock = none, addr = someip
Я искал по этой теме. Некоторые хиты очень старый, не получил ответа или обратитесь к более старым версиям flock на Linux, которые еще не поддерживали разделяемую блокировку.
Например, в моей системе man 2 flock предоставляет следующую информацию:
В ядрах Linux до 2.6.11 flock () не блокирует файлы через NFS (т.е. объем блокировок был ограничен локальной системой). Вместо этого можно использовать блокировку байтового диапазона fcntl (2), которая работает через NFS, учитывая достаточно последнюю версию Linux и сервер, поддерживающий блокировку. Начиная с Linux 2.6.12, клиенты NFS поддерживают блокировки flock (), эмулируя их как блокировки диапазона байтов для всего файла. Это означает, что блокировки fcntl (2) и flock () действительно взаимодействуют друг с другом через NFS. Начиная с Linux 2.6.37, ядро поддерживает режим совместимости, который позволяет обрабатывать блокировки flock () (а также блокировки байтовых областей fcntl (2)) как локальные; см. обсуждение опции local_lock в nfs (5).
Уже существует множество ресурсов, посвященных этой проблеме. Таким образом, вы не можете использовать flock
непосредственно на NFS по причинам, указанным на странице руководства.
См. Эти ссылки: