dcache
dcache copied to clipboard
Attempt to read NEARLINE file if staging is not allowed for NFS protocol gives "Remote I/O" error.
In dCache 8.2 attempt to read NEARLINE file via NFS ends up with "Remote I/O" error of staging is not allowed (by stage protection mechanism). This is too generic and can be confused with many other issues. We would like to have EPERM thrown in this case.
The corresponding kernel side code looks like this:
/* Prevent leaks of NFSv4 errors into userland */
static int nfs4_map_errors(int err)
{
if (err >= -1000)
return err;
switch (err) {
case -NFS4ERR_RESOURCE:
case -NFS4ERR_LAYOUTTRYLATER:
case -NFS4ERR_RECALLCONFLICT:
return -EREMOTEIO;
case -NFS4ERR_WRONGSEC:
case -NFS4ERR_WRONG_CRED:
return -EPERM;
case -NFS4ERR_BADOWNER:
case -NFS4ERR_BADNAME:
return -EINVAL;
case -NFS4ERR_SHARE_DENIED:
return -EACCES;
case -NFS4ERR_MINOR_VERS_MISMATCH:
return -EPROTONOSUPPORT;
case -NFS4ERR_FILE_OPEN:
return -EBUSY;
case -NFS4ERR_NOT_SAME:
return -ENOTSYNC;
default:
dprintk("%s could not handle NFSv4 error %d\n",
__func__, -err);
break;
}
return -EIO;
}
I will send a fix upstream, but we can't expect it to be available in RHEL 7, 8 and even 9.
Thus for us, a fix might be to return instead of EACCESS
WRONG_CRED
Could you try the following workaround:
diff --git a/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/ExceptionUtils.java b/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/ExceptionUtils.java
index 96c3b3747f..34302c5601 100644
--- a/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/ExceptionUtils.java
+++ b/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/ExceptionUtils.java
@@ -27,6 +27,7 @@ import org.dcache.nfs.status.NfsIoException;
import org.dcache.nfs.status.NoEntException;
import org.dcache.nfs.status.NoSpcException;
import org.dcache.nfs.status.ServerFaultException;
+import org.dcache.nfs.status.WrongCredException;
/**
* Utility class to convert {@link CacheException} into corresponding {@link ChimeraNFSException}.
@@ -82,7 +83,7 @@ public class ExceptionUtils {
case NO_POOL_ONLINE:
return new LayoutTryLaterException(e.getMessage(), e);
case PERMISSION_DENIED:
- return new AccessException(e.getMessage(), e);
+ return new WrongCredException(e.getMessage(), e);
case NO_POOL_CONFIGURED:
case RESOURCE:
return new NoSpcException(e.getMessage(), e);
While the trick nicely works with upstream kernel
$ cat profile
cat: profile: Operation not permitted
it goes into an infinite loop with RHEL 7, 8, and 9 kernels
However, the existing code works on RHEL9 (not on 8!!!)
# uname -a
Linux dcache-test 5.14.0-162.23.1.el9_1.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Apr 11 10:43:28 EDT 2023 x86_64 x86_64 x86_64 GNU/Linux
# cat profile
cat: profile: Permission denied
#
So, I would say won't fix
and will wait until clients update their OS