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 есть причина для получения "отказано в разрешении "вместо" операция не разрешена", однако некоторые уточнения относительно этого район был бы великолепен.
1 ответ:
Чтобы ответить на ваш вопрос, по порядку:
Вы правы, что gfortran попытается открыть файл в режиме только для чтения, когда EACCES (или EROFS) встречается.
Вы также правы, что EPERM не обрабатывается таким образом, он вообще не упоминается в дереве исходных текстов libgfortran.
Как вы сказали, это вопрос мнения. Gfortran принял решение сделать это уже давно, и, похоже, это вполне устраивает пользователей.
Я так и делаю не понимаю, почему NFS v4 возвращает EPERM в таком случае. Это кажется противоречащим, по крайней мере, документации в Open(2) Linux manpage, к которой у меня есть доступ, где она упоминается только тогда, когда O_NOATIME был указан (что libgfortran не делает). По крайней мере, такое поведение не кажется переносимым.