Having figured out Samba shares, I thought I would tackle remote file systems between Linux machines using NFS (Network File Service). The documentation looked clear enough, but it wasn’t quit as easy as I expected, largely due to the differences between version 3 and 4 of NFS with respect to:
- firewall behavior
- exporting file system syntax and use of pseudo file systems
- difference in mount command syntax
I am running systems that use SELinux and firewalls*. I have one Centos 5.3 NFS server and three client machines running as virtual machines** on the server. My goal was to establish remote file systems for the virtual machine clients. I’ll skip some of the introductory steps to set up the nfs server process that are listed in the doc.
I’ll list the commands that I used to export the file system from the server and the mount command I first used on the client. The file system that I was attempting to export was /junk/client1. On the server (server.stevens.net), I added the following to /etc/exports:
/junk/client1 client1.stevens.net(rw) (:wq!)
[root@sserver /]# exportfs -rv
[root@sserver /]# exportfs -rv
exporting client1.stevens.net:/junk/client1
[root@sserver /]# service nfs restart
Shutting down NFS mountd: [ OK ]
Shutting down NFS daemon: [ OK ]
Shutting down NFS quotas: [ OK ]
Shutting down NFS services: [ OK ]
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS daemon: [ OK ]
Starting NFS mountd: [ OK ]
and I used the following mount command on client1.stevens.net (and received the error shown):
mount.nfs4: sserver.stevens.net:/junk/client1 failed, reason given by server: No
such file or directory.
A bit surprised that it didn’t work, I poked around the Internet and I found some good info that ultimately helped me get on the right track at Miles Brennan’s Linux Home Server HOWTO page. He does an excellent job explaining the pseudo file system configuration required for version 4 of NFS.
I built out the following psuedo file system on the server:
[root@sserver /]# cd NFS4exports
[root@sserver NFS4exports]# mkdir client1
[root@sserver NFS4exports]# mkdir client2
I then created bindings in /etc/fstab between /NFS4exports and /junk directories as follows (Bindings are like symbolic links, but the files are available in both filesystems, rather than being linked to the source location.):
/junk/client1 /NFS4exports/client1 none bind 0 0
/junk/client2 /NFS4exports/client2 none bind 0 0
[root@sserver /]# mount -a -t none
[root@sserver /]# cd /NFS4exports/client1
[root@sserver client1]# ls -ltr This actually displays the files & directories in the /junk/client1/ directory.
total 24
drwxrwxrwx 2 root root 4096 Sep 7 13:38 backup
drwxrwxrwx 2 root root 4096 Sep 7 13:38 filestore
-rwxrwxrwx 1 root root 39 Sep 7 13:41 client1.txt
Then I list the pseudo file systems in the /etc/exports file, and it is critical to note that the fsid=0 option be defined on the /NFS4exports file system (even though /NFS4exports itself will not be mounted by a remote client). Then all exported file systems are sub-directories of this system. If I had additional file systems elsewhere on the server that I wanted to share (say, /home), I would need to create an entry in the pseudo file system and bind it to /home in fstab.
/NFS4exports *.stevens.net(ro,fsid=0)
/NFS4exports/client1 client1.stevens.net(rw,nohide)
/NFS4exports/client2 client2.stevens.net(rw,nohide)
then export with exportfs -rv and restart nfs
Then I mounted the file systems from the client1 system. A major difference between the NFSv3 and NFSv4 command is that the root pseudo filesystem is not included in the identity of the remote file system (i.e., the NFS4exports directory is omitted from the command.
[root@client1 /]# ls -ltr /remotesys
total 24
drwxrwxrwx 2 root root 4096 Sep 7 13:38 backup
drwxrwxrwx 2 root root 4096 Sep 7 13:38 filestore
-rwxrwxrwx 1 root root 39 Sep 7 13:41 client1.txt
And on client2, showing an example that it can mount the client1 directory, but can’t see anything or write to it:
[root@client2 /]# cd /remotesys
[root@client2 remotesys]# ls
[root@client2 remotesys]# mkdir test
mkdir: cannot create director ‘test’: Read-only file system
[root@client2 remotesys]# cd..
root@client2 /]# umount /remotesys
[root@client2 /]# mount -t nfs4 sserver.stevens.net:/client2/remotesys
[root@client2 /]# cd /remotesys
[root@client2 remotesys]# ls -ltr
total 24
drwxrwxrwx 2 root root 4096 Sep 7 13:38 backup
drwxrwxrwx 2 root root 4096 Sep 7 13:38 filestore
-rwxrwxrwx 1 root root 39 Sep 7 13:41 client2.txt
And that completed my setup (except to modify /etc/fstab so that the new /remotesys file system will automount at boot). The main point was to learn about NFS, but I also ended up with a way to provide storage for my virtual machines outside of the .vmdk virtual file system.
Footnotes:
* NFSv4 plays better with firewall because, unlike NFSv3, it does not make use of portmapper and rpc.mountd, rpc.statd, and rpc.lockd. I just had to open port 2049 on the firewall for NFS. However, during some troubleshooting, I needed to execute “showmount -e sserver.stevens.net’ from a client machine. The firewall blocked it, because it uses rpc.mountd and portmapper picks a random port by default. I used /etc/sysconfig/nfs to define a static port for rpc.mountd and then opened this port on the firewall too.
** As a side note with respect to the virtualization setup, I created one vm and installed a small, simple Centos image. Then I copied the files twice to new folders in /var/lib/vmware/VirtualMachines. Then I imported these virtual machines into VMware Server to quickly make some clones. Just a quick edit of the /etc/sysconfig/network file to update each machine to a unique hostname, and I had 3 distinct client machines.