Fortran OPEN-call отличается на NFSv3 и NFSv4


Я пытаюсь понять разницу между тем, почему вы можете сделать открытый вызов в fortran на NFSv3 в режиме чтения-записи для файла, на который у вас есть только права на чтение, в то время как если вы сделаете то же самое на NFSv4, открытый вызов завершится неудачей.

Поясню, ниже приведена простая fortran-программа, открывающая данный файл (аргумент к программе) в режиме чтения-записи,

PROGRAM test_open

 IMPLICIT NONE

 ! Parameters

 INTEGER,            PARAMETER :: lunin = 10
 CHARACTER(LEN=100) :: fname

 ! Local

 INTEGER :: i,ierr,siteid,nstation
 REAL :: lat, lon, asl
 CHARACTER(len=15) :: name

 !----------------------------------------------------------------
 !
 ! Open input file
 !

 CALL getarg(1,fname)

 OPEN(lunin,file=fname,STATUS='OLD',IOSTAT=ierr)

 IF ( ierr /= 0 ) THEN
    WRITE(6,*)'Could not open ',TRIM(fname),ierr
    STOP
 ENDIF

 WRITE(6,*)'Opened OK'

 CLOSE(lunin)


END PROGRAM test_open

Сохраните все вышесказанное в test_open.f90 и компилировать с помощью,

gfortran -o fortran test_open.f90 

, выполните следующие точка монтирования с NFSv3,

strace -eopen ./fortran file-with-only-read-permissions 

И вы должны увидеть следующие строки (наряду с большим количеством других выходных данных),

> open("file-with-only-read-permissions", O_RDWR)  = -1 EACCES (Permission denied)
> open("file-with-only-read-permissions", O_RDONLY) = 3
Таким образом, мы можем ясно видеть, что получаем "EACCES (разрешение отклонено)" при попытке открыть в 'O_RDWR' (open read-write), но сразу после того, как мы видим другой открытый O_RDONLY (open read-only), и это успешно.

Запустите ту же программу на файле на общей папке NFSv4, и мы получим следующее,

strace -eopen ./fortran file-with-only-read-permissions-on-nfsv4-share 
> open("file-with-only-read-permissions-on-nfsv4-share", O_RDWR)  = -1 EPERM (Operation not permitted) 

Итак, здесь мы получаем "EPERM (операция не разрешено) "при попытке открыть файл в 'O_RDWR' (открыть read-write) и ничего больше (т. е. приложение не работает).

Выполняя одни и те же тесты на языке Си с помощью небольшой тестовой программы, он не сможет открыть файл в обоих сценариях (то есть он не будет пытаться открыть файл в "режиме только для чтения" после получения "EACCES" на NFSv3).

Итак, к вопросам,

  • Я предполагаю, что вышеописанное поведение связано с реализацией OPEN-call в fortran, и что если fortran получает "EACCES (разрешение отказано)" при попытке открыть файл, он автоматически попытается открыть файл в режиме только для чтения (O_RDONLY). Верно ли это предположение ?

  • Я также предполагаю, что fortran не имеет этого " резервного метода "при получении" EPERM (операция не разрешена) " при попытке открыть файл. Верно ли это предположение, или я что-то упускаю ?

  • C, похоже, не реализует "запасной метод" ни в "EACCES", ни в "EPERM". Это кажется правильно для меня, так как это не оставляет места для путаницы. Если вы попытаетесь открыть файл способом, на который у вас нет прав, программа должна потерпеть неудачу - мое мнение.

  • Я осознаю, что существует явная разница между "отказано в разрешении" и "операция не разрешена". И я предполагаю, что при монтировании NFSv4 через kerberos есть причина для получения "отказано в разрешении "вместо" операция не разрешена", однако некоторые уточнения относительно этого район был бы великолепен.

Конечно, добавление соответствующих флагов к open-call (ACTION=READ) решает проблему. Я просто любопытствую о своих предположениях и о том, верны ли они.
1 3

1 ответ:

Чтобы ответить на ваш вопрос, по порядку:

  • Вы правы, что gfortran попытается открыть файл в режиме только для чтения, когда EACCES (или EROFS) встречается.

  • Вы также правы, что EPERM не обрабатывается таким образом, он вообще не упоминается в дереве исходных текстов libgfortran.

  • Как вы сказали, это вопрос мнения. Gfortran принял решение сделать это уже давно, и, похоже, это вполне устраивает пользователей.

  • Я так и делаю не понимаю, почему NFS v4 возвращает EPERM в таком случае. Это кажется противоречащим, по крайней мере, документации в Open(2) Linux manpage, к которой у меня есть доступ, где она упоминается только тогда, когда O_NOATIME был указан (что libgfortran не делает). По крайней мере, такое поведение не кажется переносимым.