2014-03-11 00:09:19

by NeilBrown

[permalink] [raw]
Subject: [PATCH 2/4 v2] nfsd: allow nfsv4leasetime and nfsv4gracetime to be set.



New arguments --gracetime (-G) and --leasetime (-L)

Signed-off-by: NeilBrown <[email protected]>

--
resend of just patch 2 from the series with fix as discussed.
NeilBrown


diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c
index d44a5e7d6a5f..65e7b7193bda 100644
--- a/utils/nfsd/nfsd.c
+++ b/utils/nfsd/nfsd.c
@@ -46,6 +46,8 @@ static struct option longopts[] =
{ "debug", 0, 0, 'd' },
{ "syslog", 0, 0, 's' },
{ "rdma", 2, 0, 'R' },
+ { "grace-time", 1, 0, 'G'},
+ { "lease-time", 1, 0, 'L'},
{ NULL, 0, 0, 0 }
};

@@ -106,6 +108,8 @@ main(int argc, char **argv)
unsigned int protobits = NFSCTL_ALLBITS;
unsigned int proto4 = 0;
unsigned int proto6 = 0;
+ int grace = -1;
+ int lease = -1;

progname = strdup(basename(argv[0]));
if (!progname) {
@@ -122,7 +126,7 @@ main(int argc, char **argv)
xlog_syslog(0);
xlog_stderr(1);

- while ((c = getopt_long(argc, argv, "dH:hN:V:p:P:sTUr", longopts, NULL)) != EOF) {
+ while ((c = getopt_long(argc, argv, "dH:hN:V:p:P:sTUrG:L:", longopts, NULL)) != EOF) {
switch(c) {
case 'd':
xlog_config(D_ALL, 1);
@@ -221,6 +225,20 @@ main(int argc, char **argv)
case 'U':
NFSCTL_UDPUNSET(protobits);
break;
+ case 'G':
+ grace = strtol(optarg, &p, 0);
+ if (*p || grace <= 0) {
+ fprintf(stderr, "%s: Unrecognized grace time.\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'L':
+ lease = strtol(optarg, &p, 0);
+ if (*p || grace <= 0) {
+ fprintf(stderr, "%s: Unrecognized lease time.\n", optarg);
+ exit(1);
+ }
+ break;
default:
fprintf(stderr, "Invalid argument: '%c'\n", c);
case 'h':
@@ -268,7 +286,7 @@ main(int argc, char **argv)
if (!found_one) {
xlog(L_ERROR, "no version specified");
exit(1);
- }
+ }

if (NFSCTL_VERISSET(versbits, 4) &&
!NFSCTL_TCPISSET(proto4) &&
@@ -292,12 +310,18 @@ main(int argc, char **argv)
}

/*
- * must set versions before the fd's so that the right versions get
+ * Must set versions before the fd's so that the right versions get
* registered with rpcbind. Note that on older kernels w/o the right
* interfaces, these are a no-op.
+ * Timeouts must also be set before ports are created else we get
+ * EBUSY.
*/
nfssvc_setvers(versbits, minorvers, minorversset);
-
+ if (grace > 0)
+ nfssvc_set_time("grace", grace);
+ if (lease > 0)
+ nfssvc_set_time("lease", lease);
+
error = nfssvc_set_sockets(AF_INET, proto4, haddr, port);
if (!error)
socket_up = 1;
@@ -353,7 +377,10 @@ static void
usage(const char *prog)
{
fprintf(stderr, "Usage:\n"
- "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version] [-V|--nfs-version version] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] [-r|--rdma=] nrservs\n",
+ "%s [-d|--debug] [-H hostname] [-p|-P|--port port]\n"
+ " [-N|--no-nfs-version version] [-V|--nfs-version version]\n"
+ " [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] [-r|--rdma=]\n"
+ " [-G|--gracetime secs] [-L|--leasetime secs] nrservs\n",
prog);
exit(2);
}
diff --git a/utils/nfsd/nfsd.man b/utils/nfsd/nfsd.man
index aedf1409dc53..58b53cbff009 100644
--- a/utils/nfsd/nfsd.man
+++ b/utils/nfsd/nfsd.man
@@ -2,7 +2,7 @@
.\" nfsd(8)
.\"
.\" Copyright (C) 1999 Olaf Kirch <[email protected]>
-.TH rpc.nfsd 8 "7 Aug 2006"
+.TH rpc.nfsd 8 "20 Feb 2014"
.SH NAME
rpc.nfsd \- NFS server process
.SH SYNOPSIS
@@ -83,6 +83,15 @@ offer certain versions of NFS. The current version of
.B rpc.nfsd
can support NFS versions 2,3,4 and the newer version 4.1.
.TP
+.B \-L " or " \-\-lease-time seconds
+Set the lease-time used for NFSv4. This corresponds to how often
+clients need to confirm their state with the server. Valid range is
+from 10 to 3600 seconds.
+.TP
+.B \-G " or " \-\-grace-time seconds
+Set the grace-time used for NFSv4. New file open requests will not be
+allowed until after this time has passed to allow clients to recover state.
+.TP
.I nproc
specify the number of NFS server threads. By default, just one
thread is started. However, for optimum performance several threads
diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c
index 4f2826b88905..eb21685ec135 100644
--- a/utils/nfsd/nfssvc.c
+++ b/utils/nfsd/nfssvc.c
@@ -303,6 +303,23 @@ nfssvc_set_rdmaport(const char *port)
}

void
+nfssvc_set_time(const char *type, const int seconds)
+{
+ char pathbuf[40];
+ char nbuf[10];
+ int fd;
+
+ snprintf(pathbuf, sizeof(pathbuf), NFSD_FS_DIR "/nfsv4%stime", type);
+ snprintf(nbuf, sizeof(nbuf), "%d", seconds);
+ fd = open(pathbuf, O_WRONLY);
+ if (fd >= 0) {
+ if (write(fd, nbuf, strlen(nbuf)) != (ssize_t)strlen(nbuf))
+ xlog(L_ERROR, "Unable to set nfsv4%stime: %m", type);
+ close(fd);
+ }
+}
+
+void
nfssvc_setvers(unsigned int ctlbits, unsigned int minorvers, unsigned int minorversset)
{
int fd, n, off;
diff --git a/utils/nfsd/nfssvc.h b/utils/nfsd/nfssvc.h
index 5ea7a448019e..fbb89b22df20 100644
--- a/utils/nfsd/nfssvc.h
+++ b/utils/nfsd/nfssvc.h
@@ -24,6 +24,7 @@ void nfssvc_mount_nfsdfs(char *progname);
int nfssvc_inuse(void);
int nfssvc_set_sockets(const int family, const unsigned int protobits,
const char *host, const char *port);
+void nfssvc_set_time(const char *type, const int seconds);
int nfssvc_set_rdmaport(const char *port);
void nfssvc_setvers(unsigned int ctlbits, unsigned int minorvers4, unsigned int minorvers4set);
int nfssvc_threads(unsigned short port, int nrservs);


Attachments:
signature.asc (828.00 B)