dcache icon indicating copy to clipboard operation
dcache copied to clipboard

Attempt to read NEARLINE file if staging is not allowed for NFS protocol gives "Remote I/O" error.

Open DmitryLitvintsev opened this issue 1 year ago • 2 comments

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.

DmitryLitvintsev avatar May 02 '23 19:05 DmitryLitvintsev

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);

kofemann avatar Jun 08 '23 09:06 kofemann

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

kofemann avatar Jun 12 '23 14:06 kofemann