Linux NFSv3和NFSv4上的Fortran OPEN调用不同

Linux NFSv3和NFSv4上的Fortran OPEN调用不同,linux,fortran,system-calls,gfortran,nfs,Linux,Fortran,System Calls,Gfortran,Nfs,我试图理解为什么可以在NFSv3上以读写模式对只有读权限的文件执行fortran打开调用,而如果在NFSv4上执行相同的操作,则打开调用将失败 让我解释一下,下面是一个简单的fortran程序,它以读写模式打开给定的文件(程序的参数) PROGRAM test_open IMPLICIT NONE ! Parameters INTEGER, PARAMETER :: lunin = 10 CHARACTER(LEN=100) :: fname ! Loca

我试图理解为什么可以在NFSv3上以读写模式对只有读权限的文件执行fortran打开调用,而如果在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 
您应该看到以下几行(以及许多其他输出)

因此,我们可以清楚地看到,在尝试以“O_RDWR”(open read-write)打开时,我们得到了一个“EACCES(Permission denied)”,但就在我们看到另一个打开的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”(打开读写)中打开文件,除此之外什么都没有(ie应用程序失败)

在C中使用一个小测试程序执行相同的测试时,它将无法在两种情况下打开文件(也就是说,在获得NFSv3上的“EACCES”后,它不会尝试以“只读模式”打开文件)

那么对于这些问题,

  • 我假设上述行为是由于在fortran中实现了OPEN调用,并且如果fortran在尝试打开文件时得到“EACCES(权限被拒绝)”,它将自动尝试以只读(O_RDONLY)方式打开文件。这个假设正确吗

  • 我还假设fortran在尝试打开文件时获取“EPERM(不允许操作)”时没有这种“回退方法”。这个假设是正确的,还是我遗漏了什么

  • C似乎在“EACCES”或“EPERM”中都没有实现“回退方法”。这对我来说似乎是正确的,因为这没有留下任何混乱的空间。如果你试图以一种你没有权限的方式打开一个文件,这个程序应该会失败——我的观点

  • 我知道“拒绝许可”和“不允许操作”之间有着明显的区别。我想,当在kerberos上安装NFSv4时,有理由得到“拒绝许可”而不是“不允许操作”,但是关于这方面的一些澄清将是非常好的


当然,将适当的标志添加到打开调用(ACTION=READ)可以解决问题。我只是好奇我的假设是否正确。

回答你的问题,顺序如下:

  • 当遇到EACCES(或EROFS)时,gfortran将尝试以只读模式重新打开文件,这是正确的

  • 同样正确的是,EPERM不是以这种方式处理的,libgfortran源代码树中根本没有提到它

  • 正如你所说,这是一个意见问题。Gfortran早就决定这么做了,它似乎很适合用户

  • 我不理解为什么在这种情况下NFS v4返回EPERM。这似乎至少与我可以访问的open(2)Linux手册页中的文档不符,在那里,只有在指定了O_NOATIME时才提到它(libgfortran没有这样做)。至少,这种行为似乎不可移植

感谢您的详细解释。我仍然必须说,格弗特兰的这种行为是值得怀疑的,如果不是的话,也是前后矛盾的。为什么您只在某些情况下尝试重新打开文件(如在EACCES&EROFS中,而不是在EPERM中),如果gfortran希望这种回退行为,我认为它应该在“打开文件时出现问题的所有情况下”——我的2美分=)回退,我已为此问题提交。
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)