NFSの動向

2017月４月
SCSK株式会社
R＆Dセンター 技術戦略部※本文中の会社名、商品名は、各社の商標及び登録商標です。

NFSの動向• NFSv3/v4プロトコル概要• NFSv4.1 (RFC 5661)– セッションの導入– pNFS (Parallel NFS)
– 委譲の強化• NFSv4.2 (RFC 7862)– サーバサイドコピー– I/Oアドバイス– 穴あきファイル• Linuxでの実装– カーネル– Red Hat Enterprise Linux
2

NFSv3ファイルシステムモデル (1/3)• Unixのファイルシステムモデル
サーバ/ (root)

/usr

/home

マウント
ポイント
/exportクライアントNFSマウント/ (root)
/home

/mnt

マウント
ポイント

/home
/home
/deraadt /perry /export/export
exported/vol1 /vol2
マウント
ポイント

/home
/home
/deraadt /perry

NFSマウント
exported

exported3

NFSv3ファイルシステムモデル (2/3)• ファイルハンドル: サーバ内のファイルを一意に識別するID• NFSのすべてのオペレーションの基本• 永続的: 通常、マウントポイントのID (デバ
イス番号など)、inode番号、世代番号などから合成– 世代番号: ファイルが削除され、inodeが再利用されたら?

• サーバの再起動などでも不変• クライアントからは透過、サーバがすべて
解釈
4

NFSv3ファイルシステムモデル (3/3)• 特殊ファイル – デバイスノード、名前つきパイプ、シンボリックリンク– デバイスそのものがexportされるわけではな
い (サーバ側のデバイスの操作はできない)– パイプの通信内容が転送されるわけではな
い (サーバ側のプロセスとの通信はできない)– シンボリックリンクの解釈はクライアントが行う (readlink(2)相当READLINKオペレーション)• 参考: ディスクレスクライアント
5

NFSv2/v3認証・アクセス制御モデル• AUTH_SYS認証～UnixのUID、GIDを利用– UID、GIDの一貫性が必須
サーバ

クライアント/etc/passwd
alan:1001:…
dillon:1002:…

/etc/passwd
dillon:1001:…
rms:1002:…

/ (root)/ (root)
/alan

/alan
/himitsuyo.txt

所有者: alan
モード: -rw------

/mnt
/mnt
/himitsuyo.txt

Kerberos認証、GSS-APIによる認証

所有者: dillon
モード: -rw-----6

ONC RPC (Sun RPC)
• Remote Procedure Call – リモートホストの手続きを呼び出す• マーシャリング: XDR表現

プロセスはディスクI/O
待ちの状態

クライアントプロセス

手続き呼び出しサーバプロセス

r=proc(a, b, c)
手続き処理
proc(a, b, c)

返事を待つ
実行再開

返り値･ステータス r

7Port mapper(NFSv4では1~6を飛ばす)

クライアント
1. mountdのポート番号?

Port
mapperTCP/UDPPort 111

2. ???番
3. /exportのファイルハンドル?
4. ファイルハンドル
5. NFSdのポート番号?
6. 2049番

0. 登録

Program

vers

proto

port

100000

2

TCP

111

Portmapper

100000

2

UDP

111

Portmapper

100003

2

TCP

2049

NFS

100003

3

UDP

2049

NFS

100005

2

TCP

???

mountd100005

3

UDP

???

mountd…

…

…

…

TCP/UDPPort ???

mountd …

TCP/UDPPort 2049

nfsd
nfsd
nfsd

7. NFSリクエスト
8. NFSリプライ…

8

NFSv4概要• NFS v3までの課題を解決– 広域での利用に適したメッセージ構造– Windowsとの相互運用性– 強力なセキュリティ機能• 既存実装の再利用は考えず、根本から設計を改訂9NFSv4ファイルシステムモデル (1/4)• 基本は同じ• ユーザID/グループID (v3) → UTF8文字
列によるユーザ名/グループ名 (v4)
• ファイル名は0で終端するASCII文字列(v3) → 0で終端するUTF8文字列• ルートファイルハンドルの概念: サーバのファイルシステム構造のエクスポート(v3) → サーバのファイルシステム構造の隠蔽 (v4)
10

NFSv4ファイルシステムモデル (2/4)
サーバ (exported namespace)

サーバ (local namespace)
ルート
ファイルハンドル/ (root)
マウント
ポイント

マウント
ポイント
/export/home

exported

ルート
ファイルハンドル

マウント
ポイント
/

/export/export /export
/vol1
/vol2

/home

/vol1

/vol2

/export /export/home /home/deraadt /perry
11

NFSv4ファイルシステムモデル (3/4)
exported

サーバ(exported namespace)

クライアント/ (root)
ルート
ファイルハンドル

/home

/
/home
/vol1

/vol2

/mnt

/home
/home
/deraadt /perry
NFSマウント

NFSマウント
12

NFSv4ファイルシステムモデル (4/4)• ファイルハンドルは永続的とは限らない• ファイル属性fh_expire_type– FH4_PERSISTENT、FH4_NOEXPIRE_WITH_OPEN、
FH4_VOLATILE_ANY、FH4_VOL_MIGRATION、
FH4_VOL_RENAME• NFSエラーコードNFS4ERR_FHEXPIRED

13

COMPOUND処理• 複数のオペレーションを1つのメッセージに• カレントファイルハンドルの導入
例: data.txtの読み込み
従来

NFSv4

LOOKUP(ROOTFH,“data.txt”)
FH

COMPOUND {PUTFH(ROOTFH)
OPEN(“data.txt”)
READ(offset,len)}
DATA

READ(FH,offset,len)
DATA

メッセージ2往復

メッセージ1往復
14クライアント側のキャッシュ処理• Delegationによるキャッシュ– ファイルを占有できる場合:• OPENしているクライアントが1つである場合• 書き込みOPENしているクライアントがない場合– Delegationの解除→クライアントへのコールバック

15

Windowsとの相互運用性• OPEN/CLOSEの導入 → stateless性の放棄:
client IDにより再起動時の状態復旧を実現• ロックプロトコルの統合• 揮発性ファイルハンドル
例: ファイルのリネーム Unixではi-node番号が変わらないためファイルハンドルも不変だった• Windowsのアクセス制御モデルのサポート• Unicode (UTF-8) ファイル名

16

Windowsとの相互運用性• OPEN/CLOSEの導入 → stateless性の放棄:
client IDにより再起動時の状態復旧を実現• ロックプロトコルの統合• 揮発性ファイルハンドル
例: ファイルのリネーム Unixではi-node番号が変わらないためファイルハンドルも不変だった• Windowsのアクセス制御モデルのサポート• Unicode (UTF-8) ファイル名

17

NFS file locking• NFSv3––––

optional (NLM)
callback based sleep lockfragile,racy
crash recovery by notification (callback)• NFSv4– polling based sleep lock– seqid4: at-most-onc e semantics by more reliable DRC(Duplicate Request Cache)– crash recovery by lease expiration– if a client holds a write delegation, locking can be performed
locally18

NFSv3+NLM
NFS サーバー

NFS クライアント
NFS

nfsd

nfs
clientNLM
lockd
exported
file system

lockd

NSM(+α)application

NSM(+α)NSM
statdstablestoragestatd
stablestorage19

lockf 処理概要(NFSv3+NLM)
NFS クライアント

NFS サーバー

nfs
clientnfsd

lockd
exported
file system

SM_MON

statd
stablestorage

NLM_LOCK

lockd

application

SM_MON

statd
stablestorage20

blocking lock(NFSv3+NLM)
NFS クライアント

NFS サーバー

NLM_LOCK(block=TRUE)LCK_BLOCKED

lockd

lockd

NLM_GRANTEDLCK_GRANTED
callback
21

client crash recovery(NFSv3+NLM)
NFS クライアント

NFS サーバー

nfs
client

nfsd

lockd

lockd

exported
file system

SM_MON
RPC
stablestorage

SM_NOTIFY

statd

statd
stablestorage22

server crash recovery(NFSv3+NLM)
NFS クライアント

NFS サーバー
grace periodnfsclient

nfsd

lockd

NLM_LOCK(reclaim=TRUE)

lockd

exported
file systemstatdstablestorage

SM_NOTIFY

application
SM_MONRPC

statd
stablestorage23

NFSv4
NFS サーバー
nfsd

NFS クライアント
NFS

nfs
clientapplication
exported
file systemstablestorage24

lockf 処理概要(NFSv4)
NFS サーバー
nfsd

NFS クライアント
LOCK

nfs
clientstateid
seqid
application
exported
file systemstablestorage25

lockf 処理概要(NFSv4+ delegation)
NFS サーバー
nfsd

NFS クライアント
nfs
clientwrite
delegation
application

exported
file systemwrite delegation

stablestorage26

blocking lock(NFSv4)
NFS サーバー

NFS クライアント

LOCK(lock_type = READW or WRITEW)NFS4ERR_DENIED
LOCK
nfsd

(lock_type = READW or WRITEW)NFS4ERR_DENIED

nfs
clientpolling

LOCK(lock_type = READW or WRITEW)

NFS4_OK27

client crash recovery(NFSv4)
NFS サーバー
nfsd

NFS クライアント
SETCLIENTID

nfs
clientlease expirationclientid
SETCLIENTID

exported
file systemstablestorage28

server crash recovery(NFSv4)
NFS サーバー
nfsd
grace period

NFS クライアント

Lease renewal(implicit or explicit)
LOCK(reclaim=TRUE)

nfs
clientNFS4ERR_STALE_CLIENTID

application
exported
file systemstablestorage29

NFSv4.1概要

30

NFSv4.1の主な機能• セッションの導入• pNFS• 委譲の強化– ディレクトリなどファイル以外の委譲• ディレクトリの変更をコールバック可能– WANT_DELEGATION (委譲が可能になったらコールバック) など

31

セッション
NFSv2/v3
ステートレス
ロックは外出し (NLM)

NFSv4

NFSv4.1

ステートフルステートフル

OPEN/CLOSE: 委譲
Client ID: ファイルロック、
委譲

OPEN/CLOSE: 委譲
Client ID: ファイルロック、
委譲
Session ID: EOS、トランキング

EOS: Exact Once Semantics
32

セッション• mount時に確立

コネクションを既存のセッションに関連付けることも可能(BIND_CONN_TO_SESSION)

クライアントサーバ
EXCHANGE_ID call

総スロット数などを
交渉

Client ID確立
EXCHANGE_ID reply

CREATE_SESSION callSession ID確立
CREATE_SESSION reply

33

EXCHANGE_ID

他にセッション乗っ取り防止策など• 主な引数– client_owner: verifierとowneridの組Linuxでは時刻
Linuxではホスト名やIPアドレ
スを組み合わせるLinuxでは時刻と通し番号から生成• verifierはクライアントの再起動ごとに変わる整数• owneridはクライアントを識別する文字列– flags: pNFSやマイグレーションなどの受け入れ状況をサーバに知らせる• 主な返り値– clientid: サーバがクライアントごとに振るID番号– sequenceid: CREATE_SESSIONのsequence– flags: 引数のflagsとのANDを取る– server_owner: minor_idとmajor_idの組• major_idはサーバを識別する文字列。一致すれば同じサーバ• minor_idは数値で、これも一致すればセッションを共有できるLinuxではホスト名Linuxでは常に
0
34

CREATE_SESSION
•

主な引数

複数の
EXCHANGE_ID/CREATE_SESSIONが、単一コネクションに同時に流れた時に、混ざらないようにする– clientid: EXCHANGE_IDで得たもの– sequenceid: 同上– flags 以下のほか、RDMA関連• FLAG_PERSIST: reply cacheをpersistentにしてほしい• FLAG_CONN_BACK_CHAN: このコネクションを、セッションのforechannelかつback channelにしてほしい
Linuxではこの2つを必ずセットする•

Linuxでは
FLAG_CONN_BACK_CHANのみサポート– fore_chan_attrs/back_chann_attrs: 要求/応答の最大バイト数、同時に発行できるCOMPOUND数など

主な返り値– sessionid: 以後使うセッションのID– sequenceid: 引数と同じ値を返す– flags: 引数のflagsとANDを取る– fore_chan_attrs/back_chan_attrs: 引数の値に対して減らしていい属性は定められている
35

チャネル
• 各セッションは1または2つのコネクショ
ンを持つ– Fore channel: クライアント⇒サーバ方向のRPC呼び出しと応答– Back channel: サーバ⇒クライアント方向のRPC呼び出しと応答 (コールバック)– 両者は同じコネクションでもよい• LinuxのNFSクライアントでは今のところいつも同じコネクション36

セッション• 以後COMPOUNDの最初のオペレーションは
SEQUENCE– 引数: sessionid、sequenceid、slotid
これが必ず付くので、 – sessionid: Session ID
パケットダンプの様相
はNFSv4とはだいぶ – sequenceid: 各スロットごとに1から始まる番号。
違う
スロットの再利用時に1増える– slotid: スロットの番号。EXCHANGE_IDで交渉された数のスロットが確保され、それ以上の要求を同時に送ることはできない

37

COMPOUND• NFS v4のCOMPOUNDCOMPOUND

tag

minorversion

# ops

PUTFH

OPEN

READ

1

(unused)0

3

22 xx-xx

18 file.txt

25 …

NFS v4.1のCOMPOUNDCOMPOUND

tag

minorversion# ops

SEQUENCE

PUTFH

…

1

(unused)

1

4

53 …

22 xx-xx…

SEQUENCE

sessionid

sequenceid

slotidhighestslotid53

yy-yy-yy

3387

1

3
38

EOS (Exactly Once Semantics)• 例: RENAME
クライアントサーバ
RENAME call

RENAME 成功×

紛失

RENAME call

さっきのファイルはもうない!
(RENAME済)

再送!
RENAME 失敗

39

EOS (Exactly Once Semantics)• NFSv3は32bitのRPC XID (Transaction ID)で対応– XID (とクライアントのアドレス)が同じであれば、同じ要求の再送とみなす– このため、送信した応答をしばらく保存しておく必要がある (リプライキャッシュ)– いつまで保存しておけばよい??
– 32bitで (将来的に) 足りる?

• NFSv4はclient IDごとのsequence IDを利用– OPEN、LOCKなどのstateを変えるオペレーションにクライアントが付与– client IDと組で利用するため、再起動が検出可能– 依然としてリプライキャッシュの保存期間の問題

40

EOS (Exactly Once Semantics)• NFSv4.1では、セッションごとのリプライ
キャッシュに対応– セッションごとに、最初の交渉で決定されたス
ロット数が上限 (Linuxではクライアントの値はsysctl変数で設定、サーバは160が上限。ただしback channelはクライアント側の制限で1)• スロットが再利用されたことはシーケンス
IDで検出可能– シーケンスIDが同じ: 再送– シーケンスIDが戻った: 古い要求がなぜか来た– シーケンスIDが飛んだ: 何かがおかしい
41

SEQUENCE• 要求をSEQ(slotid, sequenceid,
highest_slotid) として、ClientServer
SEQ(0, 101)のreply cacheを破棄できる

SEQ(0, 102)、SEQ(1, 50)のreply cacheを破棄できる42

トランキング• セッショントランキング: Session IDを同じくする複数のコネクションよるトランキング• Client IDトランキング: Client IDを同じくする
複数のコネクションによるトランキング– つまり、複数のセッションを用いたトランキング

43

NFSv4のSETCLIENTID• Sessionの概念がなかったため、
CREATE_SESSIONに相当するものはな
い。Fore/back channelは分離できない。
• クライアント (client idで識別)、セッション、
コネクションの関係が整理されておらず、
client idは状態を作るOPENなどのオペ
レーションが実行されるまで不要。
SETCLIENTIDの実行もそれまで遅延で
きる。
44

pNFS
クライアント

サーバ

ストレージ「データサーバ」

45

pNFS• クライアントはサーバから「レイアウト」を取得– 通常のLOOKUP/OPENに次いで、READ/WRITEの代
わりに「LAYOUTGET」• クライアントはストレージと直接やり取りして
読み書き– ファイルレイアウト– オブジェクトレイアウト– ブロックレイアウト• クライアントはサーバに読み書きの終了を宣言– LAYOUTCOMMIT (書き込みのみ)、
LAYOUTRETURN
46

pNFS
• 最初のEXCHANGE_IDで交渉。5通り– EXCHGID4_FLAG_USE_PNFS_MDS– EXCHGID4_FLAG_USE_PNFS_MDS|EXCHGID
4_FLAG_USE_PNFS_DS– EXCHGID4_FLAG_USE_PNFS_DS– EXCHGID4_FLAG_NON_PNFS– EXCHGID4_FLAG_USE_PNFS_DS|EXCHGID4_FLAG_NON_PNFS
MDS: Metadata Server, DS: Data Server

47

pNFS
• シナリオ例
クライアントサーバ (メタデータサーバ)
EXCHANGE_ID
データサーバのIPアドレス
データサーバ内でのファイルハンドル
ストライプサイズなど

USE_PNFS_MDSLOOKUP/OPEN
reply

ストレージ (データサーバ)

LAYOUTGETLAYOUT4_NFSV4_1_FILESEXCHANGE_ID
USE_PNFS_DS
48

pNFS
ファイルレイアウト

オブジェクトレイア
ウト

ブロックレイアウト(p)NFSサーバ

オブジェクトスト
レージ

SAN

データパス・
プロトコル

NFSv4.1 (以降)SCSI Object-Based
Storage Device
Commands (OSD)
ANSI INCITS 4002004

iSCSI、FCP、FCoEなど

レイアウト規定

RFC 5661(NFSv4.1自体と同 RFC 5665
じ)

ストレージ
(例)

制御プロトコル

RFC 5663

規定なし

49

ファイルの委譲の強化• NFSv4: OPEN時に委譲できた場合のみ委譲• NFSv4.1: 委譲できるようになったら知らせられる– OPEN時に委譲できなくても、委譲できるようになったらコールバックするよう要求– OPEN後にWANT_DELEGATIONを発行し、委譲できるようになったらコールバックするよう要求• Linuxでは (サーバ、クライアントとも) 未実装

50

マルチサーバ構成• NFS v4でも、referralにより他のサーバにリダイレクトすることができた (レプリケーション、マイグレーション)– fs_locations属性: サーバのアドレス (DNS名またはIPアドレス) とルートパスの組を複数並べられる• ⇒FedFS (Federated FS)• NFS v4.1のreferralではサーバのアドレスのほか、各サーバの優先順位 (読み書き別々に)、有効期限などが指定できる (fs_locations_info属性)• その他: サーバのminor id、サーバスコープ…

51

ロックの拡張• RECLAIM_COMPLETEの導入– RHEL6でも実装済– (次ページ)• CB_NOTIFY_LOCKの導入– RHEL7でも未実装と思われる– ロック要求時に衝突のため拒否された場
合、ロックできるようになったらコールバッ
クする機能• NFS v4ではポーリングする必要があった
52

RECLAIM_COMPLETE• サーバ再起動後のgrace期間におけるロック回復がすべて終わったことを明示する• 回復すべきロックを持たないクライアントは、セッショ
ン回復に続いて即座に発行• 再起動前Lock A、Bの2つを持っていたとして…
再起動
を検出

Client 1

Server
再起動
grace期間
53

RECLAIM_COMPLETE
再起動
を検出

再起動
を検出

NWダウン

実際にはこのLockは有効ではないが、v4ではそれを検知する手段がない

Client 1
NW回復を検出

Server
再起動

再起動
grace期間

grace期間

Client 2• サーバが、回復中 (RECLAIM_COMPLETE前) のクライアントをディスクに覚えておけば解決できる
54

NFSv4.2• RFC 7862 (2016年11月)• 主な新機能– サーバサイドコピー (Linux copy_range(2))– I/Oアドバイス– 穴あきファイル– Labeled NFS (SELinuxラベルのサポート)• NFS v4.1と互換性あり (すべての新機能
はオプション)55

サーバサイドコピー• 従来• サーバサイドコピー– トラヒックの削減に効果大クライアントクライアントLinux systemcall
copy_file_range

COPY

元ファイル

新ファイル
サーバ

元ファイル

新ファイル
サーバ
56

サーバサイドコピー• サーバサイドコピー• サーバをまたいだコピーにも対応

クライアントクライアントCOPY

このプロトコルは
NFSv4.1以降でもよいし、それ以
外でもよい

元ファイル

新ファイル
サーバ

宛先側に
要求する

元ファイル

新ファイル

サーバ1

サーバ2
57

I/Oアドバイス• POSIX fadvise(2)相当– アプリケーションがfadvise(2)を発行、クライアントがサーバにIO_ADVISEを発行– SEQUENTIAL、
SEQUENTIAL_BACKWORDS、RANDOM、WILLNEED、DONTNEED、NOREUSEなど

58

穴あきファイル
• 連続した0と「穴」を区別できる
READ_PLUSとWRITE_PLUSを追加– 区別できなくてもよい (READ、WRITEと同じ)– 特定の (アプリケーションが指定した) パター
ンで初期化することも可能 (Application Data
Hole)

• 領域の予約が可能

59

Linuxでの実装状況 (クライアント)
2.6.30 NFSv4.1のコード統合
NFSv4.1のコードにあった「開発者限定」のコメ
2.6.36
ント削除
3.7

NFSv4.1が「実験的」扱いではなくなる

3.10

NFSv4.2のコード統合 (実際にはLabeled NFSのみ)
60

Linuxでの実装状況 (サーバ)
2.6.26

NFSv4のminorversionが0でない要求をはじくよ
うになる

2.6.30 NFSv4.1のコード統合
3.8
3.10

NFSv4.1を含むNFSv4が「実験的」扱いではなくなるNFSv4.2のコード統合 (実際には新機能は追加されていない)3.11

NFSv4.1のサポートが既定で有効に

3.19

NFSv4.2のサポートが既定で有効に61

使い方 (クライアント)• 機能が有効かどうかを直接知る方法はな
いので…
# grep NFS_V4_1 /boot/config-`uname –r`
CONFIG_NFS_V4_1=y# mount –t nfs –o vers=4,minorversion=1 sv:/fs/fs# mount | tail -1
sv:/fs on /fs type nfs(rw,vers=4,minorversion=1,
addr=xxx.xxx.xxx.xxx,clientaddr=xxx.xxx.xxx.xx
x)
#

62

使い方 (サーバ)• 既定では無効かもしれない# cat /proc/fs/nfsd/versions+2 +3 +4 -4.1
# echo +4.1 >/proc/fs/nfsd/versions-bash: echo: write error: Device or resource
busy# service nfs stop(略)
# echo +4.1 >/proc/fs/nfsd/versions# cat /proc/fs/nfsd/versions+2 +3 +4 +4.1
Ubuntuではサービス名はnfs# service nfs startkernel-server(略)stopで/proc/fs/nfsdがumountされてしまうので手でmountする
63

Red Hat Enterprise Linuxでのサポート状況

6.0

mount –o vers=4,minorversion=1ができる (サポート状況は不明)
このときセッションが使われる/proc/fs/nfsd/versionsに「-4.1」の文字有効にすることも可能 (サポート状況は不明)
6.2

クライアントのpNFSのうち、ファイル・レイアウトがtechnology previewに

6.4

クライアントのファイル・レイアウトのpNFSをサポート

7

クライアントのpNFSのうち、ブロック・レイアウトをサポート
サーバの4.1サポートが既定で有効に

7.3

クライアントのpNFSのうち、SCSI (オブジェクト) レイアウト
がtechnology previewに
サーバの4.2サポートが既定で有効に64