Solaris 10 and above and Red Hat Enterprise Linux (RHEL) 5 and above have support for NFSv4. Unfortunately, how each OS handles the newest version is different, and the way it is mounted is drastically different.
How each OS handles NFSv3 and NFSv4
All Linux distros treat NFSv4 as a different filesystem. Solaris treats NFSv4 as a newer version, which is the sane, and sensible way of handling it IMO; thanks Linux…. To mount an NFSv4 filesystem in RHEL 5, you mount it the following way:
mount -t nfs4 <server>:<share> <mountpoint>
For NFSv3, you mount it the following way:
mount -t nfs <server>:<share> <mountpoint>
Solaris 10 will automatically mount an NFS share as version 4, if the server supports it, and the client is configured to support NFSv4. To check the versions supported by the server and the client, see the /etc/default/nfs configuration file. Here are the options to look for:
# Sets the minimum version of the NFS protocol that will be registered # and offered by the server. The default is 2. #NFS_SERVER_VERSMIN=2 # Sets the maximum version of the NFS protocol that will be registered # and offered by the server. The default is 4. #NFS_SERVER_VERSMAX=4 # Sets the minimum version of the NFS protocol that will be used by # the NFS client. Can be overridden by the "vers=" NFS mount option. # The default is 2. #NFS_CLIENT_VERSMIN=2 # Sets the maximum version of the NFS protocol that will be used by # the NFS client. Can be overridden by the "vers=" NFS mount option. # If "vers=" is not specified for an NFS mount, this is the version # that will be attempted first. The default is 4. #NFS_CLIENT_VERSMAX=4
Notice that by default Solaris 10 will use NFSv4 for both clients and servers.
To manually mount a filesystem as NFSv4, you mount it the following way:
mount -F nfs -o vers=4 <server>:<share> <mountpoint>
Solaris 9 doesn’t support NFSv4, only v3. To mount a filesystem as NFSv3, you mount it the following way:
mount -F nfs -o vers=3 <server>:<share> <mountpoint>
If you are familiar with automount entries, you may already see the problem.
The NFSv4 automount problem
Linux is the cause of our problem. Implementing NFSv4 as a new filesystem instead of as a higher version number means we can’t simply pass a consistent option to the automounter to specify a mount as NFSv4. Here’s an example automount entry in LDAP:
dn: cn=test,nisMapName=auto_test,dc=example,dc=com nisMapEntry: example-server:/example/share objectClass: nisObject objectClass: top nisMapName: auto_test cn: test
If we want this to mount as NFSv4, we’ll need the following for RHEL 5 and above:
dn: cn=test,nisMapName=auto_test,dc=example,dc=com nisMapEntry: -fstype=nfs4 example-server:/example/share objectClass: nisObject objectClass: top nisMapName: auto_test cn: test
This won’t work on Solaris, as Solaris doesn’t treat NFSv4 as a separate filesystem.
Solving the problem
Creating the LDAP autofs entry
To avoid duplicating all automount entries for RHEL 4 and5, and Solaris 9 and 10, we’ll need to do some trickery on the systems and in LDAP. What we want, is for Solaris 9 and below to see the following:
dn: cn=test,nisMapName=auto_test,dc=example,dc=com nisMapEntry: -vers=3 example-server:/example/share objectClass: nisObject objectClass: top nisMapName: auto_test cn: test
Solaris 10 and above to see the following:
dn: cn=test,nisMapName=auto_test,dc=example,dc=com nisMapEntry: -vers=4 example-server:/example/share objectClass: nisObject objectClass: top nisMapName: auto_test cn: test
RHEL 4 and below to see the following:
dn: cn=test,nisMapName=auto_test,dc=example,dc=com nisMapEntry: -fstype=nfs example-server:/example/share objectClass: nisObject objectClass: top nisMapName: auto_test cn: test
and RHEL 5 and above to see the following:
dn: cn=test,nisMapName=auto_test,dc=example,dc=com nisMapEntry: -fstype=nfs4 example-server:/example/share objectClass: nisObject objectClass: top nisMapName: auto_test cn: test
Thankfully, autofs on both RHEL and Solaris supports variable substitution. We can use the following entry to achieve the above results:
dn: cn=test,nisMapName=auto_test,dc=example,dc=com
nisMapEntry: -${NFSOPT}=${NFSVER} example-server:/example/share
objectClass: nisObject
objectClass: top
nisMapName: auto_test
cn: test
The two above variables aren’t standard variables, so here’s where the trickery comes in.
Setting the autofs variables on each OS
On Solaris 9, we’ll have to modify autofs’s init script; the variables can be added to the autofs command like so:
/usr/lib/autofs automountd -D NFSOPT=vers -D NFSVER=3 < /dev/null > /dev/msglog 2>&1
Specifically the “-D NFSOPT=vers -D NFSVER=3″ portion of the line is the key portion.
On Solaris 10, the options can be added in /etc/default/autofs; simply add the following lines to the bottom of the file:
AUTOMOUNTD_ENV=NFSVER=4 AUTOMOUNTD_ENV=NFSOPT=vers
On RHEL 4 and below, the following can be added to /etc/sysconfig/autofs:
LOCALOPTIONS="-DNFSOPT=fstype -DNFSVER=nfs"
On RHEL 5 and above, the following can be added to /etc/sysconfig/autofs:
OPTIONS="-DNFSOPT=fstype -DNFSVER=nfs4"
You don’t necessarily need to use these variables; you can use any variables you want. Remember, though, if you change them, to change them all consistently.
Downsides to this approach
- You need to configure every single client to support it
- Every NFSv4 automount entry needs to have “-${NFSOPT}=${NFSVER}” added
- There is no way to make Solaris clients mount some mounts as NFSv3, and others as NFSv4