NFS: Add nfs4_unique_id boot parameter

An optional boot parameter is introduced to allow client
administrators to specify a string that the Linux NFS client can
insert into its nfs_client_id4 id string, to make it both more
globally unique, and to ensure that it doesn't change even if the
client's nodename changes.

If this boot parameter is not specified, the client's nodename is
used, as before.

Client installation procedures can create a unique string (typically,
a UUID) which remains unchanged during the lifetime of that client
instance.  This works just like creating a UUID for the label of the
system's root and boot volumes.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Chuck Lever 2012-09-14 17:24:41 -04:00 committed by Trond Myklebust
parent 05f4c350ee
commit 6f2ea7f2a3
5 changed files with 59 additions and 4 deletions

View File

@ -12,9 +12,47 @@ and work is in progress on adding support for minor version 1 of the NFSv4
protocol. protocol.
The purpose of this document is to provide information on some of the The purpose of this document is to provide information on some of the
upcall interfaces that are used in order to provide the NFS client with special features of the NFS client that can be configured by system
some of the information that it requires in order to fully comply with administrators.
the NFS spec.
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 instead of a system's node name when an NFS client identifies itself to
a server. Thus, if the system's node name is not unique, or it changes, its
nfs.nfs4_unique_id stays the same, preventing collision with other clients
or loss of state during NFS reboot recovery or transparent state migration.
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. Specifying a uniquifier string is not support for NFS
clients running in containers.
The DNS resolver The DNS resolver
================ ================

View File

@ -1719,6 +1719,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
will be autodetected by the client, and it will fall will be autodetected by the client, and it will fall
back to using the idmapper. back to using the idmapper.
To turn off this behaviour, set the value to '0'. To turn off this behaviour, set the value to '0'.
nfs.nfs4_unique_id=
[NFS4] Specify an additional fixed unique ident-
ification string that NFSv4 clients can insert into
their nfs_client_id4 string. This is typically a
UUID that is generated at system install time.
nfs.send_implementation_id = nfs.send_implementation_id =
[NFSv4.1] Send client implementation identification [NFSv4.1] Send client implementation identification

View File

@ -380,6 +380,9 @@ extern bool nfs4_disable_idmapping;
extern unsigned short max_session_slots; extern unsigned short max_session_slots;
extern unsigned short send_implementation_id; extern unsigned short send_implementation_id;
#define NFS4_CLIENT_ID_UNIQ_LEN (64)
extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN];
/* nfs4sysctl.c */ /* nfs4sysctl.c */
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
int nfs4_register_sysctl(void); int nfs4_register_sysctl(void);

View File

@ -4068,9 +4068,13 @@ static unsigned int
nfs4_init_uniform_client_string(const struct nfs_client *clp, nfs4_init_uniform_client_string(const struct nfs_client *clp,
char *buf, size_t len) char *buf, size_t len)
{ {
char *nodename = clp->cl_rpcclient->cl_nodename;
if (nfs4_client_id_uniquifier[0] != '\0')
nodename = nfs4_client_id_uniquifier;
return scnprintf(buf, len, "Linux NFSv%u.%u %s", return scnprintf(buf, len, "Linux NFSv%u.%u %s",
clp->rpc_ops->version, clp->cl_minorversion, clp->rpc_ops->version, clp->cl_minorversion,
clp->cl_rpcclient->cl_nodename); nodename);
} }
/** /**

View File

@ -2662,6 +2662,7 @@ unsigned int nfs_idmap_cache_timeout = 600;
bool nfs4_disable_idmapping = true; bool nfs4_disable_idmapping = true;
unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE; unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
unsigned short send_implementation_id = 1; unsigned short send_implementation_id = 1;
char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = "";
EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport); EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
EXPORT_SYMBOL_GPL(nfs_callback_tcpport); EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
@ -2669,6 +2670,7 @@ EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
EXPORT_SYMBOL_GPL(nfs4_disable_idmapping); EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
EXPORT_SYMBOL_GPL(max_session_slots); EXPORT_SYMBOL_GPL(max_session_slots);
EXPORT_SYMBOL_GPL(send_implementation_id); EXPORT_SYMBOL_GPL(send_implementation_id);
EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier);
#define NFS_CALLBACK_MAXPORTNR (65535U) #define NFS_CALLBACK_MAXPORTNR (65535U)
@ -2694,6 +2696,8 @@ static struct kernel_param_ops param_ops_portnr = {
module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
module_param(nfs_idmap_cache_timeout, int, 0644); module_param(nfs_idmap_cache_timeout, int, 0644);
module_param(nfs4_disable_idmapping, bool, 0644); module_param(nfs4_disable_idmapping, bool, 0644);
module_param_string(nfs4_unique_id, nfs4_client_id_uniquifier,
NFS4_CLIENT_ID_UNIQ_LEN, 0600);
MODULE_PARM_DESC(nfs4_disable_idmapping, MODULE_PARM_DESC(nfs4_disable_idmapping,
"Turn off NFSv4 idmapping when using 'sec=sys'"); "Turn off NFSv4 idmapping when using 'sec=sys'");
module_param(max_session_slots, ushort, 0644); module_param(max_session_slots, ushort, 0644);
@ -2702,6 +2706,7 @@ MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
module_param(send_implementation_id, ushort, 0644); module_param(send_implementation_id, ushort, 0644);
MODULE_PARM_DESC(send_implementation_id, MODULE_PARM_DESC(send_implementation_id,
"Send implementation ID with NFSv4.1 exchange_id"); "Send implementation ID with NFSv4.1 exchange_id");
MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
MODULE_ALIAS("nfs4"); MODULE_ALIAS("nfs4");
#endif /* CONFIG_NFS_V4 */ #endif /* CONFIG_NFS_V4 */