OS X as an NFS + autofs client
16/10/2011|
1 |
|
1 |
Edit:
Please see the information I posted in the comments below before enabling the autofs feature on a mobile OSX device.
Background
Both at home and works(s), I use nfs for sharing directories, a lot. I choose nfs a couple reasons: 1) every Linux/UNIX supports it (and even Windows *can*) and 2) it’s easy to set up. Sure, it has it’s problems, but so does every other way of sharing files. If your environment is sane and you know the limitations, nfs can be configured in a few minutes and works very reliably.
There’s a very handy tool called autofs that works well with nfs. It’s an automounter, but not like the ones most folks are familiar with. Forget making your usb stick or cd/dvd magically accessible, although it can do that too, autofs can mount essentially anything on demand/access, including network shares. In my case, I use it with nfs so when I access directories, nfs mounts attach and are ready for use. After an idle period (no applications using the shares/devices and no shells open in the), autofs also unmounts them, too, eliminating the mess caused by forgetting to unmount your shares or devices.
Recently, I acquired a Macbook Pro running Snow Leopard (OS X 10.6). It’s a nice addition to my hardware collection and connects easily to TV or stereo (DVI -> hdmi cable and 1/8″ audio -> RCA input cable, respectively). Only my Atrix has been as easy to connect to them, but using the macbook, I can get anything on the screen without using accessories.
My desktop has quite a few disks of storage in it, and a lot of it has backups, videos, or audio files that I already use on other networked computers here, so naturally I’d like to include the mac in the group of systems I share my data with. NFS shares to subnets or specific IPs, so I first created a Location (in Network Preferences) that sets a static IP when connecting to my home wireless network, giving me a specific target IP to share the directories to.
Exporting NFS Shares
The Linux side of nfs version 3 sharing is easy to configure. Edit /etc/exports and start up the nfs deamon. I’m going to show three shares here and how to export and then automatically mount them on the macbook. In the following output, three directories are shared to one IP address and they are shared with read/write access, asynchronous writes (faster), and with squashing root on the client end. I write them as ip/subnet to show that CIDR notation can be used when sharing over nfs.
|
1 |
# cat /etc/exports
/mnt/desktop/video 192.168.1.40/32(rw,root_squash,async)
/mnt/desktop 192.168.1.40/32(rw,root_squash,async)
/mnt/image 192.168.1.40/32(rw,root_squash,async)
Configuring OS X automounter
Because I want my shares to automatically mount on access on the mac, I am not going to configure the nfs mounts using fstab or Disk Utility -> File -> NFS Mounts to define them. I’m going to use the automounter files that are part of the OS X base install. The main automounter file on OS X is found at /private/etc/auto_master or can be referenced by the /etc/auto_master name, too, and contains a lot of entries that very few people use. I started by commenting out all the entries except /-, which is something that I don’t know is used or not:
#
# Automounter master map
#
#+auto_master # Use directory service
#/net -hosts -nobrowse,hidefromfinder,nosuid
#/home auto_home -nobrowse,hidefromfinder
#/Network/Servers -fstab
/- -static
Now I add a line where I can define the shares from my desktop/server system, named daemon. The first column shows a mount point that will automatically be created by the automounter. The second column tells it to parse a file named auto.daemon. I named the file after the system its defining mounts from and used a dot in the filename rather than the mac way of using an underscore:
/daemon auto.daemon
The next step is to create the file that defines the individual shares exported from the nfs server. I added an entry in /etc/hosts, which is on a different firewalled subnet but reachable through a static route on my gateway, so I could reference the server by hostname:
### Added to make automounter use hostnames instead of IP’s
192.168.11.2 daemon
For the auto.daemon file, three things need defined in a specific order: mount name, mount options, and path to the nfs share on the network. Mount options can be omitted if a default set works, but I am specifying them here. Also, I have three shares exported, but I can use two entries in auto.daemon to define them because I am using wildcards , which I’ll explain later:
#cat /etc/auto.daemon
video -rw,soft,resvport,rsize=32768,wsize=32768 daemon:/mnt/desktop/video
* -rw,soft,resvport,rsize=32768,wsize=32768 daemon:/mnt/&
First I’ll explain the mount options. I am mounting the shares read/write and using soft mounts. Soft mounts will timeout and return an error if the server is not reachable; the alternative to soft is hard mounting, which will wait forever for the server to come online unless a timeout value is given. The resvport option specifies that the server is running the nfs server on a privileged port, one below 1024. By default, OS X tries to reach nfs servers on higher port numbers, which would require the “insecure” option to be added to my /etc/exportfs options for each share listed above. The rsize and wsize values set chunk size for nfs reads and writes, respectively.
The third column of the output is the nfs path. Since I created an entry for daemon in /etc/hosts, I can use daemon:/<path to share>, which for video is the exported daemon:/mnt/desktop/video directory. I’ll discuss the second path containing the & in a moment.
The first column in the output above lists the mount points for shares. The mount points will be created on access and be found inside of the /demon directory that automounter creates. The first entry, video will allow me to access /daemon/video, which will show the contents of daemon:/mnt/desktop/video. On the Mac, software will see this no different than a local directory.
The second line of the auto.daemon output above uses wildcards in two places, for both the mount points and for the nfs path. The asterisk (*) at the beginning simply catches any entry under /daemon that is not explicitly defined before the wildcard line. So, for example, I can cd /daemon/desktop or /daemon/image without having lines for each of them. The ampersand (&) at the end of the line in the nfs path appends the value of the asterick to the nfs path. Thus, cd /mnt/image expands to daemon:/mnt/image.
The asterisk and ampersand entries have some limitations, though. First, the share path is required to be exported. My server may have a /mnt/usbstick directory, but cd /daemon/usbstick will fail if /mnt/usbstick is a mount point or directory that is not listed in /etc/exports on daemon. Second, shares expanded with wildcards must reside at the same absolute paths on the host exporting them. So, for example, if the host is exporting /usbstick, a /mnt/usbstick -> /usbstick symlink on the server will not let me cd /daemon/usbstick on my client; bind mounting directories would, however work. Third, a wildcard mount point must be the last entry of the automounter map file. Since the file is parsed top down with first to match logic, if the wildcard line is first, no other lines will be used.
After editing auto_master and/or any map files for mounts, the automounter needs to be restarted. The mountpoints I defined, both /daemon and those I explictly specified in auto.daemon will then show:
#automount -vc
automount: /daemon updated
automount: no unmounts
#ls /daemon
video
The Results
To show the ease and speed of NFS, I’ll issue a couple commands just I would normally use. The setup here is this: the macbook is connected to a linksys running DD-WRT. The server (daemon) is connected to another system over 100 MB ethernet, and that system also connects to the DD-WRT router over wireless. Traffic from the laptop to the server thus follow this path:
laptop -> DD-WRT -> static routing rule -> wireless connection -> iptables on middle man -> iptables on daemon
Run as root (sudo su -) on the mac
#mount |grep daemon
map auto.daemon on /daemon (autofs, automounted, nobrowse)
This shows that the automounter has /daemon running, but there are no submounts active inside the /daemon stub.
#time ls /daemon/video
<directory listing of 73 entries omitted>
real 0m0.293s
user 0m0.006s
sys 0m0.011s
To show ls was the slow part and not the mounting:
#umount /daemon/video
#time cd /daemon/video
real 0m0.058s
user 0m0.000s
sys 0m0.000s
Finally, lets remove the time it took to cd and get a time for just the nfs mounting:
#cd /
#umount /daemon/video
#mkdir /video
#time mount -t nfs -o resvport,soft,rsize=32768,wsize=32768 daemon:/mnt/desktop/video /video
real 0m0.043s
user 0m0.001s
sys 0m0.006s