Fortran OPEN-call在NFSv3与NFSv4上有所不同

时间:2015-02-24 13:01:56

标签: linux fortran system-calls gfortran nfs

我试图了解为什么你可以在一个只有读取权限的文件上以读写模式在NFSv3上执行fortran中的OPEN调用之间的区别,而如果你做同样的事情在NFSv4上,OPEN-call将失败。

让我解释一下,下面是一个简单的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(Permission denied)"试图打开O_RDWR' (打开读写),但是在我们看到另一个打开的O_RDONLY(打开只读)并且成功之后。

在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' (打开读写),仅此而已(即应用程序失败)。

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

所以问题,

  • 我认为上述行为是由于在fortran中执行了OPEN调用,并且如果fortran获得了一个" EACCES(Permission denied)"在尝试打开文件时,它会自动尝试以只读方式打开文件(O_RDONLY)。这个假设是否正确?

  • 我还假设fortran没有这种"后退方法"获得" EPERM(不允许操作)"在尝试打开文件时。这个假设是正确的,还是我错过了什么?

  • C似乎没有实施"后备方法"在一个" EACCES"也不是" EPERM"。这似乎对我来说是正确的,因为这并没有留下任何混淆的余地。如果您尝试以无权执行的方式打开文件,程序应该失败 - 我的意见。

  • 我知道" Permission denied"之间存在明显差异。和"不允许操作"。而且我想当将NFSv4安装在kerberos上时,有理由获得" Permission denied"而不是"操作不被允许"但是关于这个区域的一些澄清将是伟大的。

当然,在open-call(ACTION = READ)中添加适当的标志可以解决问题。我只是好奇我的假设以及它们是否正确。

1 个答案:

答案 0 :(得分:1)

按顺序回答您的问题:

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

  • 你也没有这样处理EPERM,根本没有在libgfortran源代码树中提到它。

  • 正如你所说,这是一个意见问题。 Gfortran很久以前做出了这样的决定,它似乎很适合用户。

  • 我不明白为什么NFS v4会在这种情况下返回EPERM。这似乎与我有权访问的open(2)Linux联机帮助页中的文档很不一致,只有在指定了O_NOATIME时才会提到它(libgfortran没有这样做)。至少,这种行为似乎不是可移植的。