diff options
-rw-r--r-- | usr.sbin/nfsd/Makefile | 2 | ||||
-rw-r--r-- | usr.sbin/nfsd/nfsd.8 | 36 | ||||
-rw-r--r-- | usr.sbin/nfsd/nfsd.c | 133 | ||||
-rw-r--r-- | usr.sbin/nfsd/nfsv4.4 | 309 | ||||
-rw-r--r-- | usr.sbin/nfsd/stablerestart.5 | 93 |
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. |