Linux NFS development
 help / color / mirror / Atom feed
* [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
@ 2005-03-21 14:42 Steve Dickson
  2005-03-21 14:56 ` J. Bruce Fields
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Steve Dickson @ 2005-03-21 14:42 UTC (permalink / raw)
  To: Neil Brown; +Cc: nfs

[-- Attachment #1: Type: text/plain, Size: 924 bytes --]

Hello,

The following patches fix the '-p port' command line
argument to rpc.nfsd as well as adds following
flags that control the NFS versions and transports that
rpc.nfsd will use.

     -N  or  --no-nfs-version vers
         This option can be used to request that rpc.nfsd does not  offer
         certain  versions of NFS. The current version of rpc.nfsd can
         support both NFS version 2,3 and the newer version 4.

     -T  or  --no-tcp
         Disable rpc.nfsd from accepting TCP connections from clients.

     -U  or  --no-udp
         Disable rpc.nfsd from accepting UDP connections from clients.


The first patch is for nfs-utils and the second one is for the
kernel. Although I'm posting these patch together, they are
not dependent on each other. Meaning, a patched kernel
will work with an unpatched nfs-utils and visa-versa..


Is this something the upstream kernels would be interested in?

steved.

[-- Attachment #2: nfs-utils-1.0.7-nfsd-ctlbits.patch --]
[-- Type: text/x-patch, Size: 6843 bytes --]

--- nfs-utils-1.0.7/support/include/nfs/nfs.h.orig	2003-07-02 22:09:31.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfs/nfs.h	2005-03-18 09:37:09.000000000 -0500
@@ -40,7 +40,13 @@ struct nfs_fh_old {
 #define NFSCTL_LOCKD		0x10000
 #define LOCKDCTL_SVC		NFSCTL_LOCKD
 
-
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) 
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1))) 
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1))) 
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) 
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1))) 
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1))) 
 
 /* SVC */
 struct nfsctl_svc {
--- nfs-utils-1.0.7/support/include/nfslib.h.orig	2004-09-14 21:58:40.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfslib.h	2005-03-17 09:02:15.000000000 -0500
@@ -118,7 +118,7 @@ int			wildmat(char *text, char *pattern)
  * nfsd library functions.
  */
 int			nfsctl(int, struct nfsctl_arg *, union nfsctl_res *);
-int			nfssvc(int port, int nrservs);
+int			nfssvc(int port, int nrservs, unsigned int ctlbits);
 int			nfsaddclient(struct nfsctl_client *clp);
 int			nfsdelclient(struct nfsctl_client *clp);
 int			nfsexport(struct nfsctl_export *exp);
--- nfs-utils-1.0.7/support/nfs/nfssvc.c.orig	2005-03-17 09:44:28.000000000 -0500
+++ nfs-utils-1.0.7/support/nfs/nfssvc.c	2005-03-18 09:37:38.000000000 -0500
@@ -14,7 +14,7 @@
 #include "nfslib.h"
 
 int
-nfssvc(int port, int nrservs)
+nfssvc(int port, int nrservs, unsigned ctlbits)
 {
 	struct nfsctl_arg	arg;
 	int fd;
@@ -25,16 +25,21 @@ nfssvc(int port, int nrservs)
 	if (fd >= 0) {
 		/* 2.5+ kernel with nfsd filesystem mounted.
 		 * Just write the number in.
-		 * Cannot handle port number yet, but does anyone care?
 		 */
-		char buf[20];
+		char buf[40];
 		int n;
-		snprintf(buf, 20,"%d\n", nrservs);
+		snprintf(buf, 40,"%d %d %d\n", nrservs, port, ctlbits);
 		n = write(fd, buf, strlen(buf));
 		close(fd);
-		if (n != strlen(buf))
-			return -1;
-		else
+		if (n != strlen(buf)) {
+			/*
+			 * See if this an older kernel that does not
+			 * have the ctlbits support
+			 */
+			snprintf(buf, 40, "%d\n", nrservs);
+			if (n != strlen(buf))
+				return -1;
+		} else
 			return 0;
 	}
 
--- nfs-utils-1.0.7/utils/mountd/mountd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/mountd/mountd.c	2005-03-19 11:57:38.000000000 -0500
@@ -255,6 +255,9 @@ mount_mnt_3_svc(struct svc_req *rqstp, d
 			= sizeof(flavors)/sizeof(flavors[0]);
 		ok->auth_flavors.auth_flavors_val = flavors;
 	}
+	if (fh == NULL || res->fhs_status)
+		xlog(D_CALL, "MNT3(%s) failed: status %d\n", res->fhs_status);
+
 	return 1;
 }
 
--- nfs-utils-1.0.7/utils/nfsd/nfsd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.c	2005-03-18 09:40:41.000000000 -0500
@@ -23,12 +23,24 @@
 
 static void	usage(const char *);
 
+static struct option longopts[] =
+{
+	{ "help", 0, 0, 'h' },
+	{ "no-nfs-version", 1, 0, 'N' },
+	{ "no-tcp", 0, 0, 'T' },
+	{ "no-udp", 0, 0, 'U' },
+	{ "port", 1, 0, 'P' },
+	{ "port", 1, 0, 'p' },
+	{ NULL, 0, 0, 0 }
+};
+
 int
 main(int argc, char **argv)
 {
-	int	count = 1, c, error, port, fd;
+	int	count = 1, c, error, port, fd, found_one;
 	struct servent *ent;
 	DIR *dir;
+	unsigned int ctlbits = ~0;
 
 	ent = getservbyname ("nfs", "udp");
 	if (ent != NULL)
@@ -36,7 +48,7 @@ main(int argc, char **argv)
 	else
 		port = 2049;
 
-	while ((c = getopt(argc, argv, "hp:P:")) != EOF) {
+	while ((c = getopt_long(argc, argv, "hN:p:P:TU", longopts, NULL)) != EOF) {
 		switch(c) {
 		case 'P':	/* XXX for nfs-server compatibility */
 		case 'p':
@@ -47,12 +59,50 @@ main(int argc, char **argv)
 				usage(argv [0]);
 			}
 			break;
+		case 'N':
+			switch((c = atoi(optarg))) {
+			case 2:
+			case 3:
+			case 4:
+				NFSCTL_VERUNSET(ctlbits, c);
+				break;
+			default:
+				fprintf(stderr, "%c: Unsupported version\n", c);
+				exit(1);
+			}
 			break;
-		case 'h':
+		case 'T':
+				NFSCTL_TCPUNSET(ctlbits);
+				break;
+		case 'U':
+				NFSCTL_UDPUNSET(ctlbits);
+				break;
 		default:
+			fprintf(stderr, "Invalid argument: '%c'\n", c);
+		case 'h':
 			usage(argv[0]);
 		}
 	}
+	/*
+	 * Do some sanity checking, if the ctlbits are set
+	 */
+	if (!NFSCTL_UDPISSET(ctlbits) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "invalid protocol specified\n");
+		exit(1);
+	}
+	found_one = 0;
+	for (c = 2; c <= 4; c++) {
+		if (NFSCTL_VERISSET(ctlbits, c))
+			found_one = 1;
+	}
+	if (!found_one) {
+		fprintf(stderr, "no version specified\n");
+		exit(1);
+	}			
+	if (NFSCTL_VERISSET(ctlbits, 4) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "version 4 requires the TCP protocol\n");
+		exit(1);
+	}
 
 	if (chdir(NFS_STATEDIR)) {
 		fprintf(stderr, "%s: chdir(%s) failed: %s\n",
@@ -69,7 +119,6 @@ main(int argc, char **argv)
 			count = 1;
 		}
 	}
-
 	/* KLUDGE ALERT:
 	   Some kernels let nfsd kernel threads inherit open files
 	   from the program that spawns them (i.e. us).  So close
@@ -99,7 +148,7 @@ main(int argc, char **argv)
 			(void) close(fd);
 	}
 
-	if ((error = nfssvc(port, count)) < 0) {
+	if ((error = nfssvc(port, count, ctlbits)) < 0) {
 		int e = errno;
 		openlog("nfsd", LOG_PID, LOG_DAEMON);
 		syslog(LOG_ERR, "nfssvc: %s", strerror(e));
@@ -112,7 +161,8 @@ main(int argc, char **argv)
 static void
 usage(const char *prog)
 {
-	fprintf(stderr, "usage:\n"
-			"%s nrservs\n", prog);
+	fprintf(stderr, "Usage:\n"
+		"%s [-p|-P|--port] [-N|no-nfs-version] [-T|--no-tcp] [-U|--no-udp] nrservs\n", 
+		prog);
 	exit(2);
 }
--- nfs-utils-1.0.7/utils/nfsd/nfsd.man.orig	2002-08-26 12:57:59.000000000 -0400
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.man	2005-03-21 07:54:22.533718624 -0500
@@ -6,7 +6,7 @@
 .SH NAME
 rpc.nfsd \- NFS server process
 .SH SYNOPSIS
-.BI "/usr/sbin/rpc.nfsd [-p " port "] " nproc
+.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc
 .SH DESCRIPTION
 The
 .B rpc.nfsd
@@ -22,11 +22,28 @@ server provides an ancillary service nee
 by NFS clients.
 .SH OPTIONS
 .TP
-.BI \-p " port"
+.B \-p " or " \-\-port  port
 specify a diferent port to listen on for NFS requests. By default,
 .B rpc.nfsd
 will listen on port 2049.
 .TP
+.B \-N " or " \-\-no-nfs-version vers
+This option can be used to request that 
+.B rpc.nfsd
+does not offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support both NFS version 2,3 and the newer version 4.
+.TP
+.B \-T " or " \-\-no-tcp
+Disable 
+.B rpc.nfsd 
+from accepting TCP connections from clients.
+.TP
+.B \-U " or " \-\-no-udp
+Disable
+.B rpc.nfsd
+from accepting UDP connections from clients.
+.TP
 .I nproc
 specify the number of NFS server threads. By default, just one
 thread is started. However, for optimum performance several threads

[-- Attachment #3: linux-2.6.11-nfsd-ctlbits.patch --]
[-- Type: text/x-patch, Size: 7186 bytes --]

--- linux-2.6.11/fs/nfsd/nfs4state.c.orig	2005-03-02 02:38:13.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfs4state.c	2005-03-18 06:59:15.000000000 -0500
@@ -3250,6 +3250,8 @@ __nfs4_state_shutdown(void)
 void
 nfs4_state_shutdown(void)
 {
+	if (!nfs4_init)
+		return;
 	nfs4_lock_state();
 	nfs4_release_reclaim();
 	__nfs4_state_shutdown();
--- linux-2.6.11/fs/nfsd/nfssvc.c.orig	2005-03-02 02:38:10.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfssvc.c	2005-03-18 08:39:53.000000000 -0500
@@ -30,6 +30,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
 #include <linux/lockd/bind.h>
 
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
@@ -62,6 +63,29 @@ struct nfsd_list {
 };
 struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
+
+static struct svc_version *	nfsd_version[] = {
+	[2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+	[3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+	[4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS    2
+#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+struct svc_program		nfsd_program = {
+	.pg_prog		= NFS_PROGRAM,		/* program number */
+	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
+	.pg_vers		= nfsd_version,	/* version table */
+	.pg_name		= "nfsd",		/* program name */
+	.pg_class		= "nfsd",		/* authentication class */
+	.pg_stats		= &nfsd_svcstats,	/* version table */
+};
+
 /*
  * Maximum number of nfsd processes
  */
@@ -76,23 +100,47 @@ int nfsd_nrthreads(void)
 }
 
 int
-nfsd_svc(unsigned short port, int nrservs)
+nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits)
 {
 	int	error;
-	int	none_left;	
+	int	none_left, found_one, i;
 	struct list_head *victim;
 	
+	dprintk("nfsd: creating service (port %d nserver %d ctlbits 0x%x)\n",
+		port, nrservs, ctlbits);
+
 	lock_kernel();
-	dprintk("nfsd: creating service\n");
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
 	if (nrservs > NFSD_MAXSERVS)
 		nrservs = NFSD_MAXSERVS;
-	
+	/*
+	 * If set, use the ctlbits to define the
+	 * services that will be advertised
+	 */
+	if (ctlbits) {
+		found_one = 0;
+		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+			if (NFSCTL_VERISSET(ctlbits, i)) {
+				nfsd_program.pg_vers[i] = nfsd_version[i]; 
+				found_one = 1;
+			} else
+				nfsd_program.pg_vers[i] = NULL;
+		}
+		if (!found_one) {
+			printk(KERN_ERR "nfsd: no version set (cltbits 0x%x)\n", ctlbits);
+			goto out;
+		}			
+	} else { /* otherwise, turn everthing on */
+		ctlbits = ~0;
+		nfsd_program.pg_vers = nfsd_version;
+	}
+
 	/* Readahead param cache - will no-op if it already exists */
 	error =	nfsd_racache_init(2*nrservs);
-	nfs4_state_init();
+	if (NFSCTL_VERISSET(ctlbits, 4))
+		nfs4_state_init();
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
@@ -101,14 +149,17 @@ nfsd_svc(unsigned short port, int nrserv
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
 		if (nfsd_serv == NULL)
 			goto out;
-		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-		if (error < 0)
-			goto failure;
-
+		if (NFSCTL_UDPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+			if (error < 0)
+				goto failure;
+		}
 #ifdef CONFIG_NFSD_TCP
-		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-		if (error < 0)
-			goto failure;
+		if (NFSCTL_TCPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+			if (error < 0)
+				goto failure;
+		}
 #endif
 		do_gettimeofday(&nfssvc_boot);		/* record boot time */
 	} else
@@ -358,24 +409,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u3
 	return 1;
 }
 
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version *	nfsd_version[] = {
-	[2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
-	[3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
-	[4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program		nfsd_program = {
-	.pg_prog		= NFS_PROGRAM,		/* program number */
-	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
-	.pg_vers		= nfsd_version,		/* version table */
-	.pg_name		= "nfsd",		/* program name */
-	.pg_class		= "nfsd",		/* authentication class */
-	.pg_stats		= &nfsd_svcstats,	/* version table */
-};
--- linux-2.6.11/fs/nfsd/nfsctl.c.orig	2005-03-18 07:21:19.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfsctl.c	2005-03-18 09:24:22.000000000 -0500
@@ -133,7 +133,7 @@ static ssize_t write_svc(struct file *fi
 	if (size < sizeof(*data))
 		return -EINVAL;
 	data = (struct nfsctl_svc*) buf;
-	return nfsd_svc(data->svc_port, data->svc_nthreads);
+	return nfsd_svc(data->svc_port, data->svc_nthreads, 0);
 }
 
 static ssize_t write_add(struct file *file, char *buf, size_t size)
@@ -311,6 +311,9 @@ static ssize_t write_threads(struct file
 	 */
 	char *mesg = buf;
 	int rv;
+	unsigned int ctlbits = 0;
+	unsigned int port = 0;
+
 	if (size > 0) {
 		int newthreads;
 		rv = get_int(&mesg, &newthreads);
@@ -318,11 +321,30 @@ static ssize_t write_threads(struct file
 			return rv;
 		if (newthreads <0)
 			return -EINVAL;
-		rv = nfsd_svc(2049, newthreads);
+		rv = get_int(&mesg, &port);
+		if (rv) {
+			/*
+			 * its possible the rpc.nfsd does not 
+			 * have the ctlbits support, so just 
+			 * fill in with default values 
+			 */
+			port = 2049;
+			ctlbits = ~0;
+			sprintf(buf, "%d\n", newthreads);
+		} else {
+			rv = get_int(&mesg, &ctlbits);
+			if (rv) {
+				ctlbits = ~0;
+				sprintf(buf, "%d %d\n", nfsd_nrthreads(), port);
+			} else
+				sprintf(buf, "%d %d %d\n", nfsd_nrthreads(), port, ctlbits);
+		}
+		rv = nfsd_svc((unsigned short)port, newthreads, ctlbits);
 		if (rv)
 			return rv;
-	}
-	sprintf(buf, "%d\n", nfsd_nrthreads());
+	} else 
+		sprintf(buf, "%d\n", nfsd_nrthreads());
+
 	return strlen(buf);
 }
 
--- linux-2.6.11/include/linux/nfsd/syscall.h.orig	2005-03-02 02:38:38.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/syscall.h	2005-03-18 07:30:26.000000000 -0500
@@ -39,6 +39,14 @@
 #define NFSCTL_GETFD		7	/* get an fh by path (used by mountd) */
 #define	NFSCTL_GETFS		8	/* get an fh by path with max FH len */
 
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1)))
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1)))
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1)))
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1)))
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1)))
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1)))
+
 /* SVC */
 struct nfsctl_svc {
 	unsigned short		svc_port;
--- linux-2.6.11/include/linux/nfsd/nfsd.h.orig	2005-03-02 02:38:32.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/nfsd.h	2005-03-18 05:08:55.000000000 -0500
@@ -63,7 +63,7 @@ extern struct svc_version	nfsd_version2,
 /*
  * Function prototypes.
  */
-int		nfsd_svc(unsigned short port, int nrservs);
+int		nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits);
 int		nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp);
 
 /* nfsd/vfs.c */

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 14:42 [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more Steve Dickson
@ 2005-03-21 14:56 ` J. Bruce Fields
  2005-03-21 15:18   ` Trond Myklebust
  2005-03-21 15:59   ` Steve Dickson
  2005-03-21 15:46 ` [KNFSD] " Chip Salzenberg
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 13+ messages in thread
From: J. Bruce Fields @ 2005-03-21 14:56 UTC (permalink / raw)
  To: Steve Dickson; +Cc: Neil Brown, nfs

On Mon, Mar 21, 2005 at 09:42:11AM -0500, Steve Dickson wrote:
>     -N  or  --no-nfs-version vers
>         This option can be used to request that rpc.nfsd does not  offer
>         certain  versions of NFS. The current version of rpc.nfsd can
>         support both NFS version 2,3 and the newer version 4.

We definitely need something like this, thanks!  Though I would have
thought something like "--min-version" and "--max-version" would be more
natural.  (What do other OS's do?)

--b.


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 14:56 ` J. Bruce Fields
@ 2005-03-21 15:18   ` Trond Myklebust
  2005-03-21 15:59   ` Steve Dickson
  1 sibling, 0 replies; 13+ messages in thread
From: Trond Myklebust @ 2005-03-21 15:18 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Steve Dickson, Neil Brown, nfs

m=E5 den 21.03.2005 Klokka 09:56 (-0500) skreiv J. Bruce Fields:
> On Mon, Mar 21, 2005 at 09:42:11AM -0500, Steve Dickson wrote:
> >     -N  or  --no-nfs-version vers
> >         This option can be used to request that rpc.nfsd does not  offe=
r
> >         certain  versions of NFS. The current version of rpc.nfsd can
> >         support both NFS version 2,3 and the newer version 4.
>=20
> We definitely need something like this, thanks!  Though I would have
> thought something like "--min-version" and "--max-version" would be more
> natural.  (What do other OS's do?)

--min-version and --max-version are indeed more in line with the RPC
model: the PROG_MISMATCH error offers a single range of supported
versions, and was never designed to say that you are offering NFSv2 and
v4, but not NFSv3.

That said, we have already added the -N option to rpc.mountd, so if we
fix rpc.nfsd, then we should also fix rpc.mountd.

Cheers,
  Trond

--=20
Trond Myklebust <trond.myklebust@fys.uio.no>



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [KNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 14:42 [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more Steve Dickson
  2005-03-21 14:56 ` J. Bruce Fields
@ 2005-03-21 15:46 ` Chip Salzenberg
  2005-03-21 16:22   ` Steve Dickson
  2005-03-21 23:34 ` [kNFSD] " Neil Brown
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Chip Salzenberg @ 2005-03-21 15:46 UTC (permalink / raw)
  To: Steve Dickson; +Cc: Neil Brown, nfs

According to Steve Dickson:
>     -N  or  --no-nfs-version vers
>         This option can be used to request that rpc.nfsd does not  offer
>         certain  versions of NFS. The current version of rpc.nfsd can
>         support both NFS version 2,3 and the newer version 4.

Thanks very much for the patches, but would you please add on support
for the '-V' flag specifying the versions that should be allowed?

>     -T  or  --no-tcp
>         Disable rpc.nfsd from accepting TCP connections from clients.
> 
>     -U  or  --no-udp
>         Disable rpc.nfsd from accepting UDP connections from clients.

And could you please document when (if ever) these options would be
useful to an end user?

adTHANKSvance
-- 
Chip Salzenberg            - a.k.a. -            <chip@pobox.com>
         Open Source is not an excuse to write fun code
            then leave the actual work to others.


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 14:56 ` J. Bruce Fields
  2005-03-21 15:18   ` Trond Myklebust
@ 2005-03-21 15:59   ` Steve Dickson
  1 sibling, 0 replies; 13+ messages in thread
From: Steve Dickson @ 2005-03-21 15:59 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Neil Brown, nfs

J. Bruce Fields wrote:
> On Mon, Mar 21, 2005 at 09:42:11AM -0500, Steve Dickson wrote:
> 
>>    -N  or  --no-nfs-version vers
>>        This option can be used to request that rpc.nfsd does not  offer
>>        certain  versions of NFS. The current version of rpc.nfsd can
>>        support both NFS version 2,3 and the newer version 4.
> 
> 
> We definitely need something like this, thanks!  Though I would have
> thought something like "--min-version" and "--max-version" would be more
> natural.  (What do other OS's do?)
I was trying to keep the syntax similar to
what rpc.mountd uses. I figured it would be
easier to turn things on and off from a init
script point of view....

But if it makes more sense to do a min/max
type of thing, that could work too...

steved.


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [KNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 15:46 ` [KNFSD] " Chip Salzenberg
@ 2005-03-21 16:22   ` Steve Dickson
  2005-03-21 16:39     ` Chip Salzenberg
  0 siblings, 1 reply; 13+ messages in thread
From: Steve Dickson @ 2005-03-21 16:22 UTC (permalink / raw)
  To: Chip Salzenberg; +Cc: Neil Brown, nfs

Chip Salzenberg wrote:
> According to Steve Dickson:
> 
>>    -N  or  --no-nfs-version vers
>>        This option can be used to request that rpc.nfsd does not  offer
>>        certain  versions of NFS. The current version of rpc.nfsd can
>>        support both NFS version 2,3 and the newer version 4.
> 
> 
> Thanks very much for the patches, but would you please add on support
> for the '-V' flag specifying the versions that should be allowed?
Well since everything is on by default, I figured all that
was needed was a way to turn things off, but it would
be a non-issue to add.

> 
> 
>>    -T  or  --no-tcp
>>        Disable rpc.nfsd from accepting TCP connections from clients.
>>
>>    -U  or  --no-udp
>>        Disable rpc.nfsd from accepting UDP connections from clients.
> 
> 
> And could you please document when (if ever) these options would be
> useful to an end user?
I was thinking servers behind firewalls might want to
explicitly define one protocol or the other, just
to keep things simple and I know other servers have
these options.


steved.


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [KNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 16:22   ` Steve Dickson
@ 2005-03-21 16:39     ` Chip Salzenberg
  0 siblings, 0 replies; 13+ messages in thread
From: Chip Salzenberg @ 2005-03-21 16:39 UTC (permalink / raw)
  To: Steve Dickson; +Cc: Neil Brown, nfs

According to Steve Dickson:
> Chip Salzenberg wrote:
> >Thanks very much for the patches, but would you please add on support
> >for the '-V' flag specifying the versions that should be allowed?
> Well since everything is on by default, I figured all that
> was needed was a way to turn things off, but it would
> be a non-issue to add.

It's for future-proofing.  Suppose you only wanted to export NFSv3,
that's all.  You could say "-N 2" and that would be fine ... until
NFSv4 was invented, when you'd need "-N 2,4".  Spelling it as "-V 3"
is more stable for the long term.

> I was thinking servers behind firewalls might want to explicitly
> define one protocol or the other, just to keep things simple [...]

OK thanks.  A little doc patch might be helpful, if only along the
lines of "if you're not setting up firewall rules, these options
probably won't matter to you".
-- 
Chip Salzenberg            - a.k.a. -            <chip@pobox.com>
         Open Source is not an excuse to write fun code
            then leave the actual work to others.


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 14:42 [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more Steve Dickson
  2005-03-21 14:56 ` J. Bruce Fields
  2005-03-21 15:46 ` [KNFSD] " Chip Salzenberg
@ 2005-03-21 23:34 ` Neil Brown
  2005-03-22 10:17   ` Steve Dickson
                     ` (2 more replies)
  2005-03-22 15:01 ` Steve Dickson
  2005-03-23 11:56 ` Steve Dickson
  4 siblings, 3 replies; 13+ messages in thread
From: Neil Brown @ 2005-03-21 23:34 UTC (permalink / raw)
  To: Steve Dickson; +Cc: nfs

On Monday March 21, SteveD@redhat.com wrote:
> Hello,
> 
> The following patches fix the '-p port' command line
> argument to rpc.nfsd as well as adds following
> flags that control the NFS versions and transports that
> rpc.nfsd will use.

While this is all very good in principle, there are some details I'm
not comfortable with....
In particular, the kernel interface.
You have changed 
  /proc/fs/nfsd/threads
to contain not just threads information, but also port, protocol and
version information.

This is not good.

I would rather (I think) have two new files
   /proc/fs/nfsd/version
and
   /proc/fs/nfsd/ports

"version" should give a list of available versions, and which are
enabled, on read, and should enable or disable version on write.
e.g.
   # cat version
   -2 +3 -4

This means that versions 2, 3, and 4 are available. Only 3 is enabled.

   # echo +4 > version

This enables version 4 (if it is available).

"ports".... should we allow different protocols to use different
   ports?  2049 for tcp, but use 5123 for udp ???
   I think we should probably allow for distinguishing between ipv4
   and ipv6.
   And would we also want to allow binding to particular IP addresses
   ???? or multiple ports???

   Maybe a better interface is to open and bind a socket in userspace,
   and pass it down to the kernel.  Maybe not..

 How about the "ports" file contains lines:
   family:proto:address:port
 e.g.
   ipv4:udp:*:2049

 Where new entries can added one line at a time:
   echo "ipv4:tcp:*:5123" > /proc/fs/nfsd/ports
 and are all read at once.
   # cat  /proc/fs/nfsd/ports
   ipv4:udp:*:2049
   ipv4:tcp:*:2049
   #
 Initially, the only recognised address would be "*", and multiple
 ports of the same protocol would not be permitted (i.e. write(2)
 returns and error).

 A port could be disabled with
   echo "-ipv4:udp:*:2049" > /proc/fs/nfsd/ports
 maybe.
  
 When the first thread is started, if no ports are open, the default
 ports (2049 for ipv4:udp and ipv4:tcp) are openned, otherwise the
 current ports are used.

I'm happy to consider changes in syntax, but I really don't like
merging these very different concepts in the one file.

NeilBrown


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 23:34 ` [kNFSD] " Neil Brown
@ 2005-03-22 10:17   ` Steve Dickson
  2005-03-22 12:27   ` Steve Dickson
  2005-03-22 13:10   ` Steve Dickson
  2 siblings, 0 replies; 13+ messages in thread
From: Steve Dickson @ 2005-03-22 10:17 UTC (permalink / raw)
  To: Neil Brown; +Cc: nfs

Neil Brown wrote:
> I'm happy to consider changes in syntax, but I really don't like
> merging these very different concepts in the one file.

My initial thought is this adds much more complexity that
really needed... All that's needed is to set the port, version
and protocol. As soon as you added in address and address types,
it adds a hole new level complexity that may not be needed,
to solve this particular problem.

but let me take a closer took to see how much is truly need to
create a couple more proc files and well as the parsing
routines to handle theses type of syntaxes....

steved.



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 23:34 ` [kNFSD] " Neil Brown
  2005-03-22 10:17   ` Steve Dickson
@ 2005-03-22 12:27   ` Steve Dickson
  2005-03-22 13:10   ` Steve Dickson
  2 siblings, 0 replies; 13+ messages in thread
From: Steve Dickson @ 2005-03-22 12:27 UTC (permalink / raw)
  To: Neil Brown; +Cc: nfs

Neil Brown wrote:
> 
> I would rather (I think) have two new files
>    /proc/fs/nfsd/version
> and
>    /proc/fs/nfsd/ports
Hmm... I think there is a timing issue here.
These have to be set before threads since
write_threads() does the nfsd_svc(), true?

How about changing the name of the file rpc.nfsd
writes to? To something like /proc/fs/nfsd/config?

rpc.nfsd could write to nfsd/config which then could
cause the version, ports and threads files to have
the correct information....


steved.


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 23:34 ` [kNFSD] " Neil Brown
  2005-03-22 10:17   ` Steve Dickson
  2005-03-22 12:27   ` Steve Dickson
@ 2005-03-22 13:10   ` Steve Dickson
  2 siblings, 0 replies; 13+ messages in thread
From: Steve Dickson @ 2005-03-22 13:10 UTC (permalink / raw)
  To: Neil Brown; +Cc: nfs

Neil Brown wrote:
> 
> "ports".... should we allow different protocols to use different
>    ports?  2049 for tcp, but use 5123 for udp ???
I would not think so... How often has something like this
been needed in the past?

> 
>    Maybe a better interface is to open and bind a socket in userspace,
>    and pass it down to the kernel.  Maybe not..
True.... ;-)

> 
>  How about the "ports" file contains lines:
>    family:proto:address:port
>  e.g.
>    ipv4:udp:*:2049
Maybe a better name for the file should be 'address'?
since thats what we are defining....

> 
>  A port could be disabled with
>    echo "-ipv4:udp:*:2049" > /proc/fs/nfsd/ports
>  maybe.
hmm... I think I would rather just restart the server
verses disable something.... I just doesn't sound good ;-)

steved.





-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 14:42 [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more Steve Dickson
                   ` (2 preceding siblings ...)
  2005-03-21 23:34 ` [kNFSD] " Neil Brown
@ 2005-03-22 15:01 ` Steve Dickson
  2005-03-23 11:56 ` Steve Dickson
  4 siblings, 0 replies; 13+ messages in thread
From: Steve Dickson @ 2005-03-22 15:01 UTC (permalink / raw)
  To: nfs

[-- Attachment #1: Type: text/plain, Size: 472 bytes --]

Steve Dickson wrote:
> The following patches fix the '-p port' command line
> argument to rpc.nfsd as well as adds following
> flags that control the NFS versions and transports that
> rpc.nfsd will use.
Just for the sake of completion on this proposal, I've updated
the patches to introduce the -V flag and changed the name of the file
rpc.nfsd uses from threads, to config (i.e. /proc/fs/nfsd/config),
which does more accurately describes what is happening....

steved.

[-- Attachment #2: nfs-utils-1.0.7-nfsd-ctlbits2.patch --]
[-- Type: text/x-patch, Size: 7505 bytes --]

--- nfs-utils-1.0.7/support/include/nfs/nfs.h.orig	2003-07-02 22:09:31.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfs/nfs.h	2005-03-22 08:48:55.055423216 -0500
@@ -40,7 +40,14 @@ struct nfs_fh_old {
 #define NFSCTL_LOCKD		0x10000
 #define LOCKDCTL_SVC		NFSCTL_LOCKD
 
-
+#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |= (1 << ((_v) - 1)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) 
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1))) 
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1))) 
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) 
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1))) 
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1))) 
 
 /* SVC */
 struct nfsctl_svc {
--- nfs-utils-1.0.7/support/include/nfslib.h.orig	2004-09-14 21:58:40.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfslib.h	2005-03-17 09:02:15.000000000 -0500
@@ -118,7 +118,7 @@ int			wildmat(char *text, char *pattern)
  * nfsd library functions.
  */
 int			nfsctl(int, struct nfsctl_arg *, union nfsctl_res *);
-int			nfssvc(int port, int nrservs);
+int			nfssvc(int port, int nrservs, unsigned int ctlbits);
 int			nfsaddclient(struct nfsctl_client *clp);
 int			nfsdelclient(struct nfsctl_client *clp);
 int			nfsexport(struct nfsctl_export *exp);
--- nfs-utils-1.0.7/support/nfs/nfssvc.c.orig	2005-03-17 09:44:28.000000000 -0500
+++ nfs-utils-1.0.7/support/nfs/nfssvc.c	2005-03-22 09:29:34.956501872 -0500
@@ -14,27 +14,32 @@
 #include "nfslib.h"
 
 int
-nfssvc(int port, int nrservs)
+nfssvc(int port, int nrservs, unsigned ctlbits)
 {
 	struct nfsctl_arg	arg;
 	int fd;
 
-	fd = open("/proc/fs/nfsd/threads", O_WRONLY);
+	fd = open("/proc/fs/nfsd/config", O_WRONLY);
 	if (fd < 0)
 		fd = open("/proc/fs/nfs/threads", O_WRONLY);
 	if (fd >= 0) {
 		/* 2.5+ kernel with nfsd filesystem mounted.
 		 * Just write the number in.
-		 * Cannot handle port number yet, but does anyone care?
 		 */
-		char buf[20];
+		char buf[40];
 		int n;
-		snprintf(buf, 20,"%d\n", nrservs);
+		snprintf(buf, 40,"%d %d %d\n", nrservs, port, ctlbits);
 		n = write(fd, buf, strlen(buf));
 		close(fd);
-		if (n != strlen(buf))
-			return -1;
-		else
+		if (n != strlen(buf)) {
+			/*
+			 * See if this an older kernel that does not
+			 * have the ctlbits support
+			 */
+			snprintf(buf, 40, "%d\n", nrservs);
+			if (n != strlen(buf))
+				return -1;
+		} else
 			return 0;
 	}
 
--- nfs-utils-1.0.7/utils/mountd/mountd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/mountd/mountd.c	2005-03-19 11:57:38.000000000 -0500
@@ -255,6 +255,9 @@ mount_mnt_3_svc(struct svc_req *rqstp, d
 			= sizeof(flavors)/sizeof(flavors[0]);
 		ok->auth_flavors.auth_flavors_val = flavors;
 	}
+	if (fh == NULL || res->fhs_status)
+		xlog(D_CALL, "MNT3(%s) failed: status %d\n", res->fhs_status);
+
 	return 1;
 }
 
--- nfs-utils-1.0.7/utils/nfsd/nfsd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.c	2005-03-22 09:22:43.600037560 -0500
@@ -23,12 +23,25 @@
 
 static void	usage(const char *);
 
+static struct option longopts[] =
+{
+	{ "help", 0, 0, 'h' },
+	{ "nfs-version", 1, 0, 'V' },
+	{ "no-nfs-version", 1, 0, 'N' },
+	{ "no-tcp", 0, 0, 'T' },
+	{ "no-udp", 0, 0, 'U' },
+	{ "port", 1, 0, 'P' },
+	{ "port", 1, 0, 'p' },
+	{ NULL, 0, 0, 0 }
+};
+
 int
 main(int argc, char **argv)
 {
-	int	count = 1, c, error, port, fd;
+	int	count = 1, c, error, port, fd, found_one;
 	struct servent *ent;
 	DIR *dir;
+	unsigned int ctlbits = ~0;
 
 	ent = getservbyname ("nfs", "udp");
 	if (ent != NULL)
@@ -36,7 +49,7 @@ main(int argc, char **argv)
 	else
 		port = 2049;
 
-	while ((c = getopt(argc, argv, "hp:P:")) != EOF) {
+	while ((c = getopt_long(argc, argv, "hN:p:P:TUV:", longopts, NULL)) != EOF) {
 		switch(c) {
 		case 'P':	/* XXX for nfs-server compatibility */
 		case 'p':
@@ -47,12 +60,70 @@ main(int argc, char **argv)
 				usage(argv [0]);
 			}
 			break;
+		case 'N':
+			switch((c = atoi(optarg))) {
+			case 2:
+			case 3:
+			case 4:
+				NFSCTL_VERUNSET(ctlbits, c);
+				break;
+			default:
+				fprintf(stderr, "%c: Unsupported version\n", c);
+				exit(1);
+			}
+			break;
+		case 'T':
+			NFSCTL_TCPUNSET(ctlbits);
+			break;
+		case 'U':
+			NFSCTL_UDPUNSET(ctlbits);
+			break;
+		case 'V':
+			switch((c = atoi(optarg))) {
+			case 2:
+				NFSCTL_VERUNSET(ctlbits, 3);
+				NFSCTL_VERUNSET(ctlbits, 4);
+				break;
+			case 3:
+				NFSCTL_VERUNSET(ctlbits, 2);
+				NFSCTL_VERUNSET(ctlbits, 4);
+				break;
+			case 4:
+				NFSCTL_VERUNSET(ctlbits, 2);
+				NFSCTL_VERUNSET(ctlbits, 3);
+				break;
+			default:
+				fprintf(stderr, "%c: Unsupported version\n", c);
+				exit(1);
+			}
+			NFSCTL_VERSET(ctlbits, c);
 			break;
-		case 'h':
 		default:
+			fprintf(stderr, "Invalid argument: '%c'\n", c);
+		case 'h':
 			usage(argv[0]);
 		}
 	}
+	/*
+	 * Do some sanity checking, if the ctlbits are set
+	 */
+	if (!NFSCTL_UDPISSET(ctlbits) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "invalid protocol specified\n");
+		exit(1);
+	}
+	found_one = 0;
+	for (c = 2; c <= 4; c++) {
+		if (NFSCTL_VERISSET(ctlbits, c))
+			found_one = 1;
+	}
+	if (!found_one) {
+		fprintf(stderr, "no version specified\n");
+		exit(1);
+	}			
+	if (NFSCTL_VERISSET(ctlbits, 4) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "version 4 requires the TCP protocol\n");
+		exit(1);
+	}
 
 	if (chdir(NFS_STATEDIR)) {
 		fprintf(stderr, "%s: chdir(%s) failed: %s\n",
@@ -99,7 +170,7 @@ main(int argc, char **argv)
 			(void) close(fd);
 	}
 
-	if ((error = nfssvc(port, count)) < 0) {
+	if ((error = nfssvc(port, count, ctlbits)) < 0) {
 		int e = errno;
 		openlog("nfsd", LOG_PID, LOG_DAEMON);
 		syslog(LOG_ERR, "nfssvc: %s", strerror(e));
@@ -112,7 +183,8 @@ main(int argc, char **argv)
 static void
 usage(const char *prog)
 {
-	fprintf(stderr, "usage:\n"
-			"%s nrservs\n", prog);
+	fprintf(stderr, "Usage:\n"
+		"%s [-p|-P|--port] [-N|no-nfs-version] [-T|--no-tcp] [-U|--no-udp] nrservs\n", 
+		prog);
 	exit(2);
 }
--- nfs-utils-1.0.7/utils/nfsd/nfsd.man.orig	2002-08-26 12:57:59.000000000 -0400
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.man	2005-03-22 09:37:24.414133464 -0500
@@ -6,7 +6,7 @@
 .SH NAME
 rpc.nfsd \- NFS server process
 .SH SYNOPSIS
-.BI "/usr/sbin/rpc.nfsd [-p " port "] " nproc
+.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc
 .SH DESCRIPTION
 The
 .B rpc.nfsd
@@ -22,11 +22,35 @@ server provides an ancillary service nee
 by NFS clients.
 .SH OPTIONS
 .TP
-.BI \-p " port"
+.B \-p " or " \-\-port  port
 specify a diferent port to listen on for NFS requests. By default,
 .B rpc.nfsd
 will listen on port 2049.
 .TP
+.B \-N " or " \-\-no-nfs-version vers
+This option can be used to request that 
+.B rpc.nfsd
+do not offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support both NFS version 2,3 and the newer version 4.
+.TP
+.B \-T " or " \-\-no-tcp
+Disable 
+.B rpc.nfsd 
+from accepting TCP connections from clients.
+.TP
+.B \-U " or " \-\-no-udp
+Disable
+.B rpc.nfsd
+from accepting UDP connections from clients.
+.TP
+.B \-V " or " \-\-nfs-version
+This option can be used to request that
+.B rpc.nfsd
+offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support NFS version 2,3 and the newer version 4.
+.TP
 .I nproc
 specify the number of NFS server threads. By default, just one
 thread is started. However, for optimum performance several threads

[-- Attachment #3: linux-2.6.11-nfsd-ctlbits2.patch --]
[-- Type: text/x-patch, Size: 8929 bytes --]

--- linux-2.6.11/fs/nfsd/nfs4state.c.orig	2005-03-02 02:38:13.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfs4state.c	2005-03-18 06:59:15.000000000 -0500
@@ -3250,6 +3250,8 @@ __nfs4_state_shutdown(void)
 void
 nfs4_state_shutdown(void)
 {
+	if (!nfs4_init)
+		return;
 	nfs4_lock_state();
 	nfs4_release_reclaim();
 	__nfs4_state_shutdown();
--- linux-2.6.11/fs/nfsd/nfssvc.c.orig	2005-03-02 02:38:10.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfssvc.c	2005-03-18 08:39:53.000000000 -0500
@@ -30,6 +30,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
 #include <linux/lockd/bind.h>
 
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
@@ -62,6 +63,29 @@ struct nfsd_list {
 };
 struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
+
+static struct svc_version *	nfsd_version[] = {
+	[2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+	[3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+	[4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS    2
+#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+struct svc_program		nfsd_program = {
+	.pg_prog		= NFS_PROGRAM,		/* program number */
+	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
+	.pg_vers		= nfsd_version,	/* version table */
+	.pg_name		= "nfsd",		/* program name */
+	.pg_class		= "nfsd",		/* authentication class */
+	.pg_stats		= &nfsd_svcstats,	/* version table */
+};
+
 /*
  * Maximum number of nfsd processes
  */
@@ -76,23 +100,47 @@ int nfsd_nrthreads(void)
 }
 
 int
-nfsd_svc(unsigned short port, int nrservs)
+nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits)
 {
 	int	error;
-	int	none_left;	
+	int	none_left, found_one, i;
 	struct list_head *victim;
 	
+	dprintk("nfsd: creating service (port %d nserver %d ctlbits 0x%x)\n",
+		port, nrservs, ctlbits);
+
 	lock_kernel();
-	dprintk("nfsd: creating service\n");
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
 	if (nrservs > NFSD_MAXSERVS)
 		nrservs = NFSD_MAXSERVS;
-	
+	/*
+	 * If set, use the ctlbits to define the
+	 * services that will be advertised
+	 */
+	if (ctlbits) {
+		found_one = 0;
+		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+			if (NFSCTL_VERISSET(ctlbits, i)) {
+				nfsd_program.pg_vers[i] = nfsd_version[i]; 
+				found_one = 1;
+			} else
+				nfsd_program.pg_vers[i] = NULL;
+		}
+		if (!found_one) {
+			printk(KERN_ERR "nfsd: no version set (cltbits 0x%x)\n", ctlbits);
+			goto out;
+		}			
+	} else { /* otherwise, turn everthing on */
+		ctlbits = ~0;
+		nfsd_program.pg_vers = nfsd_version;
+	}
+
 	/* Readahead param cache - will no-op if it already exists */
 	error =	nfsd_racache_init(2*nrservs);
-	nfs4_state_init();
+	if (NFSCTL_VERISSET(ctlbits, 4))
+		nfs4_state_init();
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
@@ -101,14 +149,17 @@ nfsd_svc(unsigned short port, int nrserv
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
 		if (nfsd_serv == NULL)
 			goto out;
-		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-		if (error < 0)
-			goto failure;
-
+		if (NFSCTL_UDPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+			if (error < 0)
+				goto failure;
+		}
 #ifdef CONFIG_NFSD_TCP
-		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-		if (error < 0)
-			goto failure;
+		if (NFSCTL_TCPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+			if (error < 0)
+				goto failure;
+		}
 #endif
 		do_gettimeofday(&nfssvc_boot);		/* record boot time */
 	} else
@@ -358,24 +409,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u3
 	return 1;
 }
 
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version *	nfsd_version[] = {
-	[2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
-	[3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
-	[4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program		nfsd_program = {
-	.pg_prog		= NFS_PROGRAM,		/* program number */
-	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
-	.pg_vers		= nfsd_version,		/* version table */
-	.pg_name		= "nfsd",		/* program name */
-	.pg_class		= "nfsd",		/* authentication class */
-	.pg_stats		= &nfsd_svcstats,	/* version table */
-};
--- linux-2.6.11/fs/nfsd/nfsctl.c.orig	2005-03-18 07:21:19.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfsctl.c	2005-03-22 07:41:34.000000000 -0500
@@ -49,7 +49,7 @@ enum {
 	NFSD_Getfs,
 	NFSD_List,
 	NFSD_Fh,
-	NFSD_Threads,
+	NFSD_Config,
 	NFSD_Leasetime,
 };
 
@@ -64,7 +64,7 @@ static ssize_t write_unexport(struct fil
 static ssize_t write_getfd(struct file *file, char *buf, size_t size);
 static ssize_t write_getfs(struct file *file, char *buf, size_t size);
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
-static ssize_t write_threads(struct file *file, char *buf, size_t size);
+static ssize_t write_config(struct file *file, char *buf, size_t size);
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
@@ -76,7 +76,7 @@ static ssize_t (*write_op[])(struct file
 	[NFSD_Getfd] = write_getfd,
 	[NFSD_Getfs] = write_getfs,
 	[NFSD_Fh] = write_filehandle,
-	[NFSD_Threads] = write_threads,
+	[NFSD_Config] = write_config,
 	[NFSD_Leasetime] = write_leasetime,
 };
 
@@ -133,7 +133,7 @@ static ssize_t write_svc(struct file *fi
 	if (size < sizeof(*data))
 		return -EINVAL;
 	data = (struct nfsctl_svc*) buf;
-	return nfsd_svc(data->svc_port, data->svc_nthreads);
+	return nfsd_svc(data->svc_port, data->svc_nthreads, 0);
 }
 
 static ssize_t write_add(struct file *file, char *buf, size_t size)
@@ -304,13 +304,16 @@ static ssize_t write_filehandle(struct f
 
 extern int nfsd_nrthreads(void);
 
-static ssize_t write_threads(struct file *file, char *buf, size_t size)
+static ssize_t write_config(struct file *file, char *buf, size_t size)
 {
 	/* if size > 0, look for a number of threads and call nfsd_svc
 	 * then write out number of threads as reply
 	 */
 	char *mesg = buf;
 	int rv;
+	unsigned int ctlbits = 0;
+	unsigned int port = 0;
+
 	if (size > 0) {
 		int newthreads;
 		rv = get_int(&mesg, &newthreads);
@@ -318,11 +321,30 @@ static ssize_t write_threads(struct file
 			return rv;
 		if (newthreads <0)
 			return -EINVAL;
-		rv = nfsd_svc(2049, newthreads);
+		rv = get_int(&mesg, &port);
+		if (rv) {
+			/*
+			 * its possible the rpc.nfsd does not 
+			 * have the ctlbits support, so just 
+			 * fill in with default values 
+			 */
+			port = 2049;
+			ctlbits = ~0;
+			sprintf(buf, "%d\n", newthreads);
+		} else {
+			rv = get_int(&mesg, &ctlbits);
+			if (rv) {
+				ctlbits = ~0;
+				sprintf(buf, "%d %d\n", nfsd_nrthreads(), port);
+			} else
+				sprintf(buf, "%d %d %d\n", nfsd_nrthreads(), port, ctlbits);
+		}
+		rv = nfsd_svc((unsigned short)port, newthreads, ctlbits);
 		if (rv)
 			return rv;
-	}
-	sprintf(buf, "%d\n", nfsd_nrthreads());
+	} else 
+		sprintf(buf, "%d\n", nfsd_nrthreads());
+
 	return strlen(buf);
 }
 
@@ -366,7 +388,7 @@ static int nfsd_fill_super(struct super_
 		[NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
 		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
-		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Config] = {"config", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
 		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
 #endif
--- linux-2.6.11/include/linux/nfsd/syscall.h.orig	2005-03-02 02:38:38.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/syscall.h	2005-03-18 07:30:26.000000000 -0500
@@ -39,6 +39,14 @@
 #define NFSCTL_GETFD		7	/* get an fh by path (used by mountd) */
 #define	NFSCTL_GETFS		8	/* get an fh by path with max FH len */
 
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1)))
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1)))
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1)))
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1)))
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1)))
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1)))
+
 /* SVC */
 struct nfsctl_svc {
 	unsigned short		svc_port;
--- linux-2.6.11/include/linux/nfsd/nfsd.h.orig	2005-03-02 02:38:32.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/nfsd.h	2005-03-18 05:08:55.000000000 -0500
@@ -63,7 +63,7 @@ extern struct svc_version	nfsd_version2,
 /*
  * Function prototypes.
  */
-int		nfsd_svc(unsigned short port, int nrservs);
+int		nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits);
 int		nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp);
 
 /* nfsd/vfs.c */

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more.
  2005-03-21 14:42 [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more Steve Dickson
                   ` (3 preceding siblings ...)
  2005-03-22 15:01 ` Steve Dickson
@ 2005-03-23 11:56 ` Steve Dickson
  4 siblings, 0 replies; 13+ messages in thread
From: Steve Dickson @ 2005-03-23 11:56 UTC (permalink / raw)
  To: nfs

[-- Attachment #1: Type: text/plain, Size: 473 bytes --]

Steve Dickson wrote:
> The following patches fix the '-p port' command line
> argument to rpc.nfsd as well as adds following
> flags that control the NFS versions and transports that
> rpc.nfsd will use.
Just for the sake of completion on this proposal, I've updated
the patches to introduce the -V flag and changed the name of the file
rpc.nfsd uses from threads, to config (i.e. /proc/fs/nfsd/config),
which does more accurately describes what is happening....

steved.


[-- Attachment #2: nfs-utils-1.0.7-nfsd-ctlbits2.patch --]
[-- Type: text/x-patch, Size: 7506 bytes --]

--- nfs-utils-1.0.7/support/include/nfs/nfs.h.orig	2003-07-02 22:09:31.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfs/nfs.h	2005-03-22 08:48:55.055423216 -0500
@@ -40,7 +40,14 @@ struct nfs_fh_old {
 #define NFSCTL_LOCKD		0x10000
 #define LOCKDCTL_SVC		NFSCTL_LOCKD
 
-
+#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |= (1 << ((_v) - 1)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) 
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1))) 
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1))) 
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) 
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1))) 
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1))) 
 
 /* SVC */
 struct nfsctl_svc {
--- nfs-utils-1.0.7/support/include/nfslib.h.orig	2004-09-14 21:58:40.000000000 -0400
+++ nfs-utils-1.0.7/support/include/nfslib.h	2005-03-17 09:02:15.000000000 -0500
@@ -118,7 +118,7 @@ int			wildmat(char *text, char *pattern)
  * nfsd library functions.
  */
 int			nfsctl(int, struct nfsctl_arg *, union nfsctl_res *);
-int			nfssvc(int port, int nrservs);
+int			nfssvc(int port, int nrservs, unsigned int ctlbits);
 int			nfsaddclient(struct nfsctl_client *clp);
 int			nfsdelclient(struct nfsctl_client *clp);
 int			nfsexport(struct nfsctl_export *exp);
--- nfs-utils-1.0.7/support/nfs/nfssvc.c.orig	2005-03-17 09:44:28.000000000 -0500
+++ nfs-utils-1.0.7/support/nfs/nfssvc.c	2005-03-22 09:29:34.956501872 -0500
@@ -14,27 +14,32 @@
 #include "nfslib.h"
 
 int
-nfssvc(int port, int nrservs)
+nfssvc(int port, int nrservs, unsigned ctlbits)
 {
 	struct nfsctl_arg	arg;
 	int fd;
 
-	fd = open("/proc/fs/nfsd/threads", O_WRONLY);
+	fd = open("/proc/fs/nfsd/config", O_WRONLY);
 	if (fd < 0)
 		fd = open("/proc/fs/nfs/threads", O_WRONLY);
 	if (fd >= 0) {
 		/* 2.5+ kernel with nfsd filesystem mounted.
 		 * Just write the number in.
-		 * Cannot handle port number yet, but does anyone care?
 		 */
-		char buf[20];
+		char buf[40];
 		int n;
-		snprintf(buf, 20,"%d\n", nrservs);
+		snprintf(buf, 40,"%d %d %d\n", nrservs, port, ctlbits);
 		n = write(fd, buf, strlen(buf));
 		close(fd);
-		if (n != strlen(buf))
-			return -1;
-		else
+		if (n != strlen(buf)) {
+			/*
+			 * See if this an older kernel that does not
+			 * have the ctlbits support
+			 */
+			snprintf(buf, 40, "%d\n", nrservs);
+			if (n != strlen(buf))
+				return -1;
+		} else
 			return 0;
 	}
 
--- nfs-utils-1.0.7/utils/mountd/mountd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/mountd/mountd.c	2005-03-19 11:57:38.000000000 -0500
@@ -255,6 +255,9 @@ mount_mnt_3_svc(struct svc_req *rqstp, d
 			= sizeof(flavors)/sizeof(flavors[0]);
 		ok->auth_flavors.auth_flavors_val = flavors;
 	}
+	if (fh == NULL || res->fhs_status)
+		xlog(D_CALL, "MNT3(%s) failed: status %d\n", res->fhs_status);
+
 	return 1;
 }
 
--- nfs-utils-1.0.7/utils/nfsd/nfsd.c.orig	2005-03-17 07:30:36.000000000 -0500
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.c	2005-03-22 09:22:43.600037560 -0500
@@ -23,12 +23,25 @@
 
 static void	usage(const char *);
 
+static struct option longopts[] =
+{
+	{ "help", 0, 0, 'h' },
+	{ "nfs-version", 1, 0, 'V' },
+	{ "no-nfs-version", 1, 0, 'N' },
+	{ "no-tcp", 0, 0, 'T' },
+	{ "no-udp", 0, 0, 'U' },
+	{ "port", 1, 0, 'P' },
+	{ "port", 1, 0, 'p' },
+	{ NULL, 0, 0, 0 }
+};
+
 int
 main(int argc, char **argv)
 {
-	int	count = 1, c, error, port, fd;
+	int	count = 1, c, error, port, fd, found_one;
 	struct servent *ent;
 	DIR *dir;
+	unsigned int ctlbits = ~0;
 
 	ent = getservbyname ("nfs", "udp");
 	if (ent != NULL)
@@ -36,7 +49,7 @@ main(int argc, char **argv)
 	else
 		port = 2049;
 
-	while ((c = getopt(argc, argv, "hp:P:")) != EOF) {
+	while ((c = getopt_long(argc, argv, "hN:p:P:TUV:", longopts, NULL)) != EOF) {
 		switch(c) {
 		case 'P':	/* XXX for nfs-server compatibility */
 		case 'p':
@@ -47,12 +60,70 @@ main(int argc, char **argv)
 				usage(argv [0]);
 			}
 			break;
+		case 'N':
+			switch((c = atoi(optarg))) {
+			case 2:
+			case 3:
+			case 4:
+				NFSCTL_VERUNSET(ctlbits, c);
+				break;
+			default:
+				fprintf(stderr, "%c: Unsupported version\n", c);
+				exit(1);
+			}
+			break;
+		case 'T':
+			NFSCTL_TCPUNSET(ctlbits);
+			break;
+		case 'U':
+			NFSCTL_UDPUNSET(ctlbits);
+			break;
+		case 'V':
+			switch((c = atoi(optarg))) {
+			case 2:
+				NFSCTL_VERUNSET(ctlbits, 3);
+				NFSCTL_VERUNSET(ctlbits, 4);
+				break;
+			case 3:
+				NFSCTL_VERUNSET(ctlbits, 2);
+				NFSCTL_VERUNSET(ctlbits, 4);
+				break;
+			case 4:
+				NFSCTL_VERUNSET(ctlbits, 2);
+				NFSCTL_VERUNSET(ctlbits, 3);
+				break;
+			default:
+				fprintf(stderr, "%c: Unsupported version\n", c);
+				exit(1);
+			}
+			NFSCTL_VERSET(ctlbits, c);
 			break;
-		case 'h':
 		default:
+			fprintf(stderr, "Invalid argument: '%c'\n", c);
+		case 'h':
 			usage(argv[0]);
 		}
 	}
+	/*
+	 * Do some sanity checking, if the ctlbits are set
+	 */
+	if (!NFSCTL_UDPISSET(ctlbits) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "invalid protocol specified\n");
+		exit(1);
+	}
+	found_one = 0;
+	for (c = 2; c <= 4; c++) {
+		if (NFSCTL_VERISSET(ctlbits, c))
+			found_one = 1;
+	}
+	if (!found_one) {
+		fprintf(stderr, "no version specified\n");
+		exit(1);
+	}			
+	if (NFSCTL_VERISSET(ctlbits, 4) && !NFSCTL_TCPISSET(ctlbits)) {
+		fprintf(stderr, "version 4 requires the TCP protocol\n");
+		exit(1);
+	}
 
 	if (chdir(NFS_STATEDIR)) {
 		fprintf(stderr, "%s: chdir(%s) failed: %s\n",
@@ -99,7 +170,7 @@ main(int argc, char **argv)
 			(void) close(fd);
 	}
 
-	if ((error = nfssvc(port, count)) < 0) {
+	if ((error = nfssvc(port, count, ctlbits)) < 0) {
 		int e = errno;
 		openlog("nfsd", LOG_PID, LOG_DAEMON);
 		syslog(LOG_ERR, "nfssvc: %s", strerror(e));
@@ -112,7 +183,8 @@ main(int argc, char **argv)
 static void
 usage(const char *prog)
 {
-	fprintf(stderr, "usage:\n"
-			"%s nrservs\n", prog);
+	fprintf(stderr, "Usage:\n"
+		"%s [-p|-P|--port] [-N|no-nfs-version] [-T|--no-tcp] [-U|--no-udp] nrservs\n", 
+		prog);
 	exit(2);
 }
--- nfs-utils-1.0.7/utils/nfsd/nfsd.man.orig	2002-08-26 12:57:59.000000000 -0400
+++ nfs-utils-1.0.7/utils/nfsd/nfsd.man	2005-03-22 09:37:24.414133464 -0500
@@ -6,7 +6,7 @@
 .SH NAME
 rpc.nfsd \- NFS server process
 .SH SYNOPSIS
-.BI "/usr/sbin/rpc.nfsd [-p " port "] " nproc
+.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc
 .SH DESCRIPTION
 The
 .B rpc.nfsd
@@ -22,11 +22,35 @@ server provides an ancillary service nee
 by NFS clients.
 .SH OPTIONS
 .TP
-.BI \-p " port"
+.B \-p " or " \-\-port  port
 specify a diferent port to listen on for NFS requests. By default,
 .B rpc.nfsd
 will listen on port 2049.
 .TP
+.B \-N " or " \-\-no-nfs-version vers
+This option can be used to request that 
+.B rpc.nfsd
+do not offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support both NFS version 2,3 and the newer version 4.
+.TP
+.B \-T " or " \-\-no-tcp
+Disable 
+.B rpc.nfsd 
+from accepting TCP connections from clients.
+.TP
+.B \-U " or " \-\-no-udp
+Disable
+.B rpc.nfsd
+from accepting UDP connections from clients.
+.TP
+.B \-V " or " \-\-nfs-version
+This option can be used to request that
+.B rpc.nfsd
+offer certain versions of NFS. The current version of
+.B rpc.nfsd
+can support NFS version 2,3 and the newer version 4.
+.TP
 .I nproc
 specify the number of NFS server threads. By default, just one
 thread is started. However, for optimum performance several threads


[-- Attachment #3: linux-2.6.11-nfsd-ctlbits2.patch --]
[-- Type: text/x-patch, Size: 8930 bytes --]

--- linux-2.6.11/fs/nfsd/nfs4state.c.orig	2005-03-02 02:38:13.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfs4state.c	2005-03-18 06:59:15.000000000 -0500
@@ -3250,6 +3250,8 @@ __nfs4_state_shutdown(void)
 void
 nfs4_state_shutdown(void)
 {
+	if (!nfs4_init)
+		return;
 	nfs4_lock_state();
 	nfs4_release_reclaim();
 	__nfs4_state_shutdown();
--- linux-2.6.11/fs/nfsd/nfssvc.c.orig	2005-03-02 02:38:10.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfssvc.c	2005-03-18 08:39:53.000000000 -0500
@@ -30,6 +30,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
 #include <linux/lockd/bind.h>
 
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
@@ -62,6 +63,29 @@ struct nfsd_list {
 };
 struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
+
+static struct svc_version *	nfsd_version[] = {
+	[2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+	[3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+	[4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS    2
+#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+struct svc_program		nfsd_program = {
+	.pg_prog		= NFS_PROGRAM,		/* program number */
+	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
+	.pg_vers		= nfsd_version,	/* version table */
+	.pg_name		= "nfsd",		/* program name */
+	.pg_class		= "nfsd",		/* authentication class */
+	.pg_stats		= &nfsd_svcstats,	/* version table */
+};
+
 /*
  * Maximum number of nfsd processes
  */
@@ -76,23 +100,47 @@ int nfsd_nrthreads(void)
 }
 
 int
-nfsd_svc(unsigned short port, int nrservs)
+nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits)
 {
 	int	error;
-	int	none_left;	
+	int	none_left, found_one, i;
 	struct list_head *victim;
 	
+	dprintk("nfsd: creating service (port %d nserver %d ctlbits 0x%x)\n",
+		port, nrservs, ctlbits);
+
 	lock_kernel();
-	dprintk("nfsd: creating service\n");
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
 	if (nrservs > NFSD_MAXSERVS)
 		nrservs = NFSD_MAXSERVS;
-	
+	/*
+	 * If set, use the ctlbits to define the
+	 * services that will be advertised
+	 */
+	if (ctlbits) {
+		found_one = 0;
+		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+			if (NFSCTL_VERISSET(ctlbits, i)) {
+				nfsd_program.pg_vers[i] = nfsd_version[i]; 
+				found_one = 1;
+			} else
+				nfsd_program.pg_vers[i] = NULL;
+		}
+		if (!found_one) {
+			printk(KERN_ERR "nfsd: no version set (cltbits 0x%x)\n", ctlbits);
+			goto out;
+		}			
+	} else { /* otherwise, turn everthing on */
+		ctlbits = ~0;
+		nfsd_program.pg_vers = nfsd_version;
+	}
+
 	/* Readahead param cache - will no-op if it already exists */
 	error =	nfsd_racache_init(2*nrservs);
-	nfs4_state_init();
+	if (NFSCTL_VERISSET(ctlbits, 4))
+		nfs4_state_init();
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
@@ -101,14 +149,17 @@ nfsd_svc(unsigned short port, int nrserv
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
 		if (nfsd_serv == NULL)
 			goto out;
-		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-		if (error < 0)
-			goto failure;
-
+		if (NFSCTL_UDPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+			if (error < 0)
+				goto failure;
+		}
 #ifdef CONFIG_NFSD_TCP
-		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-		if (error < 0)
-			goto failure;
+		if (NFSCTL_TCPISSET(ctlbits)) {
+			error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+			if (error < 0)
+				goto failure;
+		}
 #endif
 		do_gettimeofday(&nfssvc_boot);		/* record boot time */
 	} else
@@ -358,24 +409,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u3
 	return 1;
 }
 
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version *	nfsd_version[] = {
-	[2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
-	[3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
-	[4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program		nfsd_program = {
-	.pg_prog		= NFS_PROGRAM,		/* program number */
-	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
-	.pg_vers		= nfsd_version,		/* version table */
-	.pg_name		= "nfsd",		/* program name */
-	.pg_class		= "nfsd",		/* authentication class */
-	.pg_stats		= &nfsd_svcstats,	/* version table */
-};
--- linux-2.6.11/fs/nfsd/nfsctl.c.orig	2005-03-18 07:21:19.000000000 -0500
+++ linux-2.6.11/fs/nfsd/nfsctl.c	2005-03-22 07:41:34.000000000 -0500
@@ -49,7 +49,7 @@ enum {
 	NFSD_Getfs,
 	NFSD_List,
 	NFSD_Fh,
-	NFSD_Threads,
+	NFSD_Config,
 	NFSD_Leasetime,
 };
 
@@ -64,7 +64,7 @@ static ssize_t write_unexport(struct fil
 static ssize_t write_getfd(struct file *file, char *buf, size_t size);
 static ssize_t write_getfs(struct file *file, char *buf, size_t size);
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
-static ssize_t write_threads(struct file *file, char *buf, size_t size);
+static ssize_t write_config(struct file *file, char *buf, size_t size);
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
@@ -76,7 +76,7 @@ static ssize_t (*write_op[])(struct file
 	[NFSD_Getfd] = write_getfd,
 	[NFSD_Getfs] = write_getfs,
 	[NFSD_Fh] = write_filehandle,
-	[NFSD_Threads] = write_threads,
+	[NFSD_Config] = write_config,
 	[NFSD_Leasetime] = write_leasetime,
 };
 
@@ -133,7 +133,7 @@ static ssize_t write_svc(struct file *fi
 	if (size < sizeof(*data))
 		return -EINVAL;
 	data = (struct nfsctl_svc*) buf;
-	return nfsd_svc(data->svc_port, data->svc_nthreads);
+	return nfsd_svc(data->svc_port, data->svc_nthreads, 0);
 }
 
 static ssize_t write_add(struct file *file, char *buf, size_t size)
@@ -304,13 +304,16 @@ static ssize_t write_filehandle(struct f
 
 extern int nfsd_nrthreads(void);
 
-static ssize_t write_threads(struct file *file, char *buf, size_t size)
+static ssize_t write_config(struct file *file, char *buf, size_t size)
 {
 	/* if size > 0, look for a number of threads and call nfsd_svc
 	 * then write out number of threads as reply
 	 */
 	char *mesg = buf;
 	int rv;
+	unsigned int ctlbits = 0;
+	unsigned int port = 0;
+
 	if (size > 0) {
 		int newthreads;
 		rv = get_int(&mesg, &newthreads);
@@ -318,11 +321,30 @@ static ssize_t write_threads(struct file
 			return rv;
 		if (newthreads <0)
 			return -EINVAL;
-		rv = nfsd_svc(2049, newthreads);
+		rv = get_int(&mesg, &port);
+		if (rv) {
+			/*
+			 * its possible the rpc.nfsd does not 
+			 * have the ctlbits support, so just 
+			 * fill in with default values 
+			 */
+			port = 2049;
+			ctlbits = ~0;
+			sprintf(buf, "%d\n", newthreads);
+		} else {
+			rv = get_int(&mesg, &ctlbits);
+			if (rv) {
+				ctlbits = ~0;
+				sprintf(buf, "%d %d\n", nfsd_nrthreads(), port);
+			} else
+				sprintf(buf, "%d %d %d\n", nfsd_nrthreads(), port, ctlbits);
+		}
+		rv = nfsd_svc((unsigned short)port, newthreads, ctlbits);
 		if (rv)
 			return rv;
-	}
-	sprintf(buf, "%d\n", nfsd_nrthreads());
+	} else 
+		sprintf(buf, "%d\n", nfsd_nrthreads());
+
 	return strlen(buf);
 }
 
@@ -366,7 +388,7 @@ static int nfsd_fill_super(struct super_
 		[NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
 		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
-		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Config] = {"config", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
 		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
 #endif
--- linux-2.6.11/include/linux/nfsd/syscall.h.orig	2005-03-02 02:38:38.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/syscall.h	2005-03-18 07:30:26.000000000 -0500
@@ -39,6 +39,14 @@
 #define NFSCTL_GETFD		7	/* get an fh by path (used by mountd) */
 #define	NFSCTL_GETFS		8	/* get an fh by path with max FH len */
 
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1)))
+#define NFSCTL_UDPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (17 - 1)))
+#define NFSCTL_TCPUNSET(_cltbits)     ((_cltbits) &= ~(1 << (18 - 1)))
+
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1)))
+#define NFSCTL_UDPISSET(_cltbits)     ((_cltbits) & (1 << (17 - 1)))
+#define NFSCTL_TCPISSET(_cltbits)     ((_cltbits) & (1 << (18 - 1)))
+
 /* SVC */
 struct nfsctl_svc {
 	unsigned short		svc_port;
--- linux-2.6.11/include/linux/nfsd/nfsd.h.orig	2005-03-02 02:38:32.000000000 -0500
+++ linux-2.6.11/include/linux/nfsd/nfsd.h	2005-03-18 05:08:55.000000000 -0500
@@ -63,7 +63,7 @@ extern struct svc_version	nfsd_version2,
 /*
  * Function prototypes.
  */
-int		nfsd_svc(unsigned short port, int nrservs);
+int		nfsd_svc(unsigned short port, int nrservs, unsigned int ctlbits);
 int		nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp);
 
 /* nfsd/vfs.c */


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2005-03-23 11:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-21 14:42 [kNFSD] [PATCH] fixed '-p port' arg to rpc.nfsd plus more Steve Dickson
2005-03-21 14:56 ` J. Bruce Fields
2005-03-21 15:18   ` Trond Myklebust
2005-03-21 15:59   ` Steve Dickson
2005-03-21 15:46 ` [KNFSD] " Chip Salzenberg
2005-03-21 16:22   ` Steve Dickson
2005-03-21 16:39     ` Chip Salzenberg
2005-03-21 23:34 ` [kNFSD] " Neil Brown
2005-03-22 10:17   ` Steve Dickson
2005-03-22 12:27   ` Steve Dickson
2005-03-22 13:10   ` Steve Dickson
2005-03-22 15:01 ` Steve Dickson
2005-03-23 11:56 ` Steve Dickson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox