Understanding NFS
Pages: 1, 2
Looking at the contents of $HOME/serverhome, we see that the files are
mostly owned by mwlucas, with the occasional file owned by root.
Those files shouldn't be there, really; I have some root-owned .png
files that are screenshots of terminal windows that I took for my
book. Since I happen to be thinking about it, I'll remove them.
# su
# cd serverhome
# rm usersetup.png
override rw-r--r-- root/mwlucas for usersetup.png? y
rm: usersetup.png: Permission denied
#
But I'm root! Why would it not let me delete a file?
I'm root on the client, but not on the server. The server doesn't
trust root on other machines to execute commands as root on the
server. It does trust usernames, however. NFS has a special option
for handling root; you can map requests from root to any other
username. For example, you might say that all requests from "root" on
a client will run as "nfsroot" on the server. With careful use of
groups, you could allow this nfsroot user to have limited access to
things. Use the -maproot option to map root to another user.
This is my home network and I don't have other users, however, so I can just trust the client. In this case, I map NFS root requests to uid 0, aka root. Here's the new exports file.
/usr/home/mwlucas -maproot=0
I have to restart mountd again. Since NFS is stateless, old mounts
remain in effect. On the client, I'm even in the same directory;
restarting mountd didn't affect my client at all. The rm runs
flawlessly now.
So, what if I want to export another directory on the same partition?
For example, suppose I want to export /usr/src to my laptop to save
space on the hard drive? List the other directories in /etc/exports,
right after the first exported directory, separated by a space. While
I'm at it, I could also NFS-mount /usr/obj. This way, I could run
make buildworld on my fast machine and run make installworld on
my slow laptop, greatly accelerating upgrades. My /etc/exports now
looks like this:
/usr/home/mwlucas /usr/src /usr/obj -maproot=0
There are no identifiers between the components of the line. Yes, it
would be easier to read if we could put each shared directory on its
own line, but we can't; they're all on the same partition. The
FreeBSD team could rewrite this so that it had more structure, but
then our /etc/exports would be incompatible with that from any other
Unix. Restart mountd and mount these filesytems:
# mount server:/usr/obj /usr/obj
# mount server:/usr/src /usr/src
My client filesystems now look like this:
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/ad0s1a 99183 67411 23838 74% /
/dev/ad0s1f 5186362 3873110 898344 81% /usr
/dev/ad0s1e 198399 21212 161316 12% /var
procfs 4 4 0 100% /proc
server:/usr/obj 34723447 3886485 28059087 12% /usr/obj
server:/usr/src 34723447 3886485 28059087 12% /usr/src
#
A buildworld on my laptop takes two hours; on the server, it takes
thirty minutes. I ran a make buildworld and a make buildkernel
earlier on the server; if I wanted the same kernel, I could just go
into /usr/src and type make installkernel && make installworld &&
mergemaster, and the FreeBSD built on my server would be installed on
the laptop.
To make things slightly more difficult, my home system is on a cable
modem. I'm using one of FreeBSD's built-in firewalls to protect the
system, but it would be nice to add some security into NFS itself.
You can easily restrict NFS mounts by IP address, allowing only
certain clients to mount an exported share. Just specify the host
name or IP address at the end of the partition's /etc/exports entry.
My client has an IP address of 192.168.1.200, so my /etc/exports now
looks like this:
/usr/home/mwlucas /usr/src /usr/obj -maproot=0 192.168.1.200
This quickly becomes very convenient for upgrades. What's nice is
that you can also build ports on the server, and install them on the
client, by exporting /usr/ports. This is starting to get a little
ridiculous, however; eventually, /etc/exports will have entries for
almost every directory in /usr. I might as well export the whole of
/usr and get it over with. This isn't that great, either, because I
want to mount the exported directories at different places. The
exported ports tree should go over /usr/ports, for example, but I
don't want my server's home directory overwriting mine. Fortunately,
there's an easy solution. The -alldirs option allows you to export a
partition, and all the directories beneath it. You must specify a
partition when you use alldirs. Multiple options are separated by a
comma.
/usr -alldirs,maproot=0 192.168.1.200
Now I hup mountd again, and all of /usr can be exported and mounted
separately. For example, I still had /usr/src and /usr/obj NFS-mounted. Quick tests with df and ls show that they're still there,
still accessible, and still serving files, even though I've completely
redone the way they're exported. I can mount arbitrary directories
from the server's /usr.
Finally, here's a tip on NFS performance. By default, FreeBSD uses conservative NFS mounting options. These work well when trying to interoperate with other Unixes; everybody speaks the lowest common denominator. You can use mount options to augment NFS performance but reduce interoperability somewhat. These options aren't necessary when you're working with one or two clients, but as your NFS installation grows, you'll find them helpful. They may or may not work with other operating systems; it depends on what those OSs support.
First of all, NFS runs over UDP by default. The tcp option
tells the client to request a mount over TCP.
Then we want to make the mount interruptible. This means that if the
server goes away, for any reason, client programs that are trying to
access the export can be interrupted. Otherwise, the client will
continue trying to access the export until the filesystem times out.
Set this with the intr option.
NFS comes in many versions. The latest one in wide use is Version 3.
You can request this with the nfsv3 option.
|
Related Reading Managing NFS and NIS |
Finally, you have the size of read and write requests. The defaults
are rather small, being well suited to networks of the early nineties.
You can set the read and write size to more modern values with the -r
and -w options. 32768 is a good value for both.
So, putting this all together, I want to mount my exports in the following way.
# mount -o tcp,intr,nfsv3,-w=32768,-r=32768 server:/usr/home/mwlucas serverhome
This will give me close-to-optimal performance with minimal effort. Further fine-tuning NFS requires testing various options with your particular network equipment.
Now that I have NFS running at home, I find myself mounting from one machine to others for just about any reason. It's well worth the minor trouble to set up.
Read more Big Scary Daemons columns.
Return to the BSD DevCenter.

