summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/nfsd/Makefile2
-rw-r--r--usr.sbin/nfsd/nfsd.836
-rw-r--r--usr.sbin/nfsd/nfsd.c133
-rw-r--r--usr.sbin/nfsd/nfsv4.4309
-rw-r--r--usr.sbin/nfsd/stablerestart.593
5 files changed, 544 insertions, 29 deletions
diff --git a/usr.sbin/nfsd/Makefile b/usr.sbin/nfsd/Makefile
index 21ca3f3..3237ce3 100644
--- a/usr.sbin/nfsd/Makefile
+++ b/usr.sbin/nfsd/Makefile
@@ -2,7 +2,7 @@
# $FreeBSD$
PROG= nfsd
-MAN= nfsd.8
+MAN= nfsd.8 nfsv4.4 stablerestart.5
WARNS?= 6
diff --git a/usr.sbin/nfsd/nfsd.8 b/usr.sbin/nfsd/nfsd.8
index 64c181e..3c2dcd4 100644
--- a/usr.sbin/nfsd/nfsd.8
+++ b/usr.sbin/nfsd/nfsd.8
@@ -38,7 +38,7 @@
server
.Sh SYNOPSIS
.Nm
-.Op Fl ardut
+.Op Fl ardut4
.Op Fl n Ar num_servers
.Op Fl h Ar bindip
.Sh DESCRIPTION
@@ -100,6 +100,18 @@ clients.
Serve
.Tn UDP NFS
clients.
+.It Fl 4
+Forces
+.Nm
+to try and start the experimental server that includes NFSv4 support in it.
+If this flag isn't specified, the experimental server will only be started
+if it is linked into the kernel and the regular one isn't.
+.br
+ie. The kernel is built with the following:
+.Bd -literal -offset indent -compact
+# options NFSSERVER
+options NFSD
+.Ed
.El
.Pp
For example,
@@ -120,8 +132,11 @@ utility listens for service requests at the port indicated in the
.Tn NFS
server specification; see
.%T "Network File System Protocol Specification" ,
-RFC1094 and
-.%T "NFS: Network File System Version 3 Protocol Specification" .
+RFC1094,
+.%T "NFS: Network File System Version 3 Protocol Specification" ,
+RFC1813 and
+.%T "Network File System (NFS) Version 4 Protocol" ,
+RFC3530.
.Pp
If
.Nm
@@ -178,13 +193,28 @@ just do a
.Xr nfsstat 1 ,
.Xr kldload 2 ,
.Xr nfssvc 2 ,
+.Xr nfsv4 4 ,
.Xr exports 5 ,
+.Xr gssd 8 ,
.Xr ipfw 8 ,
.Xr mountd 8 ,
.Xr nfsiod 8 ,
+.Xr nfsrevoke 8 ,
+.Xr nfsuserd 8 ,
.Xr rpcbind 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Bx 4.4 .
+.Sh BUGS
+If
+.Nm
+is started when
+.Xr gssd 8
+is not running, it will service AUTH_SYS requests only. To fix the problem
+you must kill
+.Nm
+and then restart it, after the
+.Xr gssd 8
+is running.
diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c
index 788d1c2..9afe62c 100644
--- a/usr.sbin/nfsd/nfsd.c
+++ b/usr.sbin/nfsd/nfsd.c
@@ -48,6 +48,7 @@ static const char rcsid[] =
#include <sys/syslog.h>
#include <sys/wait.h>
#include <sys/mount.h>
+#include <sys/fcntl.h>
#include <sys/linker.h>
#include <sys/module.h>
@@ -59,6 +60,7 @@ static const char rcsid[] =
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsserver/nfs.h>
+#include <nfs/nfssvc.h>
#include <err.h>
#include <errno.h>
@@ -77,11 +79,14 @@ int debug = 1;
int debug = 0;
#endif
+#define NFSD_STABLERESTART "/var/db/nfs-stablerestart"
#define MAXNFSDCNT 256
#define DEFNFSDCNT 4
pid_t children[MAXNFSDCNT]; /* PIDs of children */
int nfsdcnt; /* number of children */
int new_syscall;
+int run_v4server = 0; /* Force running of nfsv4 server */
+int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */
void cleanup(int);
void child_cleanup(int);
@@ -112,6 +117,7 @@ void usage(void);
* -d - unregister with rpcbind
* -t - support tcp nfs clients
* -u - support udp nfs clients
+ * -4 - forces it to run a server that supports nfsv4
* followed by "n" which is the number of nfsds' to fork off
*/
int
@@ -131,20 +137,15 @@ main(int argc, char **argv)
int tcp6sock, ip6flag, tcpflag, tcpsock;
int udpflag, ecode, s, srvcnt;
int bindhostc, bindanyflag, rpcbreg, rpcbregcnt;
+ int stablefd, nfssvc_addsock;
char **bindhost = NULL;
pid_t pid;
- if (modfind("nfsserver") < 0) {
- /* Not present in kernel, try loading it */
- if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0)
- errx(1, "NFS server is not available");
- }
-
nfsdcnt = DEFNFSDCNT;
unregister = reregister = tcpflag = maxsock = 0;
bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
-#define GETOPT "ah:n:rdtu"
-#define USAGE "[-ardtu] [-n num_servers] [-h bindip]"
+#define GETOPT "ah:n:rdtu4"
+#define USAGE "[-ardtu4] [-n num_servers] [-h bindip]"
while ((ch = getopt(argc, argv, GETOPT)) != -1)
switch (ch) {
case 'a':
@@ -179,6 +180,9 @@ main(int argc, char **argv)
case 'u':
udpflag = 1;
break;
+ case '4':
+ run_v4server = 1;
+ break;
default:
case '?':
usage();
@@ -203,6 +207,25 @@ main(int argc, char **argv)
}
}
+ /*
+ * If the "-4" option was specified OR only the nfsd module is
+ * found in the server, run "nfsd".
+ * Otherwise, try and run "nfsserver".
+ */
+ if (run_v4server > 0) {
+ if (modfind("nfsd") < 0) {
+ /* Not present in kernel, try loading it */
+ if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
+ errx(1, "NFS server is not available");
+ }
+ } else if (modfind("nfsserver") < 0 && modfind("nfsd") >= 0) {
+ run_v4server = 1;
+ } else if (modfind("nfsserver") < 0) {
+ /* Not present in kernel, try loading it */
+ if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0)
+ errx(1, "NFS server is not available");
+ }
+
ip6flag = 1;
s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
@@ -328,15 +351,47 @@ main(int argc, char **argv)
openlog("nfsd", LOG_PID, LOG_DAEMON);
/*
- * Figure out if the kernel supports the new-style
- * NFSSVC_NFSD. Old kernels will return ENXIO because they
- * don't recognise the flag value, new ones will return EINVAL
- * because argp is NULL.
+ * For V4, we open the stablerestart file and call nfssvc()
+ * to get it loaded. This is done before the daemons do the
+ * regular nfssvc() call to service NFS requests.
+ * (This way the file remains open until the last nfsd is killed
+ * off.)
+ * Note that this file is not created by this daemon and can
+ * only be relocated by recompiling the daemon, in order to
+ * minimize accidentally starting up with the wrong file.
+ * If should be created as an empty file Read and Write for
+ * root before the first time you run NFS v4 and should never
+ * be re-initialized if at all possible. It should live on a
+ * local, non-volatile storage device that does not do hardware
+ * level write-back caching. (See SCSI doc for more information
+ * on how to prevent write-back caching on SCSI disks.)
*/
- new_syscall = FALSE;
- if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL)
+ if (run_v4server > 0) {
+ stablefd = open(NFSD_STABLERESTART, O_RDWR, 0);
+ if (stablefd < 0) {
+ syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART);
+ exit(1);
+ }
+ if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) {
+ syslog(LOG_ERR, "Can't read stable storage file\n");
+ exit(1);
+ }
+ nfssvc_addsock = NFSSVC_NFSDADDSOCK;
+ nfssvc_nfsd = NFSSVC_NFSDNFSD;
new_syscall = TRUE;
- new_syscall = FALSE;
+ } else {
+ nfssvc_addsock = NFSSVC_ADDSOCK;
+ nfssvc_nfsd = NFSSVC_NFSD;
+ /*
+ * Figure out if the kernel supports the new-style
+ * NFSSVC_NFSD. Old kernels will return ENXIO because they
+ * don't recognise the flag value, new ones will return EINVAL
+ * because argp is NULL.
+ */
+ new_syscall = FALSE;
+ if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL)
+ new_syscall = TRUE;
+ }
if (!new_syscall) {
/* If we use UDP only, we start the last server below. */
@@ -413,7 +468,7 @@ main(int argc, char **argv)
addsockargs.sock = sock;
addsockargs.name = NULL;
addsockargs.namelen = 0;
- if (nfssvc(NFSSVC_ADDSOCK, &addsockargs) < 0) {
+ if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
syslog(LOG_ERR, "can't Add UDP socket");
nfsd_exit(1);
}
@@ -481,7 +536,7 @@ main(int argc, char **argv)
addsockargs.sock = sock;
addsockargs.name = NULL;
addsockargs.namelen = 0;
- if (nfssvc(NFSSVC_ADDSOCK, &addsockargs) < 0) {
+ if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
syslog(LOG_ERR,
"can't add UDP6 socket");
nfsd_exit(1);
@@ -711,7 +766,7 @@ main(int argc, char **argv)
addsockargs.sock = msgsock;
addsockargs.name = (caddr_t)&inetpeer;
addsockargs.namelen = len;
- nfssvc(NFSSVC_ADDSOCK, &addsockargs);
+ nfssvc(nfssvc_addsock, &addsockargs);
(void)close(msgsock);
} else if (FD_ISSET(tcpsock, &v6bits)) {
len = sizeof(inet6peer);
@@ -733,7 +788,7 @@ main(int argc, char **argv)
addsockargs.sock = msgsock;
addsockargs.name = (caddr_t)&inet6peer;
addsockargs.namelen = len;
- nfssvc(NFSSVC_ADDSOCK, &addsockargs);
+ nfssvc(nfssvc_addsock, &addsockargs);
(void)close(msgsock);
}
}
@@ -861,19 +916,47 @@ nfsd_exit(int status)
void
start_server(int master)
{
- char principal[128];
- char hostname[128];
+ char principal[MAXHOSTNAMELEN + 5];
struct nfsd_nfsd_args nfsdargs;
- int status;
+ int status, error;
+ char hostname[MAXHOSTNAMELEN + 1], *cp;
+ struct addrinfo *aip, hints;
status = 0;
if (new_syscall) {
- gethostname(hostname, sizeof(hostname));
- snprintf(principal, sizeof(principal), "nfs@%s", hostname);
+ gethostname(hostname, sizeof (hostname));
+ snprintf(principal, sizeof (principal), "nfs@%s", hostname);
+ if ((cp = strchr(hostname, '.')) == NULL ||
+ *(cp + 1) == '\0') {
+ /* If not fully qualified, try getaddrinfo() */
+ memset((void *)&hints, 0, sizeof (hints));
+ hints.ai_flags = AI_CANONNAME;
+ error = getaddrinfo(hostname, NULL, &hints, &aip);
+ if (error == 0) {
+ if (aip->ai_canonname != NULL &&
+ (cp = strchr(aip->ai_canonname, '.')) !=
+ NULL && *(cp + 1) != '\0')
+ snprintf(principal, sizeof (principal),
+ "nfs@%s", aip->ai_canonname);
+ freeaddrinfo(aip);
+ }
+ }
nfsdargs.principal = principal;
nfsdargs.minthreads = nfsdcnt;
nfsdargs.maxthreads = nfsdcnt;
- if (nfssvc(NFSSVC_NFSD, &nfsdargs) < 0) {
+ error = nfssvc(nfssvc_nfsd, &nfsdargs);
+ if (error < 0 && errno == EAUTH) {
+ /*
+ * This indicates that it could not register the
+ * rpcsec_gss credentials, usually because the
+ * gssd daemon isn't running.
+ * (only the experimental server with nfsv4)
+ */
+ syslog(LOG_ERR, "No gssd, using AUTH_SYS only");
+ principal[0] = '\0';
+ error = nfssvc(nfssvc_nfsd, &nfsdargs);
+ }
+ if (error < 0) {
syslog(LOG_ERR, "nfssvc: %m");
status = 1;
}
diff --git a/usr.sbin/nfsd/nfsv4.4 b/usr.sbin/nfsd/nfsv4.4
new file mode 100644
index 0000000..582181d
--- /dev/null
+++ b/usr.sbin/nfsd/nfsv4.4
@@ -0,0 +1,309 @@
+.\" Copyright (c) 2009 Rick Macklem, University of Guelph
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 30, 2009
+.Dt NFSV4 4
+.Os
+.Sh NAME
+.Nm nfsv4
+.Nd NFS Version 4 Protocol
+.Sh SYNOPSIS
+experimental client and server with NFSv4 support
+.Sh DESCRIPTION
+The experimental nfs client and server provides support for the
+.Tn NFSv4
+specification; see
+.%T "Network File System (NFS) Version 4 Protocol \\*(tNRFC\\*(sP 3530" .
+The protocol is somewhat similar to NFS Version 3, but differs in significant
+ways. It uses a single Compound RPC that concatenates operations to-gether.
+Each of these operations are similar to the RPCs of NFS Version 3.
+The operations in the compound are performed in order, until one of
+them fails (returns an error) and then the RPC terminates at that point.
+.Pp
+It has
+integrated locking support, which implies that the server is no longer
+stateless. As such, the
+.Tn NFSv4
+server remains in recovery mode for a Grace period (always greater than the
+lease duration the server uses) after a reboot.
+During this Grace period, clients may recover state but not perform other
+open/lock state changing operations.
+To provide for correct recovery semantics, a small file described by
+.Xr stablerestart 5
+is used by the server during the recovery phase. If this file is missing,
+the server will not start.
+If this file is lost, it should be recovered from backups, since creating
+an empty
+.Xr stablerestart 5
+file will result in the server starting without providing a Grace Period
+for recovery.
+Note that recovery only occurs when the server
+machine is rebooted, not when the
+.Xr nfsd 8
+are just restarted.
+.Pp
+It provides several optional features not in NFS Version 3:
+.sp
+.Bd -literal -offset indent -compact
+- NFS Version 4 ACLs
+- Referrals, which redirect subtrees to other servers
+ (not yet implemented)
+- Delegations, which allow a client to operate on a file locally
+.Ed
+.Pp
+The
+.Tn NFSv4
+protocol does not use a separate mount protocol and assumes that the
+server provides a single file system tree structure, rooted at the point
+in the local file system tree specified by the
+.sp 1
+.Bd -literal -offset indent -compact
+V4: <rootdir>
+.Ed
+.sp 1
+line in
+.Xr exports 5 .
+The
+.Xr nfsd 8
+allows a limited subset of operations to be performed on non-exported subtrees
+of the local file system, so that traversal of the tree to the exported
+subtrees is possible.
+As such, the ``<rootdir>'' can be in a non-exported file system. However,
+the entire tree that is rooted at that point must be in local file systems
+that are of types that can be NFS exported.
+Since the
+.Nm
+file system is rooted at ``<rootdir>'', setting this to anything other
+than ``/'' will result in clients being required to use different mount
+paths for
+.Nm
+than for NFS Version 2 or 3.
+Unlike NFS Version 2 and 3, Version 4 allows a client mount to span across
+multiple server file systems, although not all clients are capable of doing
+this.
+.Pp
+.Nm
+uses names for users and groups instead of numbers. On the wire, they
+take the form:
+.sp
+.Bd -literal -offset indent -compact
+<user>@<dns.domain>
+.Ed
+.sp
+where ``<dns.domain>'' is not the same as the DNS domain used
+for host name lookups, but is usually set to the same string. Most systems set this ``<dns.domain>''
+to the domain name part of the machine's
+.Xr hostname 1
+by default. However, this can normally be overridden by a command line
+option or configuration file for the daemon used to do the name<->number
+mapping.
+On FreeBSD, the mapping daemon is called
+.Xr nfsuserd 8
+and has a command line option that overrides the domain component of the
+machine's hostname.
+This can be set in
+.Xr rc.conf 5
+via the nfsv4_userd_flags variable.
+For use of
+.Nm ,
+either client or server, this daemon must be enabled by setting
+.sp
+.Bd -literal -offset indent -compact
+nfsv4_enable="YES"
+.Ed
+.sp
+in
+.Xr rc.conf 5 .
+If this ``<dns.domain>'' is not set correctly or the daemon is not running, ``ls -l'' will typically
+report a lot of ``nobody'' and ``nogroup'' ownerships.
+.Pp
+Although numbers are no longer used in the
+.Nm
+protocol, they will still be in the RPC authentication fields when running
+using AUTH_SYS (sec=sys), which is the default.
+As such, in this case both the user/group name and number spaces must
+be consistent between the client and server.
+.Pp
+However, if you run
+.Nm
+with RPCSEC_GSS (sec=krb5, krb5i, krb5p), only names and KerberosV tickets
+will go on the wire.
+.Sh SERVER SETUP
+.Pp
+To set up the experimental nfs server that supports
+.Nm
+you will need to either build a kernel with:
+.sp
+.Bd -literal -offset indent -compact
+options NFSD
+.Ed
+and not
+.Bd -literal -offset indent -compact
+options NFSSERVER
+.Ed
+.sp
+or start
+.Xr mountd 8
+and
+.Xr nfsd 8
+with the ``-4'' option to force use of the experimental server.
+This will occur if
+.sp
+.Bd -literal -offset indent -compact
+nfsv4_enable="YES"
+.Ed
+.sp
+is set in
+.Xr rc.conf 5 ,
+as above.
+.Pp
+You will also need to add a:
+.sp
+.Bd -literal -offset indent -compact
+V4: <rootdir>
+.Ed
+.sp
+line to the
+.Xr exports 5
+file, to tell the server where the
+.Nm
+tree is rooted.
+.Pp
+If the file systems you are exporting are only being accessed via
+.Nm
+there are a couple of
+.Xr sysctl 8
+variables that you can change, which might improve performance.
+.Bl -tag -width Ds
+.It Cm vfs.newnfs.issue_delegations
+when set non-zero, allows the server to issue Open Delegations to
+clients. These delegations permit the client to manipulate the file
+locally on the client. Unfortunately, at this time, client use of
+delegations is limited, so performance gains may not be observed.
+This can only be enabled when the file systems being exported to
+.Nm
+clients are not being accessed locally on the server and, if being
+accessed via NFS Version 2 or 3 clients, these clients cannot be
+using the NLM.
+.It Cm vfs.newnfs.enable_locallocks
+can be set to 0 to disable acquisition of local byte range locks.
+Disabling local locking can only be done if neither local accesses
+to the exported file systems nor the NLM is operating on them.
+.El
+.sp
+Note that Samba server access would be considered ``local access'' for the above
+discussion.
+.Pp
+To build a kernel with the experimental
+.Nm
+linked into it, the
+.sp
+.Bd -literal -offset indent -compact
+options NFSD
+.Ed
+.sp
+must be specified in the kernel's
+.Xr config 5
+file.
+.Sh CLIENT MOUNTS
+.Pp
+To do an
+.Nm
+mount, specify the ``nfsv4'' option on the
+.Xr mount_nfs 8
+command line.
+This will force use of the experimental client plus set ``tcp'' and
+.Nm .
+.Pp
+If the
+.Nm
+server that is being mounted on supports delegations, you can set
+.sp
+.Bd -literal -offset indent -compact
+nfsv4_callbackdaemon_enable="YES"
+.Ed
+.sp
+via
+.Xr rc.conf 5
+so that the client side callback daemon
+.Xr nfscbd 8
+is started upon boot.
+Without a functioning callback path, a server will never issue Delegations
+to a client.
+.sp
+By default, the callback address will be set to the IP address acquired via
+rtalloc() in the kernel and port# 7745.
+To override the default port#, a command line option for
+.Xr nfscbd 8
+can be set via the variable
+.sp
+.Bd -literal -offset indent -compact
+nfsv4_callbackdaemon_flag
+.Ed
+.sp
+using
+.Xr rc.conf 5 .
+.sp
+To get callbacks to work when behind a NAT gateway, a port for the callback
+service will need to be set up on the NAT gateway and then the address
+of the NAT gateway (host IP plus port#) will need to be set by assigning the
+.Xr sysctl 8
+variable vfs.newnfs.callback_addr to a string of the form:
+.sp
+N.N.N.N.N.N
+.sp
+where the first 4 Ns are the host IP address and the last two are the
+port# in network byte order (all decimal #s in the range 0-255).
+.Pp
+To build a kernel with the experimental
+.Nm
+client linked into it, the option
+.sp
+.Bd -literal -offset indent -compact
+options NFSCL
+.Ed
+.sp
+must be specified in the kernel's
+.Xr config 5
+file.
+.Sh FILES
+.Bl -tag -width /var/db/nfs-stablerestart -compact
+.It Pa /var/db/nfs-stablerestart
+NFS V4 stable restart file
+.El
+.Sh SEE ALSO
+.Xr stablerestart 5
+.Xr mountd 8
+.Xr nfscbd 8
+.Xr nfsd 8
+.Xr nfsdumpstate 8
+.Xr nfsrevoke 8
+.Xr nfsuserd 8
+.Sh BUGS
+At this time, there is no recall of delegations for local file system
+operations. As such, delegations should only be enabled for file systems
+that are being used soley as NFS export volumes and are not being accessed
+via local system calls nor services such as Samba.
diff --git a/usr.sbin/nfsd/stablerestart.5 b/usr.sbin/nfsd/stablerestart.5
new file mode 100644
index 0000000..c469835
--- /dev/null
+++ b/usr.sbin/nfsd/stablerestart.5
@@ -0,0 +1,93 @@
+.\" Copyright (c) 2009 Rick Macklem, University of Guelph
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd Sept 7, 2007
+.Dt STABLERESTART 5
+.Os
+.Sh NAME
+.Nm nfs-stablerestart
+.Nd handles restart edge conditions for the
+.Tn NFS
+V4 server
+.Sh SYNOPSIS
+.Nm nfs-stablerestart
+.Sh DESCRIPTION
+The
+.Nm
+file holds information that allows the
+.Tn NFS
+V4 server to restart without always returning the NFSERR_NOGRACE error, as described in the
+.Tn NFS V4
+server specification; see
+.%T "Network File System (NFS) Version 4 Protocol \\*(tNRFC\\*(sP 3530, Section 8.6.3" .
+.Pp
+The first record in the file, as defined by struct nfsf_rec in
+/usr/include/fs/nfs/nfsrvstate.h, holds the lease duration of the
+last incarnation of the server and the number of boot times that follows.
+Following this are the number of previous boot times listed in the
+first record.
+The lease duration is used to set the Grace Period.
+The boot times
+are used to avoid the unlikely occurrence of a boot time being reused,
+due to a TOD clock going backwards. This record and the previous boot times with this boot time added is re-written at the
+end of the Grace Period.
+.Pp
+The rest of the file are appended records, as defined by
+struct nfst_rec in /usr/include/fs/nfs/nfsrvstate.h and are used
+represent one of two things. There are records which indicate that a
+client successfully aquired state and records that indicate a client's state was revoked.
+State revoke records indicate that state information
+for a client was discarded, due to lease expiry and an otherwise
+conflicting open or lock request being made by a different client.
+These records can be used
+to determine if clients might have done either of the
+edge conditions.
+.Pp
+If a client might have done either edge condition or this file is
+empty or corrupted, the server returns NFSERR_NOGRACE for any reclaim
+request from the client.
+.Pp
+For correct operation of the server, it must be ensured that the file
+is written to stable storage by the time a write op with IO_SYNC specified
+has returned. This might require hardware level caching to be disabled for
+a local disk drive that holds the file, or similar.
+.Sh FILES
+.Bl -tag -width /var/db/nfs-stablerestart -compact
+.It Pa /var/db/nfs-stablerestart
+NFS V4 stable restart file
+.El
+.Sh SEE ALSO
+.Xr nfsv4 4
+.Xr nfsd 8
+.Sh BUGS
+If the file is empty, the NFS V4 server has no choice but to return
+NFSERR_NOGRACE for all Reclaim requests. Although correct, this is
+a highly undesirable occurrence, so the file should not be lost if
+at all possible. Nfsd will not create the file if it does not
+exist and will simply log a failure to start, in the hopes that the
+file can be recovered from a backup. To move the file, you must edit
+the nfsd sources and recompile it. This was done to discourage
+accidental relocation of the file.
OpenPOWER on IntegriCloud