요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
==========
NFS Client
==========
The NFS client
==============
The NFS version 2 protocol was first documented in RFC1094 (March 1989).
Since then two more major releases of NFS have been published, with NFSv3
being documented in RFC1813 (June 1995), and NFSv4 in RFC3530 (April
2003).
The Linux NFS client currently supports all the above published versions,
and work is in progress on adding support for minor version 1 of the NFSv4
protocol.
The purpose of this document is to provide information on some of the
special features of the NFS client that can be configured by system
administrators.
The nfs4_unique_id parameter
============================
NFSv4 requires clients to identify themselves to servers with a unique
string. File open and lock state shared between one client and one server
is associated with this identity. To support robust NFSv4 state recovery
and transparent state migration, this identity string must not change
across client reboots.
Without any other intervention, the Linux client uses a string that contains
the local system's node name. System administrators, however, often do not
take care to ensure that node names are fully qualified and do not change
over the lifetime of a client system. Node names can have other
administrative requirements that require particular behavior that does not
work well as part of an nfs_client_id4 string.
The nfs.nfs4_unique_id boot parameter specifies a unique string that can be
used together with a system's node name when an NFS client identifies itself to
a server. Thus, if the system's node name is not unique, its
nfs.nfs4_unique_id can help prevent collisions with other clients.
The nfs.nfs4_unique_id string is typically a UUID, though it can contain
anything that is believed to be unique across all NFS clients. An
nfs4_unique_id string should be chosen when a client system is installed,
just as a system's root file system gets a fresh UUID in its label at
install time.
The string should remain fixed for the lifetime of the client. It can be
changed safely if care is taken that the client shuts down cleanly and all
outstanding NFSv4 state has expired, to prevent loss of NFSv4 state.
This string can be stored in an NFS client's grub.conf, or it can be provided
via a net boot facility such as PXE. It may also be specified as an nfs.ko
module parameter.
This uniquifier string will be the same for all NFS clients running in
containers unless it is overridden by a value written to
/sys/fs/nfs/net/nfs_client/identifier which will be local to the network
namespace of the process which writes.
The DNS resolver
================
NFSv4 allows for one server to refer the NFS client to data that has been
migrated onto another server by means of the special "fs_locations"
attribute. See `RFC3530 Section 6: Filesystem Migration and Replication`_ and
`Implementation Guide for Referrals in NFSv4`_.
.. _RFC3530 Section 6\: Filesystem Migration and Replication: https://tools.ietf.org/html/rfc3530#section-6
.. _Implementation Guide for Referrals in NFSv4: https://tools.ietf.org/html/draft-ietf-nfsv4-referrals-00
The fs_locations information can take the form of either an ip address and
a path, or a DNS hostname and a path. The latter requires the NFS client to
do a DNS lookup in order to mount the new volume, and hence the need for an
upcall to allow userland to provide this service.
Assuming that the user has the 'rpc_pipefs' filesystem mounted in the usual
/var/lib/nfs/rpc_pipefs, the upcall consists of the following steps:
(1) The process checks the dns_resolve cache to see if it contains a
valid entry. If so, it returns that entry and exits.
(2) If no valid entry exists, the helper script '/sbin/nfs_cache_getent'
(may be changed using the 'nfs.cache_getent' kernel boot parameter)
is run, with two arguments:
- the cache name, "dns_resolve"
- the hostname to resolve
(3) After looking up the corresponding ip address, the helper script
writes the result into the rpc_pipefs pseudo-file
'/var/lib/nfs/rpc_pipefs/cache/dns_resolve/channel'
in the following (text) format:
"<ip address> <hostname> <ttl>\n"
Where <ip address> is in the usual IPv4 (123.456.78.90) or IPv6
(ffee:ddcc:bbaa:9988:7766:5544:3322:1100, ffee::1100, ...) format.
<hostname> is identical to the second argument of the helper
script, and <ttl> is the 'time to live' of this cache entry (in
units of seconds).
.. note::
If <ip address> is invalid, say the string "0", then a negative
entry is created, which will cause the kernel to treat the hostname
as having no valid DNS translation.
A basic sample /sbin/nfs_cache_getent
=====================================
.. code-block:: sh
#!/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}
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
NFS client 개요
1-20NFS version 2 protocol은 RFC1094(1989년 3월)에 처음 문서화됐습니다. 이후 NFSv3는 RFC1813(1995년 6월), NFSv4는 RFC3530(2003년 4월)에 문서화됐습니다.
Linux NFS client는 이 공개 version을 모두 지원하며 NFSv4 minor version 1 지원도 추가 중입니다. 이 문서는 system administrator가 구성할 수 있는 NFS client의 특수 기능을 설명합니다.
`nfs4_unique_id` parameter
21-60NFSv4 client는 server에 자신을 unique string으로 식별해야 합니다. 한 client와 server 사이의 file open·lock state는 이 identity와 연결됩니다. 견고한 NFSv4 state recovery와 투명한 state migration을 위해 identity string은 client reboot 뒤에도 바뀌면 안 됩니다.
별도 설정이 없으면 Linux client는 local system의 node name을 포함한 string을 사용합니다. 그러나 node name은 fully qualified가 아니거나 client 수명 중 바뀔 수 있고, 다른 관리 요구 때문에 `nfs_client_id4`에 적합하지 않을 수 있습니다.
`nfs.nfs4_unique_id` boot parameter는 NFS client가 server에 자신을 식별할 때 node name과 함께 사용할 unique string을 지정합니다. Node name이 unique하지 않다면 이 값이 다른 client와의 collision을 막는 데 도움이 됩니다.
값은 보통 UUID이지만 모든 NFS client에서 unique하다고 판단되는 어떤 string도 사용할 수 있습니다. Root filesystem이 설치 때 새 UUID label을 받듯 client 설치 시 `nfs4_unique_id`를 선택하고 client 수명 동안 고정해야 합니다.
Client가 clean shutdown되고 outstanding NFSv4 state가 모두 expire됐음을 보장하면 state loss 없이 안전하게 바꿀 수 있습니다. 값은 `grub.conf`, PXE 같은 net boot facility, 또는 `nfs.ko` module parameter로 제공할 수 있습니다.
Container의 모든 NFS client는 기본적으로 같은 uniquifier string을 사용합니다. 이를 바꾸려면 쓰는 process의 network namespace에 local인 `/sys/fs/nfs/net/nfs_client/identifier`에 값을 기록합니다.
DNS resolver와 referral
61-78NFSv4 server는 특별한 `fs_locations` attribute를 사용해 다른 server로 migrate된 data를 client에 referral할 수 있습니다. 자세한 규격과 구현 지침은 다음 문서를 참고합니다.
- RFC3530 Section 6: Filesystem Migration and Replication
https://tools.ietf.org/html/rfc3530#section-6 - Implementation Guide for Referrals in NFSv4
https://tools.ietf.org/html/draft-ietf-nfsv4-referrals-00
`fs_locations`는 IP address와 path 또는 DNS hostname과 path 형식입니다. Hostname 형식으로 새 volume을 mount하려면 NFS client가 DNS lookup을 해야 하므로 userspace가 서비스를 제공하는 upcall이 필요합니다.
DNS upcall 절차
79-111`rpc_pipefs`가 일반적인 `/var/lib/nfs/rpc_pipefs`에 mount됐다고 가정하면 upcall은 다음 순서로 진행됩니다.
| 단계 | 동작 |
|---|---|
| 1. Cache 확인 | `dns_resolve` cache에 유효한 entry가 있으면 반환하고 종료합니다. |
| 2. Helper 실행 | 유효한 entry가 없으면 `/sbin/nfs_cache_getent`를 cache name `dns_resolve`와 resolve할 hostname 인자로 실행합니다. Helper 경로는 `nfs.cache_getent` boot parameter로 바꿀 수 있습니다. |
| 3. 결과 기록 | 조회한 IP address, hostname, TTL을 `/var/lib/nfs/rpc_pipefs/cache/dns_resolve/channel`에 기록합니다. |
Channel에 쓰는 text format은 다음과 같습니다.
"<ip address> <hostname> <ttl>\n"
`<ip address>`는 IPv4 `123.456.78.90` 또는 IPv6 `ffee:ddcc:bbaa:9988:7766:5544:3322:1100`, `ffee::1100` 같은 일반 형식입니다. `<hostname>`은 helper의 두 번째 인자와 동일하고, `<ttl>`은 cache entry의 time to live를 초 단위로 나타냅니다.
`<ip address>`가 문자열 `0`처럼 유효하지 않으면 negative entry가 생성되고 kernel은 해당 hostname에 유효한 DNS translation이 없다고 처리합니다.
`/sbin/nfs_cache_getent` 기본 예제
112-144다음 shell script는 600초 TTL을 사용하고 `getent hosts`의 첫 field를 추출합니다. 조회 실패 시 결과를 `0`으로 만들고 선택한 cache channel에 `result name ttl`을 기록합니다.
#!/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}
관리 핵심
nfs-client.rst:1-144NFSv4의 state recovery는 reboot 후에도 고정된 client identity에 의존하며, server referral의 hostname은 `rpc_pipefs`와 userspace helper를 통해 resolve합니다.