Chapter 11
The Network File System


D.M.Z CONTENT PRE NEXT

11.1 Preparing NFS
11.2 Mounting an NFS Volume
11.3 The NFS Daemons
11.4 The exports File
11.5 The Linux Automounter

NFS, 즉 network filesystem은 RPC를 사용하는 네트웍 서비스들 중 가장 두각을 나타내는 것이다. 그것은 리모트 호스트 상의 파일을 유저가 마치 로컬 파일에 억세스 하듯이 억세스 할 수 있게 한다. 이는 (리모트 파일 시스템을 사용하는) 클라이언트 측의 커널 기능과 서버측(데이터를 제공하는)의 NFS 서버의 혼합으로 가능한 것이다. 이 파일 억세스는 클라이언트에 있어 완전히 투명한 것이고, 다양한 서버와 호스트 아키텍쳐에서 동작한다.

NFS는 몇가지 이점을 제공한다.

  • 모든 유저가 억세스할 수 있는 데이터는 중앙 호스트에 보존되고, 클라이언트는 부팅시에 이를 마운트한다. 예를 들어, 모든 유저 계정을 한 호스트에 놓아두고 네트웍 상의 모든 호스트가 /home을 그 호스트에서 마운트한다. 만약 NIS와 함께 사용할 경우, 유저는 어느 시스템에서 로그인 하건 동일한 파일 셋을 갖고 작업할 수 있다.

  • 많은 양의 디스크 공간을 소비하는 데이터를 단일 호스트에 보존할 수 있다. 예를 들어, LaTeX와 METAFONT에 관련된 모든 파일을 한 장소에 보존·유지할 수 있다.

  • 관리적인 용도의 데이터를 단일 호스트에 보존할 수 있다. 20개의 다른 머신에 쓸데없는 파일을 설치하기 위해 rcp를 사용할 필요가 없다.

리눅스 NFS는 많은 면에서 Rick Sladkey가 노력한 결과라 할 수 있다. 그는 NFS 커널 소스와 NFS 서버의 많은 부분을 썼는데, 후자는 원래 Mark Shand가 쓴 unfsd user-space NFS 서버와 Donald Becker가 쓴 hnfs Harris NFS서버에서 유래한 것이다.

이제 어떻게 NFS가 동작하는지 살펴보자. 클라이언트는 리모트 호스트에서 디렉토리를 로컬 디렉토리상에, 마치 물리적인 디바이스를 마운트하듯이, 마운트 요청을 할 수 있다. 그러나, 리모트 디렉토리를 지정하는데 사용되는 systax는 다르다. 예를 들어, 호스트 vlager/homevale/users로 마운트하기 위해, 관리자는 vale에서 다음의 커맨드를 사용한다.

     # mount -t nfs vlager:/home /users

그러면 mount는 RPC를 사용하여 vlagermountd 마운트 데몬에 연결한다. 서버는 vale이 요청한 디렉토리를 마운트하도록 허용되어 있는제 체크하고, 만약 그렇다면 파일 핸들(file handle)을 리턴해 준다. 이 파일 핸들은 이후 /users아래의 파일을 요청할 때 사용된다.

어떤이가 NFS를 통해 파일에 억세스할 때, 커널은 서버머신의 nfsd(NFS daemon)게 RPC 콜을 보낸다. 이 콜은 파일 핸들과 억세스할 파일 이름, 그리고 유저의 uid와 gid를 파라미터로 얻어온다. 이들은 지정된 파일에 접근권한을 결정한다. 인증받지 못한 유저가 파일을 읽고 변경하지 못하도록 하기 위해 유저와 그룹 id는 양 호스트상에 동일해야 한다.

대부분의 UN*X에서, 클라이언트와 서버 양쪽의 NFS 기능은, 시스템 부트시에 user space에서 시작되는 커널 레벨 데몬으로서 실행된다. 이들은 서버 호스트 상의 NFS 데몬과 클라이언트 호스트 상에서 돌아가는 Block I/O Daemon(biod)이다. 처리량을 향상시키기 위해서, biod는 read-ahead와 write-behind를 사용하는 비 동기적인 I/O를 수행한다; 보통 몇몇 nfsd 데몬도 이와 동일하게 돌아간다.

리눅스의 NFS implementation은 클라이언트의 코드가 커널의 가상 파일 시스템(VFS) 레이어 내에 견고하게 통합되어 있고 biod를 통한 부수적인 통제를 요하지 않는 면에서 약간 틀리다. 반면에, 서버 코드는 완전히 user space 내에서 돌아가므로, 동시에 여러개의 서버의 복제본이 돌아가는 일은, 이것이 의미하는 동기화 문제 때문에 거의 불가능한 것이다. 현재의 리눅스 NFS 역시 read-ahead와 write-behind가 결여되어 있으나, Rick Sladkey는 언젠가 이를 추가할 계획이다.

리눅스 NFS 코드가 안고 있는 가장 큰 문제점은 버전 1.0의 리눅스 커널이 4K 이상의 메모리 영역을 allocate할 수 없다는 것으로, 따라서 네트워킹 코드는 헤더 사이즈 등을 빼고 나면 대략 3500 바이트 이상의 데이터 그램을 다룰 수 없다. 이것이 의미하는 바는, 디폴트로 큰 UDP 데이터 그램을 사용하는 시스템 상의(예 SunOS의 8K) NFS 데몬과의 전송은 인위적으로 다운 사이징되어야 한다. 이것은 몇가지 상황하에서 퍼포먼스를 떨어뜨리는데, 이러한 제한은 Linux-1.1이후의 커널에서 사라졌으며, 클라이언트 코드는 이러한 잇점을 받아들이도록 수정되었다.


Preparing NFS

서버로써건 클라이언트로써건 NFS를 사용하기 전에, 반드시 커널이 NFS를 지원하도록 컴파일 되어 있는지 확인해야한다. 보다 새로운 커널은 이를 위해 proc 파일 시스템상에 단순한 인터페이스, 즉 /proc/filesystems 파일을 갖고 일는데, 이는 cat으로 살펴볼 수 있다.

     $ cat /proc/filesystems
     minix
     ext2
     msdos
     nodev proc
     nodev nfs

만약 nfs가 이 목록에서 제외되어 있다면, 커널을 NFS가 지원되도록 컴파일 해 주어야 한다. 커널 네트웍 옵션을 설정하는 것은 chapter 3의 "Kernel Configuration" 섹션에서 설명한 바 있다.

Linux 1.1 이전의 커널에서, 당신의 커널이 NFS 지원이 가능한지를 찾아보는 가장 단순한 방법은 실제로 NFS 파일 시스템을 마운트해 오는 것이다. 이를 위해선 /tmp밑에 디렉토리를 하나 만들고 로컬 디렉토리 하나를 그것에 마운트해 보라.

     # mkdir /tmp/test
     # mount localhost:/etc /tmp/test

만약 이러한 시도가 "fs type nfs no supported by kernel"이라는 에러메시지와 함께 실패한다면, 당신은 NFS가 가능한 새 커널을 만들어야 한다. 다른 에러 메시지는 전혀 해롭지 않은 것이며, 당신 호스트에 아직 NFS 데몬을 설정하지 않아서 나는 것들이다.


11.2 Mounting an NFS Volume

NFS 볼륨을 마운트하는 방법은 보통 파일 시스템을 마운트하는 것과 비슷하다. 다음과 같이 mount를 실행한다.

     # mount -t nfs nfs_volume local_dir options

nfs_volumeremote_host:remote_dir의 형식으로 준다. 이러한 표기법이 NFS 파일 시스템에만 있는 것이므로, -t nfs 옵션은 생략할 수도 있다.

NFS 볼륨을 마운팅할 때 mount에 지정해 줄 수 있는 추가적은 옵션들이 몇가지 있는데, 이들은 커맨드라인에서 -o 스위치 뒤에 주거나, 그 볼륨에 대한 /etc/fstab 엔트리의 옵션 필드에 줄 수 있다. 양쪽 모두, 옵션을 두 개 이상 줄 때엔 쉼표로 나누어 준다. 커맨드라인에서 지정해 준 옵션은, fstab 파일에서 준 옵션을 항상 override한다.

다음은 /etc/fstab 엔트리의 예이다.

     # volume               mount point        type    options
     news:/usr/spool/news   /usr/spool/news    nfs     timeo=14,intr

이 볼륨은 다음을 사용하여 마운트 된다.

     # mount news:/usr/spool/news

fstab의 엔트리가 없을 경우, NFS mount의 커맨드라인은 좀더 지저분해 진다. 예를 들어, 당신의 유저 홈 디렉토리를 moonshot이르는 머신에서 마운트하고자 하고, 그 머신이 읽기/쓰기 작업에 4K의 디폴트 블록 사이즈를 사용한다고 가정해보자. 당신은 리눅스의 데이터 그램사이즈 제한에 맞게끔 다음과 같이 블록 사이즈를 줄여주어야 한다.

     # mount moonshot:/home /home -o rsize=2048, wsize=2048

적절한 모든 옵션은 Rik Faith의 util-linux패키지에 있는 Rick Sladkey의 NFS-awae mount 툴에 딸려오는 nfs(5) 매뉴얼 페이지내에 적혀있다. 다음은 당신이 사용할 만한, 일부만의 리스트이다.

rsize=nwsize=n
이것은 읽기와 쓰기 요구에 NFS 클라이언트가 사용하는 데이터그램 사이즈글 지정한다. 현재 디폴트는 위에 기슬한 UDP 데이터그램 사이즈의 제약 때문에 1024바이트이다.
timeo=n 이것은 NFS클라이언트가 request를 기다리는 시간을 (1/10초 단위로) 지정한다. 디폴트 값은 0.7초이다.
hard 이 볼륨이 hard-mount되었음을 독점적으로 표시한다. 이것은 디폴트로 켜져있다.
soft 그 드라이버를 soft-mount한다. (hard-mount의 반대)
intr NFS 콜을 인터럽트하기위한 시그널을 허용한다. 서버가 응답하지 않을 때, 종료하는데 유용하다.

rsizewsize를 제외한 이들 모든 옵션들은 서버가 일시적으로 억세스 할 수 없게 되었을 때 클라이언트의 동작에 적용되는 것이다. 그것들은 다음의 방법으로 함께 작동한다: 클라이언트가 NFS 서버에 request를 보낼 때마다, 그것은 주어진 기간 경과 후(timeout옵션으로 지정된), 작업이 완료되었을 것이라 기대한다. 만약 이 시간 동안 어떠한 확인 응답(confirmation)도 수신하지 못했다면, 즉 흔히 불리는 minor timeout이 일어나면, 두배의 타임아웃 인터벌을 주어 작업을 재시도 하게 한다. 60초의 최대 타임아웃에 이르게 되면 major timeout이 일어난다.

디폴트로 메이저 타임아웃은 클라이언트 콘솔에 메시지를 출력하고, 이전의 두배의 이니셜 타임아웃을 갖고 모든 것을 다시 시작하게 된다. 잠재적으로 이러한 것은 영구히 지속된다. 서버가 다시 제대로 동작할 때까지 끈질기게 재시도하는 볼륨을 hard-mount된 것이라 하고, 반대로 soft-mount된 볼륨은 메이저 타임아웃이 일어날 때 호출 프로세스에 대한 I/O에러를 발생시킨다. write-behind가 버퍼 캐쉬에의해 전해지기 때문에, 이 에러컨디션은 프로세스 자신이 다음번에 write(2) 함수를 호출하기 전에 그 프로세스에 전달되지 않는다. 그러므로 프로그램은 soft-mount된 볼륨에 대한 쓰기 작업이 성공했는지 전혀 확신하지 못한다.

볼륨을 hard 또는 soft-mount한다는 것은 단순히 취향의 문제뿐 아니라, 이 볼륨에서 어떤 종류의 정보를 억세스하는지도 고려해야한다. 예를 들어, 만약 NFS로 X 프로그램을 마운트한다면, 어떤 사람이 동시에 xv의 카피를 구동시킨다거나 이더넷 플러그를 잠시 빼둔다거나하여 네트웍에 무리를 가해, 당신의 X 세션이 미쳐날뛰게 하고 싶지 않을 것이다. 이를 hard-mount해서 NFS 서버와의 접속이 재 성립될 때 까지 대기하도록 만들었는지 확인한다. 반면, NFS로 마운트된 news 파티션 또는 FTP archive들 같이 별로 중요하지 않은 데이터는 soft-mount할 수 있다. 그리하여 리모트 머신이 일시적으로 unreachable또는 다운되었을 때, 세션을 종료하게 된다. 만약 서버로의 네트웍 연결이 엉성하거나 로드가 심한 라우터를 경유한다면, timeo 옵션으로 이니셜 타임아웃을 늘이거나 그 볼륨을 hard-mount해야하나, 미결된 파일 억세스를 처리할 수 있도록 NFS 콜을 인터럽트하는 시그널을 허용해야한다.

보통 mountd 데몬은 몇가지 방법으로 어떤 호스트에 의해 어떤 디렉토리가 마운트 되었는지의 정보를 유지한다. 이 정보는 NFS 서버 패키지에 포함되어 있는 showmount 프로그램을 사용하여 표시할 수 있다. 그러나 리눅스 mountd는 이러한 일을 아직 하지 못한다.


11.3 The NFS Daemons

만약 다른호스트에 NFS 서비스를 제공하고자 한다면, 머신에 nfsdmountd를 돌려야한다. RPC기반 프로그램이 그러하듯, 그것들은 inetd에의해 관리되지 않고 부트시에 구동되어 포트매퍼에 자신을 등록한다. 따라서, rpc.portmap이 구동된 이후에 그것들을 구동하였는지 확인해야한다. 보통 다음의 두 라인을 rc.inet2 스크립트에 넣는다.

     if [ -x /usr/sbin/rpc.mountd ]; then
            /usr/sbin/rpc.mountd; echo -n " mountd"
     fi
     if [ -x /usr/sbin/rpc.nfsd ]; then
            /usr/sbin/rpc.nfsd; echo -n " nfsd"
     fi

NFS 데몬이 클라이언트에 제공하는 파일의 소유권 정보는 보통 유저와 그룹 id번호만을 포함한다. 만약 클라이언트와 서버 양쪽 모두 이러한 id 번호로 된 동일한 유저와 그룹네임으로 연결되어 있다면, 이를 일컬어 uid/gid space를 공유한다고 말한다. 예를 들어, 이것은 당신이 LAN 상의 모든 호스트에 passwd정보를 배분하는데 NIS를 사용하는 경우에 해당된다 하겠다.

그러나 때때로 그것들이 일치하지 않는 경우도 있다. 이 때 클라이언트의 uid와 gid를 서버에 맞도록 업데이트하기 보다는, 이에 관해 동작하는 ugidd 매핑데몬을 사용하는 것이 좋다. 아래에 설명할 map_daemon 옵션을 사용하여 nfsd에게, 클라이언트의 도움을 받아 서버의 uid/gid space를 클라이언트의 uid/gid space로 맵하게 만들 수 있다.

ugidd는 RPC 기반 서버중의 하나이며, nfsd, mountd와 마찬가지로 rc.inet2에서 구동된다.

     if [ -x /usr/sbin/rpc.ugidd ]; then
            /usr/sbin/rpc.ugidd; echo -n " ugidd"
     fi


11.4 The exports File

위의 옵션이 클라이언트의 NFS 설정에 적용되는데 비해, 서버에서 클라이언트마다 동작을 설정하는 또다른 옵션셋도 존재한다. 이 옵션들은 반드시 /etc/exports파일에서 지정되어야 한다.

디폴트로 mountd는 그 누구도 로컬 호스트에서 디렉토리를 마운트 할 수 없도록 만드는데, 이는 다소 현명한 태도이다. 하나 또는 그 이상의 디렉토리를 NFS 마운트하기 위해서는 반드시 그 디렉토리가 export되어야 한다. 즉, exports파일에 지정되어야만 한다. 예제 파일은 다음과 같다.

     # export file for vlager
     /home             vale(rw) vstout(rw) vlight(rw)
     /usr/X386         vale(ro) vstout(ro) vlight(ro)
     /usr/TeX          vale(ro) vstout(ro) vlight(ro)
     /                 vale(rw, no_root_squash)
     /home/ftp         (ro)

각 라인은 디렉토리와 그것을 마운트하도록 허용된 호스트를 정의한다. 호스트 네임은 보통 FQDN으로 주어지나, 추가적으로 *? 와일드카드를 포함할 수 있으며, 이는 Bourne shell과 같은 방법으로 동작한다. 예를 들어, lab*.foo.comlab01.foo.com이나 laber.foo.com에도 일치한다. 만약 위의 /home/ftp 디렉토리퍼럼 호스트 네임이 주어지지 않으면 어떠한 호스트에서도 이 디렉토리를 마운트할 수 있다.

export 파일에서 클라이언트 호스트를 체크할 때 mountdgethostbyaddr(2) 콜을 사용하여 클아이언트의 호스트에임을 찾는다. DNS를 사용할 때, 이 콜은 클라이언트의 canonical 호스트네임을 반환하므로 exports 파일내에 앨리어스를 사용하지 않았는지 확인해야한다. DNS를 사용하지 않을 경우엔 hosts파일에서 클라이언트의 주소에 맞는 가장 먼저 발견된 호스트네임이 반환된다.

호스트 네임 뒤엔 추가로 괄호안에 플래그를 줄 수도 있는데, 이들 플래그들이 여러개 쓰일경우엔 쉼표로 구분하며, 다음과 같은 것들이 쓰인다.

insecure 이 머신에서 인증 받지 않은 억세스를 허용한다.
unix-rpc 이 머신에서 UNIX-도메인 RPC 인증절차를 요구한다. 이것은 단순히 예약된 인터넷 포트에서 일어나는 request를 필요로한다. (즉, 포트번호는 1024 아래여야 한다.) 이 옵션은 디폴트로 켜져있다.
secure-rpc 이 머신에서 secure RPC 인증절차를 요구한다. 이것은 아직 수행되지 않는다. Secure RPC에 관한 Sun의 문서를 보라.
kerberos 이 머신에서의 억세스에 kerberos 인증절차를 요구한다. 이것 역시 아직 수행되지 않는다. Kerberos 인증 시스템에 관한 MIT의 문서를 보라
root_squash 이것은 클라이언트 호스트의 uid 0에서의 request를 서버의 uid 65534(-2)로 매핑함으로써, 지정된 호스트의 슈퍼 유저의 억세스를 거부하는 보안기능이다. uid 65534는 유저 nobody의 것이다.
no_root_squash
uid 0으로부터의 request를 매핑하지 않는다. 이것은 디폴트로 켜져있다.
ro 파일 계층을 읽기 전용(read-only)로 마운트한다. 이 옵션은 디폴트로 켜져 있다.
rw 파일 계층을 읽기 쓰기 가능(read-write)으로 마운트한다.
link_relative 절대 심볼릭 링크(링크의 내용이 슬래쉬로 시작하는)를, 링크를 포함하는 디렉토리에서 서버의 루트 디렉토리까지 필요한 수 만큼의 ../를 앞에 붙여 상대 링크로 변환한다. 이 옵션은 오직 호스트의 전체 파일 시스템을 마운트 할 때만 쓸만한 것이지, 그렇지 않을 경우 어떤 링크는 어느 곳도 지시하지 않을 수 있고, 심하면 가리키려 의도하지 않던 파일을 지시하는 수도 있다. 이 옵션은 디폴트로 켜져있다.
link_absolute 모든 심볼릭 링크를 그대로 놔둔다. (Sun에서 제공하는 NFS 서버에선 보통의 동작방식이다).
map_identity map_identity옵션은 클라이언트가 서버와 동일한 uid와 gid를 사용한다고 가정하라고 서버에게 말해준다. 이 옵션은 디폴트로 켜져 있다.
map_daemon 이 옵션은 NFS 서버에게 클라이언트와 서버가 동일한 uid/gid를 공유하지 않음을 가정하라고 말한다. 그러면 nfsd는 클라이언트의 ugidd 데몬에 쿼리하여 클라이언트와 서버간의 id를 매핑한 목록을 생성한다.

nfsdmountd가 구동되어 있다면, exports파일 파싱과정 중에 일어난 에러는 syslogddaemon기능에 notice 레벨로 보고된다.

호스트 네임은 클라이언트의 IP 주소에서 역 매핑을 통해 얻어진다는데 주의하자. 그러므로 당신은 resolver를 적절히 설정해 놓아야 한다. 만약 BIND를 사용하고, 보안에 관해 상당히 의식하고 있다면, 당신의 hosts.conf 파일에 spoof 체킹을 켜 두는 것이 좋다.


11.5 The Linux Automounter

유저가 가끔씩 억세스하길 원할 수도 있는 모든 볼륨을 마운트하는 것은, 마운트할 볼륨의 수가 많거나 구동시에 잡아 먹는 시간의 이유로, 낭비적일 수도 있다. 이에 활용할 수 있는 대안이 바로 automounter로, 이것은 자동적으로 필요한 모든 NFS 볼륨을 마운트하고 일정 시간동안 사용하지 않으면 언마운트해주는 데몬이다. automounter에서 뛰어난 점 한가지는 특정 볼륨을 다른 장소에서 마운트할 수 있다는 것으로, 예를들어 둘 또는 세 호스트에서 X 프로그램과 지원파일의 카피를 보존하고 다른 모든 호스트에서 NFS로 이를 마운트하게 한다. automounter를 사용하여 그 셋 모두가 /usr/X386에 마운트하도록 지정해 놓으면, automounter는 이들중 마운트 시도가 성공하는 하나를 마운트하려 할 것이다.

보통 리눅스에서 사용되는 automounter를 amd라 부른다. 그것은 원래 Jan-simon Pendry가 쓴 것이고 리눅스로의 포팅은 Rick Sladkey가 하였다. 현재 버전은 amd-5.3이다.

amd에 관해 설명하는 것은 이 장의 범위를 벗어난다. 좋은 매뉴얼을 원한다면 소스를 참고하라. 그것엔 자세한 정보를 담은 texinfo파일이 포함되어 있다.

Other Chapters

1. Introduction to Networking
2. Issues of TCP/IP Networking
3. Configuring the Networking Hardware
4. Setting up the Serial Hardware
5. Configuring TCP/IP Networking
6. Name Service and Resolver Configuration
7. Serial Line IP
8. The Point-to-Point Protocol
9. Various Network Applications
10. The Network Information System
11. The Network File System
12. Managing Taylor UUCP
13. Electronic Mail
14. Getting smail Up and Running
15. Sendmail+IDA
16. Netnews
17. C News
18. A Description of NNTP
19. Newsreader Configuration

Appendix

A. A Null Printer Cable for PLIP
B. Sample smail Configuration Files
C. The GNU General Public License