NFS協議
NFS (網絡文件系統)不是傳統意義上的文件系統,而是訪問遠程文件系統的網絡協議。整個NFS服務的TCP/IP協議棧以下圖所示,NFS是應用層協議,表示層是XDR,會話層是RPC,傳輸層同時支持UDP和TCP,網絡層是IP協議。NFS/XDR/RPC等協議規範細節在《TCP/IP詳解 卷1:協議》第29章有詳細的描述,這裏再也不贅述。html
通過多年的演進,NFS協議有多個版本,每一個版本都有相應的RFC規範,如RFC1813。每一個NFS的版本對好比下所示。linux
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服務的大部分功能都是由內核模塊實現的,除了圖中所示的內核模塊,內核還提供了幾個內核守護進程:cookie
- 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應用程序調試
打開應用程序調試功能:session
- /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模塊調試功能:app
- 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/四、ubifs等。其餘文件系統如rootfs、ramfs、sysfs等是不支持的。