Linux網絡文件系統的實現與調試
http://t.zoukankan.com/wahaha02-p-9559345.html
NFS協議
NFS (網絡文件系統)不是傳統意義上的文件系統,而是訪問遠程文件系統的網絡協議。整個NFS服務的TCP/IP協議棧如下圖所示,NFS是應用層協議,表示層是XDR,會話層是RPC,傳輸層同時支持UDP和TCP,網絡層是IP協議。NFS/XDR/RPC等協議規范細節在《TCP/IP詳解 卷1:協議》第29章有詳細的描述,這里不再贅述。

經過多年的演進,NFS協議有多個版本,每個版本都有相應的RFC規范,如RFC1813。每個NFS的版本對比如下所示。

NFS通過NFS過程來對外提供服務。如下是RFC1813中定義的一組NFS過程。
- null() 返回():不執行任何操作,有兩個作用:相當于到服務器的ping,以及檢測客戶端和服務器間的RTT(Round Trip Time)。
- lookup(dirfh, name) 返回(fh, attr):返回目錄中一個指定文件的fhandle和屬性信息。
- create(dirfh, name, attr) 返回(newfh, attr):創建一個新文件并且返回它的fhandle和屬性信息。
- remove(dirfh, name) 返回(status):從指定目錄中刪除文件。
- getattr(fh) 返回(attr):返回文件屬性信息。這個調用類似于一個stat調用。
- setattr(fh, attr) 返回(attr):設置一個文件的mode,uid,gid,size,access time,modify time屬性。將文件大小設置為0相當于對文件調用truncate。
- read(fh, offset, count) 返回(attr, data):從文件的offset偏移處開始,返回最多count個字節的數據。read操作也返回文件的屬性信息。
- write(fh, fh, offset, count, data) 返回(attr):向文件offset偏移處開始,寫入count字節的數據,返回寫操作完成后的文件屬性信息。
- rename(dirfh, name, tofh, toname) 返回(status):將dirfh目錄中名為name的文件,重命名為tofh目錄中名為toname的文件。
- link(dirfh, name, tofh, toname) 返回(status):在tofh目錄中創建名為toname的鏈接,指向dirfh目錄中的name文件。
- symlink(dirfh, name, string) 返回(status):在dirfh目錄中創建一個名為name的符號鏈接。服務器不解釋string的具體內容,而只是簡單將其保存起來并且與符號鏈接文件相關聯。
- mkdir(dirfh, name, attr) 返回(fh, newattr):在dirfh目錄中創建名為name的目錄,并返回其fhandle和屬性信息。
- rmdir(dirfh, name) 返回(status):從dirfh中刪除名為name的空目錄。
- readdir(dirfh, cookie, count) 返回(entries):從dirfh目錄返回組多count字節的目錄項信息。每個目錄項信息包含了一個文件名,文件id,和一個由服務器解釋的指向下一個目錄項的指針cookie。cookie的作用是在后續readdir操作中從一個指定的位置返回目錄項信息。cookie為0的readdir調用從目錄的第一個目錄項開始返回。
- statfs(fh) 返回(fsstats):返回塊大小、空閑塊數等文件系統的信息。
NFS特性對比
NFSv3特性對比
- V2支持的最大的文件大小為2GB(32bit),V3則更大(64bit)。
- V2將每個READ和WRITE 過程可以讀寫的數據限制為8192個字節,V3則取消了限制。RPC的讀寫字節數只受TCP/IP限制。
- V3引入新的NFS過程COMMIT,支持異步寫,提高寫性能。
- V3引入新的NFS過程ACCESS,支持服務側ACL訪問權限檢查。
- V3引入新的NFS過程READDIRPLUS,其返回file handle和屬性,這樣可以減少LOOKUP的調用次數。
- V3對RPC命令進行優化,每個影響文件屬性的RPC都返回新的屬性,這樣可以減少GETATTR的調用次數。
NFSv4特性對比
- V3是無狀態的,V4開始支持狀態。改善文件系統的異常恢復能力。
- V4支持file delegation(客戶端可以工作在本地副本,直到其他客戶端請求同一個文件),改善文件系統一致性問題。
- V4引入新的NFS過程COMPOUND,支持一個COMPOUND請求包含多個NFS過程。提高請求的表達能力,減少RPC請求的調用次數。
- V4強制支持RPCSEC/GSS,改善文件系統的安全問題。
- V4支持加密ACL,改善文件訪問權限管理。
- V4服務端為客戶端支持統一的偽文件系統視圖。服務端所有export目錄都必須在一個偽文件系統root export目錄下。
- V3客戶端的IP是自動適配的,V4客戶端支持mount clientaddr參數,可以指定客戶端特定的IP地址。
NFSv4.1特性對比
- 客戶端可以并行訪問存儲設備。
- 支持多個服務端。
- 支持文件系統的元數據和數據分離。
- delegation功能支持目錄。
- 支持會話機制(session),改善斷鏈、崩潰等異常恢復能力。
Linux NFS實現與實例
LInux NFS架構是典型的CS架構,其結構如下圖所示。其中服務端應用程序主要由如下幾部分組成:
- portmap:端口映射器,主要功能是進行RPC程序的端口映射工作。當客戶端嘗試連接并使用RPC服務器提供的服務(如NFS服務)時,portmap會將所管理的與服務對應的端口提供給客戶端,從而使客戶可以通過該端口向服務器請求服務。
- rpc.mountd:NFS掛載守護進程,主要功能是實現NFS MOUNT協議,負責掛載/卸載NFS文件系統和權限管理。它會讀取NFS的配置文件/etc/exports來對比客戶端訪問權限。掛載成功后,客戶獲得服務器文件系統的一個文件句柄(fh)。
- rpc.nfsd:NFS服務端守護進程,是NFS服務的用戶態部分,負責創建nfsd內核進程。需要提出的是,NFS服務的大部分功能都由nfsd內核進程處理。
可以看出NFS服務的大部分功能都是由內核模塊實現的,除了圖中所示的內核模塊,內核還提供了幾個內核守護進程:
- nfsd:主要作用是處理NFS的RPC請求。
- nfsiod:主要作用是為NFS客戶端提供高效的緩沖機制,如預讀、延時寫等,從而改善NFS文件系統的性能。
- rpciod:主要作用是作為RPC(遠過程調用服務)的守護進程,用于從客戶端啟動I/O服務。

下圖是一個NFS協議消息流圖實例(點擊見大圖),包含了一些典型的網絡文件系統操作場景,如:
服務注冊過程
- NFS掛載:mount 168.0.155.1:/datadisk0 /tmp
- 改變工作目錄:cd /tmp
- 查看目錄下文件:ls
- 讀文件:more tail bootcfg.ini

Linux NFS調試
NFS應用程序調試
打開應用程序調試功能:
/usr/sbin/portmap -d
/usr/sbin/rpc.mountd -d all
/usr/sbin/rpc.nfsd -d -s
查看NFS配置與記錄日志:
cat /etc/exports
cat /var/lib/nfs/rmtab
cat /var/lib/nfs/etab
cat /var/lib/nfs/xtab
cat /var/lib/nfs/state
tail /var/log/messages
NFS內核模塊調試
- 打開NFS模塊調試功能:
sysctl -w sunrpc.nfs_debug=2147483647
sysctl -w sunrpc.nfsd_debug=2147483647
- 查看NFS相關統計和日志:
cat /proc/slabinfo | grep nfs
/proc/fs/nfsfs/
nfsstat
dmesg
TCP/IP模塊調試
- 打開RPC模塊調試功能:
sysctl -w sunrpc.rpc_debug=2147483647
- 查看RPC相關統計和日志:
cat /var/run/portmap_mapping
cat /proc/net/rpc/nfs
cat /proc/net/rpc/nfsd
- 查看TCP/IP相關統計和配置:
ping // 查看網絡情況
netstat -tpwn | grep 2049 // 查看NFS TCP鏈接
cat /proc/sys/net/ipv4/... // 查看網絡配置,如tcp_retries2等
cat /proc/net/rpc/nfs
cat /proc/net/rpc/nfsd // deciles等字段
cat /proc/net/snmp // IP: ReasmFails等字段
sysctl -a | grep net // 查看所有網絡配置參數,如/proc/sys/net/ipv4/tcp_retries2控制tcp斷鏈嘗試次數
- 網絡抓包:
tcpdump -s 9000 -w /tmp/dump.out port 2049
其他
nfs-utils移植
./configure
CC=XX-gcc
--build=$(./config.guess)
--host=mips64-unknown-linux-gnu
LDFLAGS="-L/usr/local/lib"
CPPFLAGS="-I/usr/local/include"
--disable-tirpc --disable-gss --disable-uuid --without-tcp-wrappers --with-gnu-ld
make
make install
文件系統導出條件
由NFS導出的文件系統由配置文件/etc/exports配置,可以導出的文件系統需要滿足如下2個條件:
- 文件系統必須有一個設備號(需要有FS_REQUIRES_DEV,即存儲設備)或FSID號(需要有NFSEXP_FSID 或 ->uuid)。
- 文件系統必須支持s_export_op接口。而支持s_export_op接口的文件系統都是存儲設備文件系統,如ext3/4、ubifs等。其他文件系統如rootfs、ramfs、sysfs等是不支持的。
本文來自博客園,作者:dolinux,未經同意,禁止轉載

浙公網安備 33010602011771號