Проблема описана во второй части поста: http://bugs.etersoft.ru/show_bug.cgi?id=4398#c9 Надо проверить действительно ли она имеет место быть и какие версии Samba затрагивает.
Разобрался с проблемой. Проявляется если выставить опцию "kernel oplocks = no". Без этой опции или при значении "yes", бага не воспроизводится.
https://bugzilla.samba.org/show_bug.cgi?id=7928 Так же заметил, что проблема пропадает, если выставить для шары опцию strict locking = yes.
Данная проблема вызвала обсуждение в багзилла - и выяснилось, что на представленной капче, проявляется проблема http://bugs.etersoft.ru/show_bug.cgi?id=6823 для Samba-3.
*** Bug 6823 has been marked as a duplicate of this bug. ***
Воспроизвёл сразу две проблемы на Samba-3.6.0pre1 и Samba-3.5.4 (Ubuntu 10.10), отправил капчу, скрипт и лог самбы с описанием проблемы в https://bugzilla.samba.org/show_bug.cgi?id=7928.
Проблема с оплоками вызвала недоумение и непонимание со стороны разработчиков Samba. Провёл исследование на эту тему и нашёл материалы, доказывающие нашу точку зрения, что при наличии блокировок на файле клиентам не должны выдаваться оплоки второго уровня: http://msdn.microsoft.com/en-us/library/cc308443.aspx http://msdn.microsoft.com/en-us/library/ff549259(v=vs.85).aspx
Обсуждение в баге на samba.org затихло, потому написал в рассылку. Получил быстрый ответ. Есть идея воспроизвести проблему с помощью tortue.
Выяснил, что проблема с чтением из заблокированного участка проявляется опять же из-за того, что Samba неправильно выдаёт оплоки на чтение. В итоге получается следующее: 1) клиент с открытым файлов в оплок level2 читает из заблокированного участка. 2) Samba смотрит, что у клиента есть оплок и проводит оптимизацию (не проверяет участок на блокировки), что является корректным. 3) в итоге клиент получает информацию из учатка файла, которую получить не должен был. Всё это справедливо для опции Samba strict locking = auto (по умолчанию). При установке этой опции в 'yes' тест проходит (http://bugs.etersoft.ru/show_bug.cgi?id=6816#c2). Из всего этого можно сделать следующие выводы: 1) При работе с WINE по CIFS все текущие версии Samba нужно использовать только с опцией 'level2 oplocks = no' в smb.conf для шары с базой (или глобально, если нужно для всех шар). 2) Если нужны-таки оплоки на чтение, то надо использовать Windows сервера. Доведения до апстрима этих сведений будет продолжаться, но: 1) если там и поправят, то не скоро; 2) если изменения и появятся, то скорее всего коснутся только новых версий Samba.
Написал соответствующий пост в нашу рассылку.
Возникли вопросы. Ответил в рассылке.
Подытожил обсуждение в рассылке. level2 oplocks = no надо внести в нашу документацию.
Эксперементировал с Windows сервером. Если клиент удерживает блокировку через дескриптор1 и оплок на запись, то при ещё одном открытии файла оплок может сбросить до 2 уровня. При этом, как было замечено раньше, второму дескриптору не возвращается оплоков (что правильно, а отличие от поведения Samba). Данное замечание никак не влияет на работу нашего модуля.
Разобрался с smbtortue и написал тест, который воспроизводит проблему с оплоками на чтение в Samba. http://git.etersoft.ru/people/piastry/packages/?p=samba4.git;a=commitdiff;h=7b957a3639280e7881a3fae226780cc3da1012ad;hp=619e5cb646b465a4d6a031cbb462878e096498a6 Написал в samba-technical об этом.
Написал патч, который исправляет не позволяет Samba выдавать оплоки на чтение на заблокированные файлы.
Ссылка на патч: http://git.etersoft.ru/people/piastry/packages/?p=samba4.git;a=commitdiff;h=8acc20b87a6f14f79595c5eef0097cbf03c84542;hp=d5e4d87767cfc9e8f92fd99222c1e3af3de59d75
Нашёл ещё одну проблему Samba с оплоками на чтение: при записи или блокировке файла и наличие двух открытых файлов с оплоками на чтение, оплок сбрасывается только с одного.
Исправил вышеописанную проблему - использовался один и тот же указатель на разные открытые файлы при сбрасывании оплока. Теперь для каждого создаю новый. http://git.etersoft.ru/people/piastry/packages/?p=samba4.git;a=shortlog;h=refs/heads/v3-6-stable
Прокинул патчи в master ветку и написал в samba-technical. Так же, надо заметить, что последняя проблема не обнаружена в Samba-4.0.0alpha14, и замечена в 3.5.4 и 3.6.0pre1. Первая же присутствует в обоих ветках.
Получил фидбэк со стороны разработчиков - с первого взгляда патчи правильные, но требуют более глубокого изучения. Немного поправил код второго патча - переотправил в рассылку. http://git.etersoft.ru/people/piastry/packages/?p=samba4.git;a=commitdiff;h=569ee7e3553b4e2fb0b098cca9d1a32ddc7afee6
Создал патч для Samba-4.0.0-alpha14, исправляющий проблему выдачи оплоков на чтение при наличии блокировок на файле: http://git.etersoft.ru/people/piastry/packages/?p=samba4.git;a=commitdiff;h=f5e27f15c653071b257b22dc1dca9f46491cd6dd
Нашёл в коде Samba-3.6.0pre1 ещё одну ошибку при сбросе оплоков второго уровня: проверки, что текущий файловый дескриптор, операция на котором вызвала сброс оплоков, может быть только с оплоком второго уровня неверна. Создал патч, исправляющий эту проблему: http://git.etersoft.ru/people/piastry/packages/?p=samba4.git;a=commitdiff;h=d930638886dd4171139b4b35b87e98e9612f7588 Далее займусь оформлением этого и предыдущего патча для Samba-4.0.0-alpha14 для отправки в апстрим. По первому патчу получил ответ в рассылке - собираются принять в апстрим и бэкпортировать в stable веткe 3.5.*.
Исследовал код Samba на наличие рэйсов при выдачи оплоков. На данный момент ситуация следующая: при текущей реализации в Samba-3 быть не должно, в Samba-4 может быть рэйс, но поймать его не получилось. Два уже отправленных патча и tortue тест уже в апстрим: http://git.samba.org/?p=samba.git;a=commit;h=7690d9d70c2425f6357732c0901d9dd18483e097 http://git.samba.org/?p=samba.git;a=commit;h=f453235ce057339a69398f5c862fdd3e46bd31c4 http://git.samba.org/?p=samba.git;a=commit;h=6696fd1c1e94a6b830fe8d1191b85da97bfb10c1 Там уже подготовили патчи для портирования в ветку 3.5.*: https://bugzilla.samba.org/show_bug.cgi?id=7928#c19 https://bugzilla.samba.org/show_bug.cgi?id=7928#c20
Оформил патчи для Samba-3 и Samba-4.0.0-alpha14 и отправил - первый в рассылку, второй в соответствующую багу.
Поправил стиль патча для Samba-4 и переотправил.
По последнему патчу для Samba-3 возникли вопросы. Подробно расписал текущее поведение, почему оно неверно и как этот патч его исправляет.
Выяснилось, что следует поправить первый патч, так как Samba старается поддерживать только три состояния в дескрипторах одного файла: 1) exclusive or batch oplock - один дескриптор. 2) level2 or fake_level2_oplocks - несколько. 3) no oplocks - несколько. для ситуаций, когда есть один открытый файл в level2 oplock и другой в no oplock, для последнего выставляется fake_level2_oplock в списке дескрипторов, но клиенту возвращается no oplock. Буду править первый патч, согласно данному замечанию, так как исправления для Samba-3.6 нельзя просто наложить на Samba-3.5.y из-за изменений в коде обработки оплоков в первой.
Поправил первый патч, протестировал и отправил в рассылку.
Патч для Samba-4.0.0 принят в апстрим в ветку master: http://git.samba.org/?p=samba.git;a=commit;h=738b2abe784bc38bdaf1abc913a401e0e732e188
Сделал rebase веток, обновил репо на git.eter, написал в багу на samba.org об этом.
Откладываю пока не придёт ответ от разработчиков апстрим.
Ответа так и не последовало. Синхронизировался с апстрим и проверил наличие наших патчей. Сейчас они присутствуют в ветке v3-6-test и в master. Таким образом, как минимум, войдут в следующий релиз 3.6.0. По поводу ветки v3-5-test - отправил разработчику ещё одно письмо. Жду в течении недели и закрываю в случае отсутствия ответа.
Ответа не последовало. В любом случае войдёт в Samba-3.6.0.
Данное исправление не войдёт в Samba-3.5.*, поскольку для его корректной работы нужно переписывать код внитрисамбовых блокировок, иначе получается дедлок. Поэтому, исправление присутствует только в Samba-3.6.0pre2 и Samba-4.0.0alpha15 и позднее.