分散システム 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/dsys-2005/2006-01-31
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/
NFS ( Network File System ) は, Sun Microsystems 社が 開発したネットワーク・ファイル・システムの名前(固有名詞, 商標)。
その他のネットワーク・ファイル・システム
NFSを使うと, ネットワークを通じて別のコンピュータ上のファイルシステム
の一部分を, ローカルディスク上にあるファイルシステムと同じように, 自分
のファイルシステムの木に
マウント(mount)
できる。
図? NFSによるファイルの共有
相互に参照し合える。
nfsd
というプログラムが
動いているように見える(
ps
コマンドで表示される)
が、それは普通のプロセスではない。
/usr/include/rpcsvc/nfs_prot.x
表? NFSで使われているRPCの手続き
手続き名 | 意味 | 関連するコマンド、システムコール |
---|---|---|
null() | 何もしない | rpcinfo -u hostname nfs コマンド |
getattr() | 属性の読み出し | ls -l コマンド, stat システムコール , open システムコール |
setattr() | 属性の設定 | chmod , chown コマンド |
lookup() | ファイルの検索 | open システムコール |
readlink() | シンボリックリンクの読み出し | ls -l コマンド, readlink システムコール |
read() | ファイルの読み出し | read システムコール |
write() | ファイルの書き込み | write システムコール |
create() | ファイルの作成 | creat システムコール, open システムコール |
remove() | ハードリンクの削除 | rm コマンド, unlink システムコール |
rename() | ファイル名前の変更 | mv コマンド, rename システムコール |
link() | ハードリンクの作成 | ln コマンド, link システムコール |
symlink() | シンボリックリンクの作成 | ln -s コマンド, symlink システムコール |
mkdir() | ディレクトリの作成 | mkdir コマンド |
rmdir() | ディレクトリの削除 | rmdir コマンド |
readdir() | ディレクトリの読み出し | ls コマンド |
statfs() | ファイルシステムの利用状況 | df コマンド, statfs システムコール |
commit()* | ディスクへの書き込み | fsync システムコール |
access()* | アクセス権のチェック | access システムコール |
NFS でファイルやディレクトリを区別するための識別子。32バイト。
const NFS_FHSIZE = 32; ... /* * File access handle */ struct nfs_fh { opaque data[NFS_FHSIZE]; };
一番最初のNFSファイル・ハンドルをどうやって入手するか。
手続き名 | 意味 | 関連するコマンド、 システムコール |
---|---|---|
null() | 何もしない | rpcinfo -u hostname mount コマンド |
mnt() | NFSファイルハンドルを返す | mount コマンド |
dump() | マウント一覧表 | showmount hostname コマンド |
umnt() | アンマウント | umount コマンド |
umntall() | 全アンマウント | umount -h hostname コマンド |
export() | アクセス可能なディレクトリのリストを返す |
2.2.5. Look Up File Name diropres NFSPROC_LOOKUP(diropargs) = 4; If the reply "status" is NFS_OK, then the reply "file" and reply "attributes" are the file handle and attributes for the file "name" in the directory given by "dir" in the argument. 2.3.10. diropargs struct diropargs { fhandle dir; filename name; }; The "diropargs" structure is used in directory operations. The "fhandle" "dir" is the directory in which to find the file "name". A directory operation is one in which the directory is affected. 2.3.11. diropres union diropres switch (stat status) { case NFS_OK: struct { fhandle file; fattr attributes; } diropok; default: void; }; The results of a directory operation are returned in a "diropres" structure. If the call succeeded, a new file handle "file" and the "attributes" associated with that file are returned along with the "status".
2.2.7. Read From File struct readargs { fhandle file; unsigned offset; unsigned count; unsigned totalcount; }; union readres switch (stat status) { case NFS_OK: fattr attributes; nfsdata data; default: void; }; readres NFSPROC_READ(readargs) = 6; Returns up to "count" bytes of "data" from the file given by "file", starting at "offset" bytes from the beginning of the file. The first byte of the file is at offset zero. The file attributes after the read takes place are returned in "attributes". Notes: The argument "totalcount" is unused, and is removed in the next protocol revision.
2.2.9. Write to File struct writeargs { fhandle file; unsigned beginoffset; unsigned offset; unsigned totalcount; nfsdata data; }; attrstat NFSPROC_WRITE(writeargs) = 8; Writes "data" beginning "offset" bytes from the beginning of "file". The first byte of the file is at offset zero. If the reply "status" is NFS_OK, then the reply "attributes" contains the attributes of the file after the write has completed. The write operation is atomic. Data from this "WRITE" will not be mixed with data from another client's "WRITE". Notes: The arguments "beginoffset" and "totalcount" are ignored and are removed in the next protocol revision.
2.2.2. Get File Attributes attrstat NFSPROC_GETATTR (fhandle) = 1; If the reply status is NFS_OK, then the reply attributes contains the attributes for the file given by the input fhandle. 2.3.9. attrstat union attrstat switch (stat status) { case NFS_OK: fattr attributes; default: void; }; The "attrstat" structure is a common procedure result. It contains a "status" and, if the call succeeded, it also contains the attributes of the file on which the operation was done. 2.3.5. fattr struct fattr { ftype type; unsigned int mode; unsigned int nlink; unsigned int uid; unsigned int gid; unsigned int size; unsigned int blocksize; unsigned int rdev; unsigned int blocks; unsigned int fsid; unsigned int fileid; timeval atime; timeval mtime; timeval ctime; }; ... Notes: The bits are the same as the mode bits returned by the stat(2) system call in UNIX. The file type is specified both in the mode bits and in the file type. This is fixed in future versions. The "rdev" field in the attributes structure is an operating system specific device specifier. It will be removed and generalized in the next revision of the protocol.
例:
ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); ssize_t pread(int fd, void *buf, size_t count, off_t offset); ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
NFS Version 2は, サーバ側で状態を保持しない(state-less)。
操作を冪等にして、サーバを無状態にすると、障害に強くなる。
RPC のようにコネクションが作られない通信サービスを使う時に冪等や無状態 といった性質を実現する時に必要になる技術。
例:NFSでのディレクトリの読み込み手続き nfsproc_readdir() で、1回の RPC で全部のデータを返せないことが起きる。 ディレクトリのどの位置まで読み込んだかを 示す中間状態を クッキー(cookie) という形でクライアントに返す。
クライアントは、次の RPC の呼び出しで、 前回受けとった応答の中のクッキーを、サーバへの要求に含めて送す。
const NFS_COOKIESIZE = 4; typedef opaque nfscookie[NFS_COOKIESIZE];
2.2.17. Read From Directory struct readdirargs { fhandle dir; nfscookie cookie; unsigned count; }; struct entry { unsigned fileid; filename name; nfscookie cookie; entry *nextentry; }; union readdirres switch (stat status) { case NFS_OK: struct { entry *entries; bool eof; } readdirok; default: void; }; readdirres NFSPROC_READDIR (readdirargs) = 16; Returns a variable number of directory entries, with a total size of up to "count" bytes, from the directory given by "dir". If the returned value of "status" is NFS_OK, then it is followed by a variable number of "entry"s. Each "entry" contains a "fileid" which consists of a unique number to identify the file within a filesystem, the "name" of the file, and a "cookie" which is an opaque pointer to the next entry in the directory. The cookie is used in the next READDIR call to get more entries starting at a given point in the directory. The special cookie zero (all bits zero) can be used to get the entries starting at the beginning of the directory. The "fileid" field should be the same number as the "fileid" in the the attributes of the file. (See section "2.3.5. fattr" under "Basic Data Types".) The "eof" flag has a value of TRUE if there are no more entries in the directory.
nfsproc_readdir() で、1回目と2回目の RPC の間にディレクトリの内容が 更新された場合、どのような結果になるのか不明。
NFS非同期入出力デーモン
(
nfsiod (local NFS asynchronous I/O Daemon)
または
biod (asynchronous Block I/O Daemon)
)
は、NFSのクライアントホスト上で動き、NFSの非同期的な入出力を行う。
lockd
lockd
は、受け取った要求をサーバ上の lockd
に転送する。
サーバ・ホスト上の lockd
は、クライアントの lockd
から受け取っ
た要求をシステム・コールでカーネルに伝える。
statd
lockd
は、クライアント・ホスト上の statd
に問い合わせて、
クライアント・ホストがクラッシュしていないか調べる。
クライアント・ホストがクラッシュしたら、
そのクライアントから受け取っていたロック要求を解除する。
lockd
には、当初からかなりバグが多かった。
初期の statd
には、バッファ・オーバーフローのバグがあった。
commit()
という手続きが追加。
それまでに行われた書き込みをディスクに行うように指示できる。
昔の名前は、 SMB プロトコル。 Samba は、 CIFS/SMB を、Unix 系のオペレーティング・システムで実現したプログラム。
Samba の利用法
NIS(Network Information Service)
は、/etc/hosts
や /etc/passwd
などを管理
するための分散型名前サービス。
名前サービスとは、名前(ホスト名, ログイン名)から、何か別の値(アドレス, パスワードやホームディレクトリなど) へ変換する。 インターネットで使われている名前サービスは、DNS 。
NIS は、1つの閉じた組織で使われることを想定して設計されている。
NISは、かつて
YP(Yellow Pages)
と呼ばれてた。YPという商標が使われていたために、途中で名前が
変った。
しかし、コマンドの名前は、以前のまま
ypXXXX
になっている。
NISの主目的は、パスワード・ファイルの共有。
その他の共有できるファイル
passwd
ファイルや hosts
ファイルなど、
(NIS管理下の)すべてのホストで共有するファイルをNISの
マップ(map)
という。
NISでは、アクセスの高速化のために、
dbm
(または
ndbm
)
ライブラリを使って索引をつける。
例: /etc/passwd
から作られるマップ
passwd.byname
csh
の「~
」で
使われる。
getpwnam
ライブラリに対応。
passwd.byuid
ls -l
で使われる。
getpwuid
ライブラリに対応。
ファイル | マップ |
bootparams | bootparams |
ethers | ethers.{byaddr,byname} |
group | group.{bygid,byname} |
hosts | hosts.{byaddr,byname} |
aliases | mail.{aliases,byaddr} |
netgroup | netgroup |
netmasks | netmasks.byaddr |
networks | networks.{byaddr,byname} |
passwd | passwd.{byname,byuid} |
protocols | protocols.{byname,bynumber} |
publickey | publickey.byname |
rpc | rpc.bynumber |
services | services.byname |
passwd,hosts,group | netid.byname |
なし | ypservers |
NISのマップの集合を共有するホストの集合を、
NISの
ドメイン(domain)
という。
インターネットの DNS でいうドメインとは、別の概念。
domainmame
コマンドを使って調べたり、設定できる。
ypserv
)RPC のサーバ。索引付けされたマップを管理する。
NISのサーバプロセスが走るホストの分類
ypclnt
)
NISクライアントライブラリ(ypclnt
)は, NISサーバに
RPCを行い、NISのマップを参照する。
例
getservbyname
(get service entry by service name) ライブラリ関数。
NISの services
マップを参照。
getpwent
(get password file entry)
ライブラリ関数。
passwd.byname マップを参照。
ypbind
)
バインドプロセス(ypbind
)は、NISクライアントライブラリを
利用するホスト上で動作し、どのNISサーバを使うのかを決定するためのプロ
セス。
サーバを探す時には、
放送(broadcast)
を使って、NISのサーバプロセスが走っているかを調べ、一番先
に応答したサーバプロセスのホストを
/var/yp/ドメイン名.N
というファイルに記録する。
NISのサーバプロセスがクラッシュしたり、負荷が高くなった時には、 バインドプロセスは、再び放送を使って別のNISサーバを探す。
マスタ・サーバのホストでマップが更新されたときに、 スレーブ・サーバにマップをコピーするためのコマンド。
例:すべてのスレーブサーバに passwd.byname
マップをコピーする。
# yppush passwd.byname
マスタサーバ上の /etc/
の下のファイルの日付と、対応する
マップの最終更新時刻を調べてマップを作り直す。 yppush
コ
マンドを使ってスレーブサーバに転送する。
makedbm
コマンドは, /etc/
の下のファイルから, 索引つきのファイ
ルを作るコマンド。
ypxfr
コマンドは、NISのスレーブサーバで、マスタサーバか
らNISのマップをコピーする時に使う。
起動方法
yppasswdd
(YP passwd daemon) は,
yp
)passwd
コマンド
と通信を行い、マスタサーバ上の /etc/passwd
を変更する。
ypwhich
コマンドは, 現在利用しているNISサーバのホスト名を表示する。
ypset
コマンドは、ypbind
に働きかけ、
利用するNISのサーバを強制的に変更する。
パスワードファイルのすり替えに使えるので、 一般ユーザからの要求は受け付けない。
NISでは, ypbind
で
放送(broadcast)
を使ってサーバを探すので、放送が届く範囲に, NISのサーバを置く必要がある。
typedef string domainname<YPMAXDOMAIN>; typedef string mapname<YPMAXMAP>; typedef string peername<YPMAXPEER>; typedef opaque keydat<YPMAXRECORD>; typedef opaque valdat<YPMAXRECORD>; enum ypstat { YP_TRUE = 1, YP_NOMORE = 2, YP_FALSE = 0, YP_NOMAP = -1, YP_NODOM = -2, YP_NOKEY = -3, YP_BADOP = -4, YP_BADDB = -5, YP_YPERR = -6, YP_BADARGS = -7, YP_VERS = -8 }; struct ypreq_key { domainname domain; mapname map; keydat key; }; struct ypresp_val { ypstat stat; valdat val; }; /* * YP access protocol */ program YPPROG { version YPVERS { void YPPROC_NULL(void) = 0; bool YPPROC_DOMAIN(domainname) = 1; bool YPPROC_DOMAIN_NONACK(domainname) = 2; ypresp_val YPPROC_MATCH(ypreq_key) = 3; ypresp_key_val YPPROC_FIRST(ypreq_key) = 4; ypresp_key_val YPPROC_NEXT(ypreq_key) = 5; ypresp_xfr YPPROC_XFR(ypreq_xfr) = 6; void YPPROC_CLEAR(void) = 7; ypresp_all YPPROC_ALL(ypreq_nokey) = 8; ypresp_master YPPROC_MASTER(ypreq_nokey) = 9; ypresp_order YPPROC_ORDER(ypreq_nokey) = 10; ypresp_maplist YPPROC_MAPLIST(domainname) = 11; } = 2; } = 100004;