NFS 客戶端¶
NFS 客戶端¶
NFS 版本 2 協議最早在 RFC1094(1989 年 3 月)中進行了文件化。此後,NFS 又釋出了兩個主要版本,NFSv3 在 RFC1813(1995 年 6 月)中進行了文件化,NFSv4 在 RFC3530(2003 年 4 月)中進行了文件化。
Linux NFS 客戶端目前支援上述所有已釋出的版本,並且正在努力新增對 NFSv4 協議的次要版本 1 的支援。
本文件的目的是提供有關 NFS 客戶端的一些特殊功能的資訊,這些功能可以由系統管理員配置。
nfs4_unique_id 引數¶
NFSv4 要求客戶端使用一個唯一的字串向伺服器標識自己。客戶端和伺服器之間共享的檔案開啟和鎖定狀態與此身份相關聯。為了支援健壯的 NFSv4 狀態恢復和透明狀態遷移,此身份字串在客戶端重新啟動後不得更改。
在沒有任何其他干預的情況下,Linux 客戶端使用包含本地系統節點名稱的字串。然而,系統管理員通常不注意確保節點名稱是完全限定的,並且在客戶端系統的生命週期內不會更改。節點名稱可能有其他管理要求,需要特定的行為,而這些行為作為 nfs_client_id4 字串的一部分並不適用。
nfs.nfs4_unique_id 引導引數指定了一個唯一的字串,當 NFS 客戶端向伺服器標識自己時,可以與系統節點名稱一起使用。因此,如果系統節點名稱不唯一,其 nfs.nfs4_unique_id 可以幫助防止與其他客戶端的衝突。
nfs.nfs4_unique_id 字串通常是一個 UUID,儘管它可以包含任何被認為在所有 NFS 客戶端中都是唯一的字串。應該在安裝客戶端系統時選擇一個 nfs4_unique_id 字串,就像系統根檔案系統在安裝時其標籤中獲得一個新的 UUID 一樣。
該字串應在客戶端的整個生命週期內保持不變。如果小心確保客戶端乾淨關閉且所有未完成的 NFSv4 狀態已過期,以防止 NFSv4 狀態丟失,則可以安全地更改它。
此字串可以儲存在 NFS 客戶端的 grub.conf 中,也可以透過 PXE 等網路啟動設施提供。它也可以指定為 nfs.ko 模組引數。
此唯一識別符號字串對於所有在容器中執行的 NFS 客戶端都將相同,除非透過寫入 /sys/fs/nfs/net/nfs_client/identifier 的值進行覆蓋,該值將是寫入程序的網路名稱空間的本地值。
DNS 解析器¶
NFSv4 允許一個伺服器透過特殊的“fs_locations”屬性將 NFS 客戶端引導至已遷移到另一個伺服器上的資料。請參閱 RFC3530 第 6 節:檔案系統遷移和複製 和 NFSv4 中引用的實現指南。
fs_locations 資訊可以採用 IP 地址和路徑的形式,也可以採用 DNS 主機名和路徑的形式。後者要求 NFS 客戶端進行 DNS 查詢才能掛載新卷,因此需要一個向上呼叫以允許使用者空間提供此服務。
假設使用者已將“rpc_pipefs”檔案系統掛載到通常的 /var/lib/nfs/rpc_pipefs,則向上呼叫包括以下步驟
程序檢查 dns_resolve 快取以檢視它是否包含有效條目。如果包含,則返回該條目並退出。
如果不存在有效條目,則執行幫助指令碼“/sbin/nfs_cache_getent”(可以使用“nfs.cache_getent”核心引導引數更改),帶兩個引數:- 快取名稱,“dns_resolve” - 要解析的主機名
在查詢相應的 IP 地址後,幫助指令碼將結果寫入 rpc_pipefs 偽檔案“/var/lib/nfs/rpc_pipefs/cache/dns_resolve/channel”,格式如下(文字)
“<ip 地址> <主機名> <ttl>n”
其中 <ip 地址> 採用常見的 IPv4 (123.456.78.90) 或 IPv6 (ffee:ddcc:bbaa:9988:7766:5544:3322:1100, ffee::1100, ...) 格式。<主機名> 與幫助指令碼的第二個引數相同,<ttl> 是此快取條目的“生存時間”(以秒為單位)。
注意
如果 <ip 地址> 無效,例如字串“0”,則會建立一個負條目,這將導致核心將該主機名視為沒有有效的 DNS 翻譯。
一個基本的 /sbin/nfs_cache_getent 示例¶
#!/bin/bash
#
ttl=600
#
cut=/usr/bin/cut
getent=/usr/bin/getent
rpc_pipefs=/var/lib/nfs/rpc_pipefs
#
die()
{
echo "Usage: $0 cache_name entry_name"
exit 1
}
[ $# -lt 2 ] && die
cachename="$1"
cache_path=${rpc_pipefs}/cache/${cachename}/channel
case "${cachename}" in
dns_resolve)
name="$2"
result="$(${getent} hosts ${name} | ${cut} -f1 -d\ )"
[ -z "${result}" ] && result="0"
;;
*)
die
;;
esac
echo "${result} ${name} ${ttl}" >${cache_path}