27.3 Network File System (NFS)

Reorganized and enhanced by Tom Rhodes. Written by Bill Swingle.

網路文件系統(Network File System), 是 FreeBSD 支援的眾多檔案系統之一,也被稱為 NFSNFS 允許一個系統分享其目錄與檔案給網路上的其他人。 透過使用 NFS 使用者和程式可以像在本地端一般地存取遠端系統中的檔案。

NFS 可以提供最顯而易見的好處是:

27.3.1 NFS 如何運作?

NFS 至少包含兩項主要部份: 一個伺服器以及一或多個客戶端。 客戶端遠端存取儲存在伺服器上的資料。 為了讓這一切正確地運作, 必須配置並執行一些程序。

伺服器必須執行下列的 daemons:

Daemon Description
nfsd 用來服務 NFS 客戶端請求的 NFS daemon。
mountd NFS 的掛載 daemon, 用來實行由 nfsd(8) 傳過來的請求。
rpcbind 這個 daemon 允許 NFS 客戶端查詢 NFS 伺服器使用了哪一個連接埠(port)。

客戶端也可以跑一種 daemon,稱為 nfsiodnfsiod daemon 處理從 NFS 伺服器發出的請求。 這是可以選擇的,它可以增加效能,但對於普通和正確的操作來說並非必要。 參閱 nfsiod(8) 來獲得更多資訊。

27.3.2 設定 NFS

NFS 設定起來相對地簡單。 若要讓其在啟動過程中跑起來,只需要對你的 /etc/rc.conf 做一點點修改。

NFS server 上面, 確保下列選項都被設定在 /etc/rc.conf 當中:


一旦 NFS 伺服器啟動了, mountd 便會自動跑起來。

在客戶端,確保下面這個選項出現在 /etc/rc.conf


/etc/exports 這個檔案指定了 哪些檔案系統 NFS 應該輸出 (有時也被稱為 “分享”)。 /etc/exports 當中的每一行都指定了一個會被輸出的檔案系統, 以及有哪些機器可以存取這個檔案系統。 在指定哪些機器可以存取這個檔案系統的同時,存取選項通常也會被指定。 有許多這類的存取選項可以被使用在這個檔案中,但在這裡我們只會提到一些。 透過瀏覽 exports(5) 手冊,你可以很輕易地找到其他的選項。

這裡有一些 /etc/exports 的設定例子:

下面給了一個如何輸出檔案系統的例子, 雖然其設定可能會因你的環境和網路設定而有所不同。 例如,要把 /cdrom 目錄輸出到三台 具有和伺服器相同網域名稱的機器 (因此每個都少了網域名稱), 或者是在 /etc/hosts 中有指定。 -ro flag 表示讓被輸出的檔案系統為只能讀取。 有了這個 flag,遠端系統便不能寫入或更動這個被輸出的檔案系統。

/cdrom -ro host1 host2 host3

下面這行將 /home 輸出到三台以 IP 位址表示的主機。 對於沒有設置 DNS 伺服器的私人網路來說,這相當地有用。 你也可以在 /etc/hosts 中設定內部的 hostname; 參考 hosts(5) 可以獲得更多資訊。 -alldirs flag 允許子目錄也可以當作掛載點 (mount point)。 換句話說,除非允許客戶端可以依照需求只掛載需要的目錄, 否則客戶端是不能掛載子目錄的。

/home  -alldirs

The following line exports /a so that two clients from different domains may access the file system. The -maproot=root flag allows the root user on the remote system to write data on the exported file system as root. If the -maproot=root flag is not specified, then even if a user has root access on the remote system, he will not be able to modify files on the exported file system.

/a  -maproot=root  host.example.com box.example.org

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

In /etc/exports, each line represents the export information for one file system to one host. A remote host can only be specified once per file system, and may only have one default entry. For example, assume that /usr is a single file system. The following /etc/exports would be invalid:

# Invalid when /usr is one file system
/usr/src   client
/usr/ports client

One file system, /usr, has two lines specifying exports to the same host, client. The correct format for this situation is:

/usr/src /usr/ports  client

The properties of one file system exported to a given host must all occur on one line. Lines without a client specified are treated as a single host. This limits how you can export file systems, but for most people this is not an issue.

The following is an example of a valid export list, where /usr and /exports are local file systems:

# Export src and ports to client01 and client02, but only
# client01 has root privileges on it
/usr/src /usr/ports -maproot=root    client01
/usr/src /usr/ports               client02
# The client machines have root and can mount anywhere
# on /exports. Anyone in the world can mount /exports/obj read-only
/exports -alldirs -maproot=root      client01 client02
/exports/obj -ro

The mountd daemon must be forced to recheck the /etc/exports file whenever it has been modified, so the changes can take effect. This can be accomplished either by sending a HUP signal to the running daemon:

# kill -HUP `cat /var/run/mountd.pid`

or by invoking the mountd rc(8) script with the appropriate parameter:

# /etc/rc.d/mountd onereload

Please refer to Section 11.7 for more information about using rc scripts.

Alternatively, a reboot will make FreeBSD set everything up properly. A reboot is not necessary though. Executing the following commands as root should start everything up.

On the NFS server:

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

On the NFS client:

# nfsiod -n 4

Now everything should be ready to actually mount a remote file system. In these examples the server's name will be server and the client's name will be client. If you only want to temporarily mount a remote file system or would rather test the configuration, just execute a command like this as root on the client:

# mount server:/home /mnt

This will mount the /home directory on the server at /mnt on the client. If everything is set up correctly you should be able to enter /mnt on the client and see all the files that are on the server.

If you want to automatically mount a remote file system each time the computer boots, add the file system to the /etc/fstab file. Here is an example:

server:/home   /mnt    nfs rw  0   0

The fstab(5) manual page lists all the available options.

27.3.3 Locking

Some applications (e.g. mutt) require file locking to operate correctly. In the case of NFS, rpc.lockd can be used for file locking. To enable it, add the following to the /etc/rc.conf file on both client and server (it is assumed that the NFS client and server are configured already):


Start the application by using:

# /etc/rc.d/nfslocking start

If real locking between the NFS clients and NFS server is not required, it is possible to let the NFS client do locking locally by passing -L to mount_nfs(8). Refer to the mount_nfs(8) manual page for further details.

27.3.4 Practical Uses

NFS has many practical uses. Some of the more common ones are listed below:

27.3.5 Automatic Mounts with amd

Contributed by Wylie Stilwell. Rewritten by Chern Lee.

amd(8) (the automatic mounter daemon) automatically mounts a remote file system whenever a file or directory within that file system is accessed. Filesystems that are inactive for a period of time will also be automatically unmounted by amd. Using amd provides a simple alternative to permanent mounts, as permanent mounts are usually listed in /etc/fstab.

amd operates by attaching itself as an NFS server to the /host and /net directories. When a file is accessed within one of these directories, amd looks up the corresponding remote mount and automatically mounts it. /net is used to mount an exported file system from an IP address, while /host is used to mount an export from a remote hostname.

An access to a file within /host/foobar/usr would tell amd to attempt to mount the /usr export on the host foobar.

Example 27-2. Mounting an Export with amd

You can view the available mounts of a remote host with the showmount command. For example, to view the mounts of a host named foobar, you can use:

% showmount -e foobar
Exports list on foobar:
% cd /host/foobar/usr

As seen in the example, the showmount shows /usr as an export. When changing directories to /host/foobar/usr, amd attempts to resolve the hostname foobar and automatically mount the desired export.

amd can be started by the startup scripts by placing the following lines in /etc/rc.conf:


Additionally, custom flags can be passed to amd from the amd_flags option. By default, amd_flags is set to:

amd_flags="-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map"

The /etc/amd.map file defines the default options that exports are mounted with. The /etc/amd.conf file defines some of the more advanced features of amd.

Consult the amd(8) and amd.conf(5) manual pages for more information.

27.3.6 Problems Integrating with Other Systems

Contributed by John Lind.

Certain Ethernet adapters for ISA PC systems have limitations which can lead to serious network problems, particularly with NFS. This difficulty is not specific to FreeBSD, but FreeBSD systems are affected by it.

The problem nearly always occurs when (FreeBSD) PC systems are networked with high-performance workstations, such as those made by Silicon Graphics, Inc., and Sun Microsystems, Inc. The NFS mount will work fine, and some operations may succeed, but suddenly the server will seem to become unresponsive to the client, even though requests to and from other systems continue to be processed. This happens to the client system, whether the client is the FreeBSD system or the workstation. On many systems, there is no way to shut down the client gracefully once this problem has manifested itself. The only solution is often to reset the client, because the NFS situation cannot be resolved.

Though the “correct” solution is to get a higher performance and capacity Ethernet adapter for the FreeBSD system, there is a simple workaround that will allow satisfactory operation. If the FreeBSD system is the server, include the option -w=1024 on the mount from the client. If the FreeBSD system is the client, then mount the NFS file system with the option -r=1024. These options may be specified using the fourth field of the fstab entry on the client for automatic mounts, or by using the -o parameter of the mount(8) command for manual mounts.

It should be noted that there is a different problem, sometimes mistaken for this one, when the NFS servers and clients are on different networks. If that is the case, make certain that your routers are routing the necessary UDP information, or you will not get anywhere, no matter what else you are doing.

In the following examples, fastws is the host (interface) name of a high-performance workstation, and freebox is the host (interface) name of a FreeBSD system with a lower-performance Ethernet adapter. Also, /sharedfs will be the exported NFS file system (see exports(5)), and /project will be the mount point on the client for the exported file system. In all cases, note that additional options, such as hard or soft and bg may be desirable in your application.

Examples for the FreeBSD system (freebox) as the client in /etc/fstab on freebox:

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

Examples for the FreeBSD system as the server in /etc/fstab on fastws:

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

As a manual mount command on fastws:

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

Nearly any 16-bit Ethernet adapter will allow operation without the above restrictions on the read or write size.

For anyone who cares, here is what happens when the failure occurs, which also explains why it is unrecoverable. NFS typically works with a “block” size of 8 K (though it may do fragments of smaller sizes). Since the maximum Ethernet packet is around 1500 bytes, the NFS “block” gets split into multiple Ethernet packets, even though it is still a single unit to the upper-level code, and must be received, assembled, and acknowledged as a unit. The high-performance workstations can pump out the packets which comprise the NFS unit one right after the other, just as close together as the standard allows. On the smaller, lower capacity cards, the later packets overrun the earlier packets of the same unit before they can be transferred to the host and the unit as a whole cannot be reconstructed or acknowledged. As a result, the workstation will time out and try again, but it will try again with the entire 8 K unit, and the process will be repeated, ad infinitum.

By keeping the unit size below the Ethernet packet size limitation, we ensure that any complete Ethernet packet received can be acknowledged individually, avoiding the deadlock situation.

Overruns may still occur when a high-performance workstations is slamming data out to a PC system, but with the better cards, such overruns are not guaranteed on NFS “units”. When an overrun occurs, the units affected will be retransmitted, and there will be a fair chance that they will be received, assembled, and acknowledged.


若有 FreeBSD 方面疑問,請先閱讀 FreeBSD 相關文件,如不能解決的話,再洽詢 <questions@FreeBSD.org>。
關於本文件的問題,請洽詢 <doc@FreeBSD.org>。