Summary: | Не работают блокировки в режиме forcemand | ||
---|---|---|---|
Product: | CIFS@Etersoft | Reporter: | Евгений Синельников <sin> |
Component: | блокировки файлов и доступ | Assignee: | Pavel Shilovsky <piastry> |
Status: | CLOSED FIXED | QA Contact: | Денис Баранов <baraka> |
Severity: | major | ||
Priority: | P2 | CC: | alter, amorozov, baraka, lav, lbeasty, piastry, sonner |
Version: | не указана | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | All | ||
Whiteboard: | |||
Заявки RT: | Связано с: | 4370 | |
Дата напоминания: | 2009-12-19 | ||
Bug Depends on: | 4536 | ||
Bug Blocks: | 3043, 4284 | ||
Deadline: | 2009-12-21 | ||
Attachments: |
Тест выявляющий проблемы на блокировках forcemand
Исправленный тест |
Выяснил порядок изменения поведения теста. 1. Монтируем 2. Запускаем тест - падает на чтении 3. Пробуем файл PDOXUSRS.NET с помощью Vim: первый раз не получается - "ошибка при чтении" второй раз всё хорошо открывается 4. Запускаем тест - всё читается хорошо Так же хочу заметить, что последнее чтение с 10 до 12 менялось на с 14 до 16 и поведение было абсолютно такое же! Так же запостил багу на bugzilla.samba.org: https://bugzilla.samba.org/show_bug.cgi?id=6823 Выяснилось ещё кое-что: Тест меняет своё поведение именно после чтения из файла ( при записи - нет ). То бишь описанное в предыдущем посте открытие с помощью Vim можно заменить на след порядок действий: отрытие, чтение, закрытие. Так же выяснилось что процесс видит блокировки там, где они есть и не видит, там где нет ( использовалис GET_LK запросы )! Проблема в том, что на поведение функции read() это не влияет. Буду продолжать разбираться. Кое-что выяснилось: драйвер, когда поступает запрос на чтение, начинает читать с сервера страницами. Если мы пытаемся прочесть незаблокированную часть часть файла, которая входят в страницу, в какой-то части которой есть блокировка, то чтение не проходит. Это в случае, когда у нас неактуальный кеш, то есть мы лезем за страницей на сервер. В случае же когда у нас кеш актуальный, то мы просто читаем из него локально, при этом не опрашивая сервер на возможные блокировки в этой области. Предлагаю тестовую ветку драйвера: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=shortlog;h=refs/heads/dev И первый патч: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=92d0d49b584a0aace55abc169abe437c867fa89d;hp=302ab600b70cd26301791a994ddfe173b0e8a488 Тест из описания баги проходит успешно! Я сделал две тестовых сборки: 4.4.0 и 4.4.1. Описание доступно здесь: http://wiki.etersoft.ru/Etercifs/Changelog Просьба проверить. Рабочие условия для проверки: forcemand,noperm (без direct) Пакеты собраны для тестовых платформ, просьба проверить. (In reply to comment #4) > Я сделал две тестовых сборки: 4.4.0 и 4.4.1. Поставил попробовал сделать build, обе прерываются на /tmp/Etercifs.I7DYRmvu/kernel-source-etercifs-2.6.31-1.60/file.c: In function ‘cifs_lock’: /tmp/Etercifs.I7DYRmvu/kernel-source-etercifs-2.6.31-1.60/file.c:913: error: too few arguments to function ‘CIFSSMBLock’ /tmp/Etercifs.I7DYRmvu/kernel-source-etercifs-2.6.31-1.60/file.c:919: error: too few arguments to function ‘CIFSSMBLock’ make[1]: *** [/tmp/Etercifs.I7DYRmvu/kernel-source-etercifs-2.6.31-1.60/file.o] Ошибка 1 make[1]: *** Ожидание завершения заданий... make: *** [_module_/tmp/Etercifs.I7DYRmvu/kernel-source-etercifs-2.6.31-1.60] Ошибка 2 Ubuntu x64 Linux lin-test 2.6.31-15-generic Проверил на сборке 4.4.0 монтировал с параметрами MOUNT_OPTIONS=user=guest,pass=,rw,iocharset=utf8,noperm,forcemand Результаты запуска теста: ./a.out start 6733 server start 6734 second server start 6735 server open for -1 server second open for -1 fcntl set lock on -1 failed (Bad file descriptor) fcntl set lock on -1 failed (Bad file descriptor) close failed -1 (Bad file descriptor) sendmsg failed server send -1 server file not locked second open failed server end Создаётся впечатление, что в каталоге запуска отсутствует файл "PDOXUSRS.NET", а тест использует его. Причём он должен содержат произвольную текстовую информацию длиной более 16 байт! Created attachment 1444 [details]
Исправленный тест
Исправил тест, теперь файл создаётся автоматически. Можно тестировать!
Проверил исправленный тест на сборке 4.4.0 монтировал с параметрами MOUNT_OPTIONS=user=guest,pass=,rw,iocharset=utf8,noperm,forcemand Результаты запуска теста: ./a.out start 19658 second server start 19660 server start 19659 server open for 5 server second open for 6 server close 6 server send 5 fd received=5 (len=1) server file not locked second server open for 5 second server lock for 5 second server lseek done on 5 with 10 second server read done on 5 with 2 wait second server for end file 5 not locked first read done on 5 with 1 second lseek done on 5 with 1 second read done on 5 with 2 third lseek done on 5 with 10 third read failed on 5 (Permission denied) done Fixed. Проверил на но новом etercifs: etercifs-4.4.2-alt1 Параметры монтирования: MOUNT_OPTIONS=user=guest,pass=,rw,iocharset=utf8,noperm,forcemand При запуске, выдается след: $ ./a.out start 9915 server start 9916 second server start 9917 server open for 5 server second open for 6 server close 6 server send 5 fd received=5 (len=1) server file not locked second server open for 5 second server lock for 5 second server lseek done on 5 with 10 second server read done on 5 with 2 wait second server for end file 5 not locked first read done on 5 with 1 second lseek done on 5 with 1 second read done on 5 with 2 third lseek done on 5 with 10 third read failed on 5 (Permission denied) done |
Created attachment 1344 [details] Тест выявляющий проблемы на блокировках forcemand Найден пример однозначно показывающий проблему блокировок. Стоит отметить, что он фиксирует ещё и проблему принадлежности блокировки wine server'ру и дальнейшей самоблокировки, если она проявится. На вид же блокируется вообще весь файл. Тест не учитывает shared-флаги - с ними, наверное, всё ещё интереснее... | Стартуем первый основной процесс. | Создаём unix-сокет для обмена с | макетным wine-сервером. |\ | \ | | Стартуем макетный вариант | | wine-сервера. | | Открываем файл. | | Ставим на него блокировку | | от 0 до 1. | | Открываем файл ещё раз. | | Ставим на него блокировку | | от 1 до 3. | | Закрываем второй раз открытый | | файл. | | Передаём первый открытый | | файловый дескриптор основному | | процессу. | | Проверяем заблокированную область | | (от 0 до 1) - не должны видеть | | блокировки, ибо сами установили. | | Пробуем прочесть заблокированную | | область. | | Засыпаем фиксирую блокировку, | | которая после закрытия второго | | файлового дескриптора, должна | | остаться. | ... |\ | \ | | Стартуем конкурирующий процесс | | Открываем файл. | | Ставим на него блокировку | | от 10 до 12. | | Пробуем прочесть заблокированную | | область. | | Засыпаем фиксирую блокировку, | | которая после закрытия второго | | файлового дескриптора, должна | | остаться. | ... | | Принимаем от макетного wine-сервера | файловый дескриптор | Проверяем заблокированную область | (видим, но pid, указан основного | процесса, ибо не передаётся на | сервер в режиме forcemand) | Пробуем прочесть заблокированную | область от 0 до 1. | Пробуем прочесть заблокированную | область от 1 до 3. | Пробуем прочесть удерживаемую | конкурентом заблокированную | область от 10 до 12. .... Это пример не работает - блокируется весь файл, и считать нельзя не из какой области никакому процессу. $ ./raw7 start 26977 server start 26978 server open for 5 server second open for 6 second server start 26979 server close 6 server send 5 server file not locked fd received=5 (len=1) second server open for 5 second server lock for 5 second server lseek done on 5 with 10 file 5 not locked second server read failed on 5 (Permission denied) first read failed on 5 (Permission denied) second lseek done on 5 with 1 second read failed on 5 (Permission denied) third lseek done on 5 with 10 third read failed on 5 (Permission denied) done Иногда, этот пример, ведёт себя также, как на локальной файловой системе. $ /tmp/raw7 start 26842 server start 26843 second server start 26844 server open for 5 server second open for 6 server close 6 server send 5 server file not locked fd received=5 (len=1) second server open for 5 second server lock for 5 second server lseek done on 5 with 10 second server read done on 5 with 2 wait second server for end file 5 not locked first read done on 5 with 1 second lseek done on 5 with 1 second read done on 5 with 2 third lseek done on 5 with 10 third read done on 5 with 2 data:ab done Во втором случае блокировка не срабатывает...