Hi all and many thanks for the tremendous amount of replies to my question.
Especially Ricks very helpful and professional reply must be honorably mentioned.
With all of your help (or maybe despite) I did some investigations and
snip it works!
To start from the very beginning, why use NFS instead of SMB (that is NOT Windows, many thanks Rick for the hint) is quite simple:
NFS is the commonly used way to connect to remote shares on Unix or Unix based or Unix like systems.
On the other hand, if you mount SMB manually (automounting may work if you pull the icon into your start-up settings,
but it will be disconnected when you use the sleep mode of your MAC often)
Than you have to mount it manually, that works, but:
The mount point looks something like this on your local file system:
/Volumes/DOMAINNAME;SERVERNAME /Volumes/DOMAINNAME;SERVERNAME-1 ... /Volumes/DOMAINNAME;SERVERNAME-n
So something like Domainname;Servername-<number of mount>
That is indeed not useful if you have for example your templates folder somewhere in your net.
As the path changes if you change the mounting order you will not be able to access this folder anymore. ==> not very useful
With an NFS mount, you can always use the same folder as it is automatically mounted by the automounter.
It creates something like this:
automount/Servers/<Servername>/<share>
This works also after a sleep mode because it is automatically re-mounted on request.
What I can't tell is why APPLE itself seems not to have an interest in fixing this, I found while traveling through the net a huge amount
of people that seem to have the same problems as I have but there is not any information given by APPLE (at least I did not find any)
But a lot of useful hints from many experienced users all over the world.
I will try to put these hints together here to give other users a reliable source of information.
NFS on a MAC HowTo
Prerequisite
This HowTo is not designed to tell how to set up an NFS server or how to connect to an NFS server.
A precondition for this HowTo is that you know how to set up a NFS connection on your MAC or that you have an existing connection that
in general works but that is slow.
If you want to set up an NFS connection here are some good and reliable sources:
http://blogs.acceleration.net/theoden/archive/2006/06/27/2973.aspx
http://linsec.ca/macosx/nfs_client.php
For NFS it is a known fact that writing to an NFS share is normally much slower than reading from it.
But it is not acceptable if the write speed is about 80 Kbit/sec.
The following list may give other users that want to use NFS some useful hints to find a solution to get some more speed out of their NFS connections.
I do like using the command line so if you don't like the command line or you are uncertain, I will try to give you a hint how to do this from the GUI.
1.) How fast is the NFS connection at present and are there any doubts?
We need the commandline.
Open a terminal window on your NFS server and a second one on your MAC.
In both windows run the following command:
netstat -I <interface name, see ifconfig> -p <protocol either udp or tcp> -w <interval in seconds>
Example: netstat -I en0 -p tcp -p udp -w 2
This will report every 2 seconds (from left to the right)
The number of packets send, number of errors occured and bytes send from the computer
The number of packets received, errors occured and bytes transfered from the net to this computer and the number of collisions
for upd and tcp packets (you can set more than one -p option).
If you immediately can see errors or collisions occuring make sure to read 2.) carefully! It seems that there is a serious problem with your network
settings or with your equipment (network card, cables, switches, hubs what ever you have)!
If there are no errors or collisions shown, copy a bigger file (lets say 100 Mb) from the NFS share to the local disk.
To get a reliable measurement use again the command line (third window) and run something like:
time cp <path to NFS share/filename> <local path>
The time command will measure the time needed to run the command and it will print out this information when the command has finished.
Note down the time needed.
Now, turn the process around:
time cp <local path/filename> <path to nfs share>
Again note down the time needed.
To find out about the speed, simply divide the filesize in Mb by the needed seconds(!) for both processes, this should give you a rough idea about the speed
and the possibility to find out later if the tuning worked.
As a rule of thumb for 100 Mbit/sec ethernets, for writing to an nfs server the amount of seconds needed should be about 50%
or less than the amount of Mb transferred (2 Mb per second), for reading from
an nfs share (writing to the local computer) we can consider 25% or less (4 Mb per second).
This is not really lightning fast but believe me it is far more then many others have 🙂
Please keep in mind that writing to an NFS share is much slower than reading from an NFS share.
This is maybe the time to think about what you do more, reading from NFS or writing to NFS?
2.) Make sure your network cards are configured properly
Run the command "ifconfig" from a shell you may get a more or less long list of interfaces.
On Unix (or Unix like... and so on) systems the name of the interface is different, it changes with the card manufacturer.
The interfaces gif0, lo0, fw0 and stf0 are not the ones you are looking for.
On my MAC the name is en0.
It looks like this:
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 192.168.111.8 netmask 0xffffff00 broadcast 192.168.111.255
ether 00:0d:96:b6:d1:54
media: 100baseTX <full-duplex> status: active
supported media: none autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback>
100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback>
There are some important informations in this output:
The line "media:" tells you about the selected speed for the interface.
Normally, autoselect should be fine, if this sets something strange like half-duplex or 10baseT this can be changed by the ifconfig
parameter media or easier use the system settings application, Network the tab Ethernet gives you the possibility.
CAUTION You may only want to change this if you really know what you are doing!
Please do only change this if you are sure that your network supports the setting you want to set as otherwise you may
lose your network connection completely!
Next parameter you should look for is the MTU (Maximum Transmission Unit) this limits the size of packets that are transmitted on an interface.
For ethernet it should be set to 1500 (Oktets).
This is an important parameter so handle with care!
It should be set to 1500 for an ethernet connection but be careful if you are using different network types the setting may differ!
Do not change this unless you know what you are doing!
Please see
http://en.wikipedia.org/wiki/Maximumtransmissionunit for more information. on the German page of this is a nice table that
shows the standard MTU settings for different network types:
http://de.wikipedia.org/wiki/MaximumTransmissionUnit
Do not increase this on ethernets as this does not help at all, the opposite will happen.
If you have a directly connected DSL modem and you see that the MTU there is set to something different (1492) do not change this!
For DSL connections your packets will be wrapped into an other packet (4 bytes header, 4 bytes tail) so don't change this.
The parameter can be changed using the parameter mtu of ifconifg or with the system settings application.
If this is fine, we can go on to investigate.
If your settings differ from the ones shown above, please invest some time to make sure that your settings are fine for your configuration.
3.) What kind of NFS server do you connect to and how is the server configured?
This information is also very important to know as these settings will tell you how to configure your local NFS client.
If you are not the administrator of the server sharing data via NFS, you may need some help from your friendly and helpful administrator.
Questions to be answered:
- What version of NFS the server is running on (Version 2 or 3 are the most common ones)?
- What protocol does the server use to share (UDP or TCP)?
- What ports are used (reserved ports)?
If you are not the administrator of the server, you are the lucky guy as your always being friendly and helpful administrator will answer your questions,
you do not need to work by yourself to find out 🙂
All others, the not so lucky ones, need to find the line in the startup scripts where the NFS server is started during boot.
Where these scripts are stored depends on the operating system that is running on the server.
For FreeBSD you can find the line starting the NFS server in /etc/rc.conf, watch out for nfs
serverflags.
If there is only a line saying nfs
serverenable="YES" than automatically the settings from /etc/defaults/rc.conf are taken. You may find a third line there like nfs
reserved_portonly="YES" if so, it answers the question about reserved ports.
For Linux systems it is different, you may like to have a look into /etc/rc.d or one of the /etc/rc1 to 6 folders (/etc/rc2.d) or one of the administrative tools like Yast.
For Solaris systems the folders in /etc/rc1 to 6 may be helpful, maybe something like /opt/SUNWnfs/etc or several other places as Sun tends to change this quite often.
It belongs to the Solaris version you are using, the upper hints should help for 8, 9 and 10.
When you have found the needed string, it may look like this: /sbin/nfsd -u -t -n 4
By reading the man page for nfsd, you will find out that this server shares its shares on TCP and UDP connections and it starts 4 server processes at boot time.
The nfsd does not offer too much options, here is a list of the options found in FreeBSD 4.11
- -u shares can be accessed with UDP
- -t shares can be accessed with TCP
- -a bind the wildcard address. This means NFS is available on all network interfaces and it is the default if no -h (see below) option is given. Do not do this.
- -h <bindip> bind to the IP address <bindip>.
- -n Specifies how many servers to create at start time
- -r Register NFS server with portmap without starting any server
If nothing is specified, the server operates on all interfaces and uses UDP.
Please do not hesitate to look it up by yourself as this may differ!
There is something that we can say in general:
If your NFS server supports TCP connections it is NFS version 3 as version 2 only supports UDP.
If only TCP is supported and it is not an option in the start up parameters, the server is maybe one of the rare version 4 ones.
If the NFS server only accepts connections on a secure port (port number < 1024) is somewhat difficult to find, as it is compiled into the kernel.
On FreeBSD you can find out by typing the command
sysctl vfs.nfs.nfs_privport.
The output looks like this if secure ports are enabled: vfs.nfs.nfs_privport 1
4.) What options are used by my NFS client to connect?
This information is normally stored in the netinfo database of your system.
It can be looked up by running the netinfo manager from the folder system programs and looking into /mounts or by running
nidump -r /mounts / from the command line.
If there are no results you may not have an NFS connection so do not wonder if it is slow 🙂
There are several possible options that can be found here.
If not already done, now is the time to read man mount_nfs
Please note that there are always two ways to tell the mounter what to do!
For example you can either use resvport or the option -P to get the system to use only reserved ports.
The information needed is available in the line "opts", the reserved word "net" must always be there and can be ignored here.
5.) Does the name resolution work properly?
This is also an important part of the configuration work as if the name given can not be resolved, you may not get connected.
To find out, we need again the output of the command nidump that we used in step 4 to find out what server we are connecting to.
If you have the output still on your screen, watch out for the line starting with "name = "
The same information can be found by running the netinfo manager application described above.
The output of nidump should look something like this: "name" = ( "<full qualified hostname>:<share to connect to>" ) ;
The full qualified hostname is the name of the server you want to connect to including the domain part.
Now open a terminal window on your NFS server and run the commands: hostname and domainname
The output should give you the domain the server belongs to the command hostname prints out the full qualified hostname.
The results may differ as it is possible that the server for example is a member of a NIS domain, but the full qualified hostname given
by the command hostname should be the same as the one shown by nidump.
Now lets try if it works.
Go to the terminal window of your MAC and run the command: dig <full qualified hostname of the nfs server>
You can also run this command on the NFS server itself the result should be the same.
The result should give you an Answer section where you can find the name and the IP address of your NFS server.
If this does not work or if this gives you different results the name resolution does not work as expected.
If you do not have a name server running, you need to create an entry for your NFS server in the file /etc/hosts
The entry should look something like this: <IP Adress of the host> <tab> <full qualified name> <tab> <hostname>
For example: 169.254.12.13 mynfsserver.mydomain.de mynfsserver
If you do not want that, the connection settings in netinfo need to be changed, remove the given server name and put the IP address instead.
This is not a very professional way but it works as long as the IP address is the one the NFS server is listening on.
6.) Find out about the settings of TCP buffers and other important kernel specific parameters
Be warned: Editing these variables may have a serious impact on your system!
It is also not true, that "much helps much" Please do not forget that you are playing around with very sensitive variables that have an influence on
your TCP stack and on any network connection that you may use so be careful!
It seems that some of the network parameters are set ... hmm lets say a bit too careful by APPLE.
To find out about your settings, please run the following commands from the command line of your MAC and write the results down.
sysctl net.inet.tcp.delayed_ack
sysctl net.inet.tcp.mssdflt
sysctl net.inet.tcp.sendspace
sysctl net.inet.tcp.recvspace
sysctl net.inet.tcp.newreno
The output of these commands tells you the actual settings.
Again, please be careful with changing these settings as they have a direct influence on the behavior of your TCP stack.
The variables used in here are only a small part of the amount of available variables and they only take care of TCP connections not on UDP!
I will now give you a short description what these variables mean.
net.inet.tcp.delayed_ack: Delay the ACK and piggyback it onto the packet? Default 0 (Do not) net.inet.tcp.mssdflt Default TCP maximum segment size Default 512
net.inet.tcp.sendspace Maximum outgoing TCP datagram size Default 32768
net.inet.tcp.recvspace Maximum incoming TCP datagram size Default 57344
net.inet.tcp.newreno Enable NewReno Algorithms (for more information visit
http://www.ietf.org/rfc/rfc3782.txt) Default 1 (Enabled)
7. Time for a short summary
What do we know now about our systems?
Almost anything we need to know 🙂
Let's summarize, we now know:
- The settings of our network card
- How fast our connection to the NFS server is at present
- The settings of our NFS server
- How we have set up our NFS client
- What the state of the naming resolution is
- What the kernel variables are set to
Now we can start to optimize.
I assume that if you found strange things about your network connection, that you already have fixed that, I also expect that your name resolution is working now and
that the NFS server is up and running. I also assume that you use a standard ethernet.
8.) Optimize syctl variables
Again be warned it is not a good idea to play around with that without knowing what you are doing!
The settings shown below are given in a good faith there is not at all any guarantee that it will work perfectly for you.
Lets give it a try and run the following commands from the command line:
sysctl -w net.inet.tcp.delayed_ack=0
sysctl -w net.inet.tcp.mssdflt=1460
sysctl -w net.inet.tcp.sendspace=65535
sysctl -w net.inet.tcp.recvspace=65535
sysctl -w net.inet.tcp.newreno=1
Please be aware that this needs to be done as root!
If you are not root, you will get a permission denied message so either become root by running the command su on the command line before you run the sysctl command
or run the commands with sudo for example sudo sysctl -w net.inet.tcp.delayed_ack=0 To find out if it worked as you expected it watch the output of the sysctl command, for example net.inet.tcp.delayed_ack: 0 -> 0 This would tell you that the variable already was set to that value.
After all variables have been set to the value shown above, we go back to copying (see 1.) and measure the speed.
It is maybe a good idea to use a different file or copy from/to a different share to prevent false data because of caching.
Looks much better now?
Fine 🙂
But there is a small problem: The settings for these variables will be set to the default when you reboot your MAC.
This is a pitty as it would mean that you have to do this any time you reboot your MAC, not a good thing.
But there are ways to prevent this:
8.1.) Option 1: Get the nfs-tuner utility from the fink packages database
It may be a good idea anyway to install fink on your system as it gives you a wide range of freely available software for your MAC.
Please find fink at
http://fink.sourceforge.net/ a description of the nfs-tuner package is available here
http://lists.finkproject.org/pdb/package.php/nfs-tuner
nfs-tuner can easily be installed and put into daemon mode to set the before mentioned variables during boot.
In fact the before mentioned settings are the ones nfs-tuner uses as default for me it turned out that these settings work great and I did not optimize them anymore.
Many thanks to Chris Zubrzycki who maintains this package and to whom ever created it, if you Chris or who else, thanks a lot for the great work.
nfs-tuner installs a small script doing this, /sw/sbin/nfs-tuner.sh
The variables can be configured/changed by editing the file /sw/etc/nfs-tuner.conf.
8.2.) Option 2: Create a file named sysctl.conf in your local /etc folder
This needs again to be done as root!
Go to the command line, become root and fire up your preferred editor (vi) by typing vi /etc/sysctl.conf
Put the following into the newly created file
net.inet.tcp.delayed_ack=0
net.inet.tcp.mssdflt=1460
net.inet.tcp.sendspace=65535
net.inet.tcp.recvspace=65535
net.inet.tcp.newreno=1
and save the file.
The file rights must be set to: owner root:wheel and -rw-r--r-- please make sure by typing ls -al /etc/sysctl.conf on the command line
and if not change it by running chown root:wheel /etc/sysctl.conf and chmod 0644 /etc/sysctl.conf from the command line.
9.) Optimize the settings for your NFS client
Now its the time to change the netinfo database.
I assume that you already have entries to automatically mount NFS shares.
This can easily be done with the netinfo manager application, so fire it up and click on the folder mounts
The part to be edited is the part "opts".
To add a new entry to the "opts" part, mark "opts" by clicking on it once and than click on directories, new value.
Whatever you want to put here belongs to the what the server offers, I will assume that your server supports TCP and uses reserved ports for connections.
Any entry needs to be put in a single line.
Double click the right part of the line where you want to add or change something and put in the desired value.
For the before mentioned server the settings to put would be -T (connect via TCP) -P (use reserved port) you also can put tcp instead of -T and resvport instead of -P
If you want to make really sure that protocol version 3 is used, put the option -3 or the phrase nfsv3 into a seperate line
(remember that version 2 of NFS only supports UDP).
An other option to think about is -b or bg that if the initial attempt to mount the share fails forks off this process and retries to mount in the background
and -d or dumptimer that turns off the dynamic retransmit timeout estimator.
This is useful for UDP mounts, to prevent that the timeout is too short if you experience high retry rates.
Please make sure to read man mount_nfs to find out about the meaning of the parameters you put into the netinfo manager!
If you click onto an other key you will be asked to update and save this as the actual version, click yes.
Do not forget to measure the result to see the impact on the performance.
10.) An other useful thing to look at
An other thing that need to be looked at is a thing that I did not find too often in the documentations: The nfsiod
This is a daemon that serves asynchronous I/O requests.
It is, for correct operations, not required but it improves the performance.
To find out if the nfsiod is running, go to the commandline and type ps -ax | grep nfsiod
This should show you a line (maybe among others) that looks something like
110 ?? Ss 0:00.00 nfsiod -n 4
If you can not find a line that looks like this and you are sure that you did not do a typo you can consider that there is no nfsiod running.
The idea is to find out how many daemons are required to give you a reliable speed, as this daemon really improves the speed but it is necessary to optimize the settings.
If you are not root, you should become root or use the sudo command to do the following things.
If the nfsiod is not running at all, try to start it by typing on the command line:
nfsiod -n 4 or sudo nfsiod -n 4
If there is no error message shown, the ps command given above now should show you a line as mentioned above.
Now measure again.
To find out if you can optimize this.
People that found a running nfsiod pop in here.
First of all, we need to stop the running daemon this is done with the command
kill <process ID> or sudo kill <process ID> where <process ID> is the first number in the row shown by the ps command.
In the example shown above it is 110.
After the process has been killed, start it with more servers, for example type nfsiod -n 6
Measure again.
.... and so on until you found an optimal setting.
To make the found settings boot proof, you need to add it to the corresponding startup script.
The nfsiod is normally started with the NFS startup script that can be found in /System/Library/StartupItems/NFS
The script itself is named NFS, you can edit it from the command line if you are root.
So become root if you are not and open the file with your preferred text editor.
Scroll down and find these lines that should normally be there:
# nsfiod is the NFS asynchronous block I/O daemon, which implements
# NFS read-ahead and write-behind caching on NFS clients.
nfsiod -n 4
Change the 4 to the value you found before for example put 6 or 8 here.
Save the file.
That's it!
What should I say these about 3 pages should give you the needed information to get a working NFS connection with a reliable speed.
I would like to say thank you to all the persons that put a real effort to help in several forums, like:
http://linsec.ca/macosx/nfs_client.php?display=printer
http://www.macosxhints.com/article.php?story=20030504042711312
and many others more.
If I used protected names in this document, please be aware that they belong to their owners and are used in here as the names are well known
and not at all for any other reason.
Stefan Schmidt
Mac Mini PowerMac 10,1 Mac OS X (10.4.8)