Назад | Перейти на главную страницу

сбой flock на общем NFS для монопольных блокирующих блокировок с 2 разных машин

Я использую 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 по причинам, указанным на странице руководства.

См. Эти ссылки: