An Example:
-----------

This example shows (very briefly!) how to install and run the NFS
server to export the directory /home/testnfs, and then to mount it on
the same machine as /mnt/nfs.  It is NOT intended to be complete,
rather it reflects a simple test case that may help you understand
what this enhancement permits.

Volunteers to write real documentation are very welcome!

Installation

Unpack the tgz file using tar:

$ tar -xvzf  ClusterNFS_1.0.0.tgz

change  into the directory

$ cd  ClusterNFS_1.0.0

and run "BUILD" and answer the questions

$ ./BUILD

now run make to compile the package

$ make

and then (as root) install the binaries and help pages using

$ make install

This last step is not necessary to run the examples below.

Setup:

Create  the directory /home/testnfs:

$ mkdir /home/testnfs

and create some sample files

$ echo "SAMPLE" > /home/testnfs/sample.txt
$ echo "SAMPLE FILE FOR 127.0.0.1" > /home/testnfs/sample.txt\$\$IP=127.0.0.1\$\$

$ ls -l /home/testnfs
total 2
-rw-r--r-- 1 root staff 7 Mar 9 16:32 sample.txt
-rw-r--r-- 1 root staff 23 Mar 10 13:51 sample.txt$$IP=127.0.0.1$$

Now, enable NFS mounting of this directory by adding  an appropriate line
to /etc/exports:

$ echo  /home/testnfs localhost(rw,no_root_squash) >> /etc/exports

Now, start the NFS daemon with the command line option "--translate-names":

$ ./rpc.nfsd --translate-names

Start the mount daemon

$ ./rpc.mountd 

Create (if necessary) the mount point  /mnt/nfs

$ mkdir /mnt/nfs


This should let you mount the directory at  /mnt/nfs

$ mount -t nfs localhost:/home/testnfs /mnt/nfs


(IF you get errors here, try starting nfsd and mountd using the parameters
	-F -d auth -d call -d fhcache --translate-names
 this will make them run in the foreground and display debugging information.)

Once you have mounted the directory, you can change to it 


Usage:

Ask for a directory  listing  of the mounted directory:

Note that you only see one file, even though the directory actually
contains 2 files.  

$ ls -l /mnt/nfs
total 1
-rw-r--r-- 1 root staff 26 Mar 10 15:01 sample.txt

The original sample.txt file has been "shadowed" by
the sample.txt$$IP=127.0.0.1$$ file.


(If you don't like this behavior, modify Makefile.in to comment out
the definition of READDIR_MASQUERADE.  This will restore the full
directory listing.)

When we try to read or write "sample.txt" we get the contents of
"sample.txt$$IP=127.0.0.1$$ "instead:

$ cat /mnt/nfs/sample.txt
SAMPLE FILE FOR 127.0.0.1

If we need the contents of "sample.txt" rather than
"sample.txt$$IP=127.0.0.1$$", we can use the file name "sample.txt$$$$":

$ cat /mnt/nfs/sample.txt\$\$\$\$
SAMPLE

The same things happens for file writes.  On the mounted filesystem,

$ echo Message from 127.0.0.1 > /mnt/nfs/sample.txt

actually modifies /home/testnfs/sample.txt\$\$IP=127.0.0.1\$\$ .

$ cat /home/testnfs/sample.txt\$\$IP=127.0.0.1\$\$
Message from 127.0.0.1

This also happens for directory access.

On the server, create two directories.  On "base" directory and one "client"
directory:

$ mkdir /home/testnfs/test/
$ mkdir /home/testnfs/test\$\$IP=127.0.0.1\$\$

Now, on the client, creating the file "/mnt/nfs/test/Test"

$ echo Test > /mnt/nfs/test/Test

results in a file being created in the "/home/testnfs/test\$\$IP=127.0.0.1\$\$"
directory.

$ ls -la /home/testnfs/test\$\$IP=127.0.0.1\$\$
total 3
drwxr-sr-x 2 root staff 1024 Mar 10 15:20 .
drwxr-sr-x 4 root staff 1024 Mar 10 15:20 ..
-rw-r--r-- 1 root staff 5 Mar 10 15:20 Test

leaving the "plain" test directory is unchanged:

$ ls -la /home/testnfs/test
total 2
drwxr-sr-x 2 root staff 1024 Mar 10 15:20 .
drwxr-sr-x 4 root staff 1024 Mar 10 15:20 ..


!!! NEW !!!:  ClusterNFS now supports filename translation on mount requests.

First, unmount the NFS filesystem

$ umount /mnt/nfs

Kill and restart the mountd daemon:

$ killall rpc.mountd
$ rpc.mountd --translate-names

Now, try mounting the 'test' directoy

$ mount localhost:/home/testnfs/test /mnt/nfs

Notice that the directory contains the file 'Test', 

$ ls -l /mnt/nfs
total 4
-rw-r--r--    1 root     staff           5 Sep 24 18:31 Test

This demonstrats that the mounted directory is actually 
/home/testnfs/test$$127.0.0.1$$.


Wish/Bug list:



  1. Currently the name translation applies only to nfsd.  Mount
     requests, which are serviced by mountd, do not have the name
     translation.  This could easily be implemented.
 
     [ Fixed in version 1.0.0-pre1, 2001-09-24 ]


  2. Currently, there is no method for causing file creation to occur
     with the an extended file name.  EG, there is no way to ensure
     that when a client creates a file named 'muck' that it will get
     created on the server with the name 'muck$$IP=xxx.yyy.zzz". 

     One idea for implementing this is allowing the user to create a
     file named "muck$$CREATE=IP$$".  This would mean 'Append the IP
     number to files created with the name "muck".  It would also seem
     useful to allow wildcards like "*$$CREATE=IP$$" meaning 'On any
     file creation, append the IP number.'

  3. The current implementation, searching sequentially along a fixed
     list of possible translations, has a number of inefficiencies and
     limitations.  A more efficient and more flexible approach would
     be to 'reverse' the process.

     When a file request arrives, 

     A) do a directory listing to find all files that match the
        base name

		 if the request is for 'my.file', search for
		 'my.file\$\$*\$\$' plus 'my.file'

     B) use the discovered entries as patterns to match against,
        possibly allowing wildcards.
            
        this will, of course, require definition of rules for
        resolving multiple matches.  A reasonable approach is that
        files which match on the largest number of fields match first.

        I.E., if the list of matching files is

             my.file$$IP=10.0.0.14$$
             my.file$$GID=57,HOSTNAME=bee*$$
             my.file

        we would first examine "my.file$$GID=57,HOSTNAME=bee*$$",
        since it has the most fields (2).  Parsing it, we arrive at
        two tests, first testing if GID=57.  If not, we can fall
        through to the next match.  If this matches, we then have
        another test "HOSTNAME=bee*".  This time we have a wildcard so
        we need to do pattern machine.

        If the file matched and is accessible, (readable) return it,
        otherwise, try the next filename in the list.