Linux NFSv3和NFSv4上的Fortran OPEN调用不同
我试图理解为什么可以在NFSv3上以读写模式对只有读权限的文件执行fortran打开调用,而如果在NFSv4上执行相同的操作,则打开调用将失败 让我解释一下,下面是一个简单的fortran程序,它以读写模式打开给定的文件(程序的参数)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
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没有这样做)。至少,这种行为似乎不可移植
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)