Этот вопрос ранее обсуждался в контексте вставки костылей в CIFS. Проблема возникает из-за того, что сетевая ФС удалённо снимает при закрытии файлов блокировки согласно POSIX. В связи с этим WINE по-разному себя ведёт на разных ФС: """ Локально и на NFS. 1. Win-программа открывает файл xxx -> wineserver открывает файл xxx и получает дескриптор 1, устанавливает специальные блокировки, обозначающие SHARE-флаги 2. Win-программа открывает файл xxx второй раз -> wineserver открывает файл xxx и получает дескриптор 2. Проверяется, что мы не нарушим sharing, если откроем файл, устанавливаются блокировки, обозначающие SHARE-флаги 3. Win-программа закрывает файл xxx -> wineserver помечает соответствующий дескриптор как закрытый. Если мы закроем дескриптор тут, то мы сбросим блокировки и потеряем информацию о SHARE-флагах 4. Win-программа закрывает файл xxx -> wineserver закрывает дескрипторы 1 и 2 CIFS 1. Win-программа открывает файл xxx -> wineserver открывает файл xxx с параметрами, описывающими SHARE-флаги, и получает дескриптор 1 2. Win-программа открывает файл xxx второй раз -> wineserver открывает файл xxx с параметрами, описывающими SHARE-флаги, и получает дескриптор 2. Если SHARE-флаги не совместимы с предыдущими, то файл открыть не удастся. 3. Win-программа закрывает файл xxx -> wineserver закрывает дескриптор 2 4. Win-программа закрывает файл xxx -> wineserver закрывает дескриптор 1 Почему мы не можем действовать в случае CIFS так же, как в локальном случае. Допустим, мы открываем файл с GENERIC_WRITE и FILE_SHARE_READ|FILE_SHARE_WRITE, получаем дескриптор 1. Затем открываем его с GENERIC_READ и FILE_SHARE_WRITE, получаем дескриптро 2, закрываем дескриптор 2. Теперь мы не сможем открыть его с GENERIC_READ ещё раз. """ Хотелось бы уточнить проводил ли кто-нибудь тесты на поведение CIFS в описанном случае повторного открытия файла? Далее я приведу свои...
Created attachment 1332 [details] Пример теста на снятие блокировок после закрытия файла Прилагаю простой тест на повторное открытие, соответствующее снятие блокировок и последующее чтение из первого ФС. Вот как это работает эталонно на локальной ФС: $ ./raw6 start 32166 server start 32167 server open for 5 server second open for 6 server close 6 server send 5 server file not locked fd received=5 (len=1) file 5 not locked done Аналогично всё ведёт себя и при обычном монтировании в CIFS (-oguest,noperm) $ ./raw6 start 32451 server start 32452 server open for 5 server second open for 6 server close 6 server send 5 server file not locked fd received=5 (len=1) file 5 not locked done А вот при использовании forcemand и nounix начинаются чудеса: $ ./raw6 start 32601 server start 32602 server open for 5 server second open for 6 server close 6 server send 5 server file not locked fd received=5 (len=1) file 5 not locked read failed on 5 (Permission denied) done Причём на это влияет установка блокировки в первом файле и последующее открытие второго...
Очевидно, что проблема в связке Samba->CIFS->(Использование) Вопрос в том, как должен работать WINE... Мы его подстраиваем под особенности Samba+CIFS или нет? Вообще проблема есть в самой Samba, которая довольно странно отрабатывает на разных запросах. Можно пытаться перебрать все варианты... Но мне бы хотелось уточнить сценарии использования Samba+CIFS в WINE, иначе сложно добиться его нормальной работы... На примере теста на снятие блокировок после закрытия файла показано, что в Samba+CIFS есть странности. Эти странности входят в набор сценариев работы для WINE?
Ещё более интересный эффект наблюдается, если фиксировать не вторую блокировку, а первую: $ diff -u raw6.old raw6.c --- raw6.old 2009-10-05 23:58:22 +0400 +++ raw6.c 2009-10-05 23:56:25 +0400 @@ -165,8 +165,8 @@ flk.l_type = F_WRLCK; flk.l_whence = SEEK_SET; - flk.l_start = 1; - flk.l_len = 2; + flk.l_start = 0; + flk.l_len = 1; if (fcntl(fd, F_GETLK, &flk) < 0) fprintf(stderr, "fcntl get lock on %d failed (%s)\n", fd, strerror(errno)); Для обычного монтирования всё нормально: $ ./raw6 start 374 server start 375 server open for 5 server second open for 6 server close 6 fd received=5 (len=1) file 5 not locked done server send 5 server file not locked А для forcemand наблюдаем отсутствие снятия блокировок после закрытия файлов - в общем то, что и хотелось бы вроде как: $ ./raw6 start 382 server start 383 server open for 5 server second open for 6 server close 6 server send 5 server file not locked fd received=5 (len=1) file 5 locked by 382 read failed on 5 (Permission denied) done Сие гадание и перебор параметров печальны... Слишком много исходов...
Резюмирую, forcemand (и mandatory нормально срабатывает и блокировки не снимаются) нас как бы всем устраивает, но непонятно почему Permission Denied на чтении - вероятно здесь придётся лезть в самбу....
О! Ну, надо же... Добавил свои костыли для пробрасывания Pid'а Проблема Permission Denied пропала... Но пропало снятие блокировок... Далее добавил два накопанных в исходниках самбы параметра (должно быть достаточно одного): posix locking = false blocking locks = false Всё получилось!!! Тесты прошли!!! Нужно проверить VVS... Сделаю новую сборку etercifs - расскажу как оно должно настраиваться... Но это уже завтра...