17.4. NFS

Written by Bill Swingle , 4 March 2000.

Among the many different file systems that FreeBSD supports is a very unique type, the Network File System or NFS. NFS allows you to share directories and files on one machine with one or more other machines via the network they are attached to. Using NFS, users and programs can access files on remote systems as if they were local files.

NFS has several benefits:

17.4.1. How It Works

NFS is composed of two sides - a client side and a server side. Think of it as a want/have relationship. The client wants the data that the server side has. The server shares its data with the client. In order for this system to function properly a few processes have to be configured and running properly.

The server has to be running the following daemons:

The client side only needs to run a single daemon:

17.4.2. Configuring NFS

Luckily for us, on a FreeBSD system this setup is a snap. The processes that need to be running can all be run at boot time with a few modifications to your /etc/rc.conf file.

On the NFS server make sure you have:

    portmap_enable="YES"
    nfs_server_enable="YES"
    nfs_server_flags="-u -t -n 4"
    mountd_flags="-r"

mountd is automatically run whenever the NFS server is enabled. The -u and -t flags to nfsd tell it to serve UDP and TCP clients. The -n 4 flag tells nfsd to start 4 copies of itself.

On the client, make sure you have:

    nfs_client_enable="YES"
    nfs_client_flags="-n 4"

Like nfsd, the -n 4 tells nfsiod to start 4 copies of itself.

The last configuration step requires that you create a file called /etc/exports. The exports file specifies which file systems on your server will be shared (a.k.a., "exported") and with what clients they will be shared. Each line in the file specifies a file system to be shared. There are a handful of options that can be used in this file but only a few will be mentioned here. You can find out about the rest in the exports(5) man page.

Here are a few example /etc/exports entries:

The following line exports /cdrom to three silly machines that have the same domain name as the server (hence the lack of a domain name for each) or have entries in your /etc/hosts file. The -ro flag makes the shared file system read-only. With this flag, the remote system will not be able to make any changes to the the shared file system.

    /cdrom -ro moe larry curly

The following line exports /home to three hosts by IP address. This is a useful setup if you have a private network but do not have DNS running. The -alldirs flag allows all the directories below the specified file system to be exported as well.

    /home  -alldirs  10.0.0.2 10.0.0.3 10.0.0.4

The following line exports /a to two machines that have different domain names than the server. The -maproot=0 flag allows the root user on the remote system to write to the shared file system as root. Without the -maproot=0 flag even if someone has root access on the remote system they won't be able to modify files on the shared file system.

    /a  -maproot=0  host.domain.com box.example.com

In order for a client to share an exported file system it must have permission to do so. Make sure your client is listed in your /etc/exports file.

Now that you have made all these changes you can just reboot and let FreeBSD start everything for you at boot time or you can run the following commands as root:

On the NFS server:

    # portmap
    # nfsd -u -t -n 4
    # mountd -r

On the NFS client:

    # nfsiod -n 4

Now you should be ready to actually mount a remote file system. This can be done one of two ways. In these examples the server's name will be server and the client's name will be client. If you just want to temporarily mount a remote file system or just want to test out your config you can run a command like this as root on the client:

    # mount server:/home /mnt

This will mount /home on the server on /mnt on the client. If everything is setup correctly you should be able to go into /mnt on the client and see all the files that are on the server.

If you want to permanently (each time you reboot) mount a remote file system you need to add it to your /etc/fstab file. Here is an example line:

    server:/home	/mnt	nfs	rw	0	0

Read the fstab(5) man page for more options.

17.4.3. Practical Uses

There are many very cool uses for NFS. Some of the more common ones are listed below.

17.4.4. Problems integrating with other systems

Contributed by .

某些用於ISA PC系統的乙太網路卡(Ethernet adapter) 可能會導致網路發生嚴重的問題,尤其是使用NFS的時候。 這個問題並非FreeBSD特有的,但是FreeBSD多少會受到影響。

這個問題幾乎總是發生同時擁有(FreeBSD) PC系統與高性能工作站的網路上, 例如矽圖(Silicon Graphics, Inc.) 和昇陽(Sun Microsystems, Inc.)所製造的工作站。 一開始,客戶端成功的掛上NFS檔案系統,一些操作也都順利的達成, 但是伺服器突然就對客戶端的要求毫無反應, 但是其它客戶端卻仍能正常工作,無論這些客戶端是FreeBSD系統或工作站。 在許多系統上,只要出現這個問題就無法正常的將客戶端關閉, 因為沒有辦法解決這種問題,唯一的辦法就是不斷的重置(reset)客戶端。

雖然FreeBSD"正確"的解決方法是改用性能更好的網路卡, 不過也有一個簡單可行的辦法: 如果你的FreeBSD系統是伺服端, 在掛上NFS時加上-w=1024這個參數; 如果是客戶端, 則在掛上NFS時加上-r=1024這個參數。 這些參數可以加在客戶端fstab檔案的第四個欄位, 或著是mount指令的參數-o後面。

有時後會出現另一種問題,但是經常被誤認為是我們在上面所提到的問題, 當NFS伺服端和客戶端位於不同的網路時, 務必確定你的路由器會傳送必要的UDP資訊, 否則就無法使用NFS。

在接下來的範例中,fastws是一部高性能工作站的名稱, freebox是一部FreeBSD系統,並且使用較差的網路卡,另外, /sharedfs是被開放(export)的NFS檔案系統 (請參考 man exports), 而/project 則是在客戶端的NFS掛入點(mount point)。在所有情況下, 你可以試著使用額外的參數,例如hardsoftbg

以FreeBSD系統(freebox)為客戶端的範例: 在freebox上的/etc/fstab檔案中:

    fastws:/sharedfs /project nfs rw,-r=1024 0 0

As a manual mount command on freebox:

    # mount -t nfs -o -r=1024 fastws:/sharedfs /project

以FreeBSD系統為伺服端的範例: 在fastws/etc/fstab檔案中:

    freebox:/sharedfs /project nfs rw,-w=1024 0 0

fastws上直接使用mount指令:

    # mount -t nfs -o -w=1024 freebox:/sharedfs /project

幾乎所有16位元的乙太網路卡對讀取或寫入的容量都沒有限制。

如果你有興趣,這個部份會告訴你錯誤發生的時狀況, 同時也會說明無法復原的原因。NFS一般是以8K為資料的傳輸單位, 但是乙太網路的封包最大為1500位元組,因此NFS 傳送的資料會被切割為許多的乙太網路封包, 而接收端在必須接收、組合封包,交給NFS系統並且送出回應 (acknowledge),高性能工作站可以將包含NFS 資料的封包依序取出(pump out)。但是在比較低階的網路卡上, 較晚送出的封包可能會跑得比先送出的封包快,導致NFS的資料無法重新組合, 當逾時值到達後,接收端就會要求傳送端將資料再送一次, 但是提供NFS服務的機器會將整個8K的資料重新送出, 而上面所說的整個程序就會再重複一次,最後進入一個不會停止的迴圈。

藉著讓NFS的資料傳輸單位小於乙太網路封包, 我們可以保證每個封包都可以正確的被接收及回應,進而必免這個問題。

當一部高性能的工作站以高速將資料送給PC系統時, 即使這部PC所用的是較好的網路卡,這種狀況仍可能發生。 當狀況發生時,被影響的NFS資料會被重新傳送, 不過封包會有一定的機會被接收、重組,然後送出回應。