Access to NFS-Share from Java-Application

扶醉桌前 提交于 2021-02-07 04:13:46

问题


I am trying to access a NFS share on a CentOS 6.3 System from within a Java application. I've tried the following libraries but can't get either to work:

YaNFS

Trying to access the NFS Share with YaNFS I run into an NfsException with ErrorCode 10001 (NFSERR_BADHANDLE). Sometimes the text of the Exception says "Stale NFS file handle". My code for YaNFS is:

    public static void main(String[] args) {
    XFile xf = new XFile("nfs://192.168.1.10/nfs-share");

    nfsXFileExtensionAccessor nfsx =
        (nfsXFileExtensionAccessor)xf.getExtensionAccessor();

        if (! nfsx.loginPCNFSD("192.168.1.10", "rpx-nfs-user", "Test123!")) {
             System.out.println("login failed");
             return;
        }

        if (xf.canRead())
             System.out.println("Read permission OK");
        else
             System.out.println("No Read permission");

}

nfs-client-java

Trying to initialize Nfs3 object with "nfs-client-java" I get a MountException that looks like:

com.emc.ecs.nfsclient.mount.MountException: mount failure, 
    server: 192.168.1.205, 
    export: /home/share, 
    nfs version: 3, 
    returned state: 13
at com.emc.ecs.nfsclient.nfs.nfs3.Nfs3.lookupRootHandle(Nfs3.java:359)

State 13 on this point says Permission denied.


I can access this share from another CentOS-System (with authorized to access to this folder uid and gid) by mounting this share and from Windows-System(with authorized to access to this folder login and password) as well.

Is there anyone, who has already solved this problem? Or maybe someone can help me get further?


回答1:


So, you indicate in a comment that you need a specific user's priveledges to be able to access the files, hence the 'Permission Denied' error. In YaNFS you need to look at the nfsXFileExtensionAccessor to be able to send the username and password so you can gain permission. Here's an example I pulled from this page: https://docs.oracle.com/cd/E19455-01/806-1067/6jacl3e6g/index.html

import java.io.*;
import com.sun.xfile.*;
import com.sun.nfs.*;

public class nfslogin {

     public static void main(String av[])
     {
          try {
               XFile xf = new XFile(av[0]);
               com.sun.nfsXFileExtensionAccessor nfsx =
               (com.sun.nfsXFileExtensionAccessor)xf.getExtensionAccessor();

               if (! nfsx.loginPCNFSD("pcnfsdsrv", "bob", "-passwd-")) {
                    System.out.println("login failed");
                    return;
               }

               if (xf.canRead())
                    System.out.println("Read permission OK");
               else
                    System.out.println("No Read permission");

          } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace(System.out);
          }
     }
}

EDIT

No, I don't think you're supposed to call bind() before the login operation. From the XFile sourcecode on github:

 /*
 * Check that the file is open.
 * The open() method must be called before
 * any other methods in the Accessor.
 * This makes it easier for Accessors to
 * centralize initialization code in one place.
 */
private boolean bind() {
    if (bound)
        return true;

    bound = xfa.open(this, false, false);

    return bound;
}

Since the bind() function is trying to open the file, it will always fail until you authenticate. Then consider this code from the XFileExtensionAccessor code on github:

/**
 * Sets the user's RPC credential from Login name and password.
 *
 * Every NFS request includes a "credential" that identifies the user.
 * An AUTH_SYS credential includes the user's UID and GID values.
 * These are determined from the user's login name (and password)
 * by the PCNFSD service that must be available on a local server.
 * Once the credential is set, it is assigned globally to all
 * future NFS XFile objects.
 * <p>
 * If this method is not called, a default credential is assigned
 * with a UID and GID of "nobody".
 *
 * @param  <code>host</code> The name of the host that runs the PCNFSD service.
 *   This does not have to be an NFS server.
 * @param <code>username</code> The user's login name.
 * @param <code>password</code> The user's password.
 *   This is obscured before transmission to the PCNFSD server.
 * @return true if the login succeeded, false otherwise.
 */
public boolean loginPCNFSD(String host, String username, String password) {
    return NfsConnect.getCred().fetchCred(host, username, password);
}

So, the loginPCNFSD() function sets credentials for the XFile system globally until you logout or use a new login. Definitely call it before calling XFile.Bind();




回答2:


The problem was solved by enabling CIFS protokol on the share and using old implimentation with JCIFS to transfer the data.



来源:https://stackoverflow.com/questions/41741365/access-to-nfs-share-from-java-application

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!