All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd
@ 2006-07-03  6:19 NeilBrown
  2006-07-03  6:19 ` [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes NeilBrown
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: NeilBrown @ 2006-07-03  6:19 UTC (permalink / raw)
  To: nfs

The following 6 patches are an RFC.  I'm not sending them to Andrew yet, but
plan to once the current merge window closes.

They allow fine control over what sockets nfsd listens on (userspace and
open a socket and pass the fd down - nfs-utils-1.0.9 will support this).
They allow course control over what sockets lockd listens on.
Lockd will only listen on a protocol that either:

 nfs is using for a mount
 nfsd is listening on
 a specific port was given as a module parameter.

Steve Dickson @ redhat helped with/motivated some of this development.

Comments welcome.

Thanks,
NeilBrown


 [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
 [PATCH 002 of 6] knfsd: Be more selective in which sockets lockd listens on.
 [PATCH 003 of 6] knfsd: Remove nfsd_versbits as intermediate storage for desired versions.
 [PATCH 004 of 6] knfsd: Separate out some parts of nfsd_svc, which start nfs servers.
 [PATCH 005 of 6] knfsd: Define new nfsdfs file: portlist - contains list of ports.
 [PATCH 006 of 6] knfsd: Allow sockets to be passed to nfsd via 'portlist'

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
  2006-07-03  6:19 [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd NeilBrown
@ 2006-07-03  6:19 ` NeilBrown
  2006-07-03 22:12   ` Christoph Hellwig
  2006-07-03  6:19 ` [PATCH 002 of 6] knfsd: Be more selective in which sockets lockd listens on NeilBrown
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: NeilBrown @ 2006-07-03  6:19 UTC (permalink / raw)
  To: nfs


nfsd has some cleanup that it wants to do when the last thread
exits, and there will shortly be some more.
So collect this all into one place and define a callback for
an rpc service to call when the service is about to be destroyed.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/lockd/svc.c             |    2 +-
 ./fs/nfsd/nfssvc.c           |   39 +++++++++++++++++----------------------
 ./include/linux/sunrpc/svc.h |    8 +++++++-
 ./net/sunrpc/svc.c           |    7 ++++++-
 4 files changed, 31 insertions(+), 25 deletions(-)

diff .prev/fs/lockd/svc.c ./fs/lockd/svc.c
--- .prev/fs/lockd/svc.c	2006-07-03 12:23:23.000000000 +1000
+++ ./fs/lockd/svc.c	2006-07-03 12:19:59.000000000 +1000
@@ -236,7 +236,7 @@ lockd_up(void)
 			"lockd_up: no pid, %d users??\n", nlmsvc_users);
 
 	error = -ENOMEM;
-	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE);
+	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
 	if (!serv) {
 		printk(KERN_WARNING "lockd_up: create service failed\n");
 		goto out;

diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c	2006-07-03 12:23:23.000000000 +1000
+++ ./fs/nfsd/nfssvc.c	2006-07-03 12:23:42.000000000 +1000
@@ -130,11 +130,25 @@ int nfsd_nrthreads(void)
 		return nfsd_serv->sv_nrthreads;
 }
 
+static int killsig = 0; /* signal that was used to kill last nfsd */
+static void nfsd_last_thread(struct svc_serv *serv)
+{
+	/* When last nfsd thread exits we need to do some clean-up */
+	nfsd_serv = NULL;
+	nfsd_racache_shutdown();
+	nfs4_state_shutdown();
+
+	printk(KERN_WARNING "nfsd: last server has exited\n");
+	if (killsig != SIG_NOCLEAN) {
+		printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
+		nfsd_export_flush();
+	}
+}
 int
 nfsd_svc(unsigned short port, int nrservs)
 {
 	int	error;
-	int	none_left, found_one, i;
+	int	found_one, i;
 	struct list_head *victim;
 	
 	lock_kernel();
@@ -197,7 +211,7 @@ nfsd_svc(unsigned short port, int nrserv
 
 		atomic_set(&nfsd_busy, 0);
 		error = -ENOMEM;
-		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
+		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, nfsd_last_thread);
 		if (nfsd_serv == NULL)
 			goto out;
 		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
@@ -231,13 +245,7 @@ nfsd_svc(unsigned short port, int nrserv
 		nrservs++;
 	}
  failure:
-	none_left = (nfsd_serv->sv_nrthreads == 1);
 	svc_destroy(nfsd_serv);		/* Release server */
-	if (none_left) {
-		nfsd_serv = NULL;
-		nfsd_racache_shutdown();
-		nfs4_state_shutdown();
-	}
  out:
 	unlock_kernel();
 	return error;
@@ -353,7 +361,7 @@ nfsd(struct svc_rqst *rqstp)
 			if (sigismember(&current->pending.signal, signo) &&
 			    !sigismember(&current->blocked, signo))
 				break;
-		err = signo;
+		killsig = signo;
 	}
 	/* Clear signals before calling lockd_down() and svc_exit_thread() */
 	flush_signals(current);
@@ -362,19 +370,6 @@ nfsd(struct svc_rqst *rqstp)
 
 	/* Release lockd */
 	lockd_down();
-
-	/* Check if this is last thread */
-	if (serv->sv_nrthreads==1) {
-		
-		printk(KERN_WARNING "nfsd: last server has exited\n");
-		if (err != SIG_NOCLEAN) {
-			printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
-			nfsd_export_flush();
-		}
-		nfsd_serv = NULL;
-	        nfsd_racache_shutdown();	/* release read-ahead cache */
-		nfs4_state_shutdown();
-	}
 	list_del(&me.list);
 	nfsdstats.th_cnt --;
 

diff .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c
--- .prev/net/sunrpc/svc.c	2006-07-03 12:23:23.000000000 +1000
+++ ./net/sunrpc/svc.c	2006-07-03 12:15:14.000000000 +1000
@@ -26,7 +26,8 @@
  * Create an RPC service
  */
 struct svc_serv *
-svc_create(struct svc_program *prog, unsigned int bufsize)
+svc_create(struct svc_program *prog, unsigned int bufsize,
+	   void (*shutdown)(struct svc_serv *serv))
 {
 	struct svc_serv	*serv;
 	int vers;
@@ -40,6 +41,7 @@ svc_create(struct svc_program *prog, uns
 	serv->sv_nrthreads = 1;
 	serv->sv_stats     = prog->pg_stats;
 	serv->sv_bufsz	   = bufsize? bufsize : 4096;
+	serv->sv_shutdown  = shutdown;
 	xdrsize = 0;
 	while (prog) {
 		prog->pg_lovers = prog->pg_nvers-1;
@@ -92,6 +94,9 @@ svc_destroy(struct svc_serv *serv)
 				  sk_list);
 		svc_delete_socket(svsk);
 	}
+	if (serv->sv_shutdown)
+		serv->sv_shutdown(serv);
+
 	while (!list_empty(&serv->sv_permsocks)) {
 		svsk = list_entry(serv->sv_permsocks.next,
 				  struct svc_sock,

diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h	2006-07-03 12:23:23.000000000 +1000
+++ ./include/linux/sunrpc/svc.h	2006-07-03 12:03:25.000000000 +1000
@@ -42,6 +42,11 @@ struct svc_serv {
 	int			sv_tmpcnt;	/* count of temporary sockets */
 
 	char *			sv_name;	/* service name */
+
+	void			(*sv_shutdown)(struct svc_serv *serv);
+						/* Callback to use when last thread
+						 * exits.
+						 */
 };
 
 /*
@@ -311,7 +316,8 @@ typedef void		(*svc_thread_fn)(struct sv
 /*
  * Function prototypes.
  */
-struct svc_serv *  svc_create(struct svc_program *, unsigned int);
+struct svc_serv *  svc_create(struct svc_program *, unsigned int,
+			      void (*shutdown)(struct svc_serv*));
 int		   svc_create_thread(svc_thread_fn, struct svc_serv *);
 void		   svc_exit_thread(struct svc_rqst *);
 void		   svc_destroy(struct svc_serv *);

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 002 of 6] knfsd: Be more selective in which sockets lockd listens on.
  2006-07-03  6:19 [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd NeilBrown
  2006-07-03  6:19 ` [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes NeilBrown
@ 2006-07-03  6:19 ` NeilBrown
  2006-07-03  6:19 ` [PATCH 003 of 6] knfsd: Remove nfsd_versbits as intermediate storage for desired versions NeilBrown
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2006-07-03  6:19 UTC (permalink / raw)
  To: nfs


Currently lockd listens on UDP always, and TCP if CONFIG_NFSD_TCP 
is set.

However as lockd performs services of the client as well, this is a
problem.  If CONFIG_NfSD_TCP is not set, and a tcp mount is used, the
server will not be able to call back to lockd.

So:
 - add an option to lockd_up saying which protocol is needed
 - Always open sockets for which an explicit port was given, otherwise
   only open a socket of the type required
 - Change nfsd to do one lockd_up per socket rather than one per thread.

This
 - removes the dependancy on CONFIG_NFSD_TCP
 - means that lockd may open sockets other than at startup
 - means that lockd will *not* listen on UDP if the only
   mounts are TCP mount (and nfsd hasn't started).

The latter is the only one that concerns me at all - I don't know if
this might be a problem with some servers.


Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/lockd/clntlock.c        |    2 -
 ./fs/lockd/svc.c             |   47 ++++++++++++++++++++++++++++++++++++-------
 ./fs/nfs/super.c             |    6 +++--
 ./fs/nfsd/nfssvc.c           |   16 +++++++++-----
 ./include/linux/lockd/bind.h |    2 -
 5 files changed, 56 insertions(+), 17 deletions(-)

diff .prev/fs/lockd/clntlock.c ./fs/lockd/clntlock.c
--- .prev/fs/lockd/clntlock.c	2006-07-03 12:32:30.000000000 +1000
+++ ./fs/lockd/clntlock.c	2006-07-03 12:24:17.000000000 +1000
@@ -202,7 +202,7 @@ reclaimer(void *ptr)
 	/* This one ensures that our parent doesn't terminate while the
 	 * reclaim is in progress */
 	lock_kernel();
-	lockd_up();
+	lockd_up(0);
 
 	nlmclnt_prepare_reclaim(host);
 	/* First, reclaim all locks that have been marked. */

diff .prev/fs/lockd/svc.c ./fs/lockd/svc.c
--- .prev/fs/lockd/svc.c	2006-07-03 12:32:30.000000000 +1000
+++ ./fs/lockd/svc.c	2006-07-03 12:43:02.000000000 +1000
@@ -31,6 +31,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
+#include <net/ip.h>
 #include <linux/lockd/lockd.h>
 #include <linux/nfs.h>
 
@@ -46,6 +47,7 @@ EXPORT_SYMBOL(nlmsvc_ops);
 static DEFINE_MUTEX(nlmsvc_mutex);
 static unsigned int		nlmsvc_users;
 static pid_t			nlmsvc_pid;
+static struct svc_serv		*nlmsvc_serv;
 int				nlmsvc_grace_period;
 unsigned long			nlmsvc_timeout;
 
@@ -112,6 +114,7 @@ lockd(struct svc_rqst *rqstp)
 	 * Let our maker know we're running.
 	 */
 	nlmsvc_pid = current->pid;
+	nlmsvc_serv = serv;
 	complete(&lockd_start_done);
 
 	daemonize("lockd");
@@ -189,6 +192,7 @@ lockd(struct svc_rqst *rqstp)
 			nlmsvc_invalidate_all();
 		nlm_shutdown_hosts();
 		nlmsvc_pid = 0;
+		nlmsvc_serv = NULL;
 	} else
 		printk(KERN_DEBUG
 			"lockd: new process, skipping host shutdown\n");
@@ -205,11 +209,42 @@ lockd(struct svc_rqst *rqstp)
 	module_put_and_exit(0);
 }
 
+
+static int find_socket(struct svc_serv *serv, int proto)
+{
+	struct svc_sock *svsk;
+	int found = 0;
+	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+		if (svsk->sk_sk->sk_protocol == proto) {
+			found = 1;
+			break;
+		}
+	return found;
+}
+
+static int make_socks(struct svc_serv *serv, int proto)
+{
+	/* Make any sockets that are needed but not present.
+	 * If nlm_udpport or nlm_tcpport were set as module
+	 * options, make those sockets unconditionally
+	 */
+	int err = 0;
+	if (proto == IPPROTO_UDP || nlm_udpport)
+		if (!find_socket(serv, IPPROTO_UDP))
+			err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport);
+	if (err)
+		return err;
+	if (proto == IPPROTO_TCP || nlm_tcpport)
+		if (!find_socket(serv, IPPROTO_TCP))
+			err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport);
+	return err;
+}
+
 /*
  * Bring up the lockd process if it's not already up.
  */
 int
-lockd_up(void)
+lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
 {
 	static int		warned;
 	struct svc_serv *	serv;
@@ -224,8 +259,10 @@ lockd_up(void)
 	/*
 	 * Check whether we're already up and running.
 	 */
-	if (nlmsvc_pid)
+	if (nlmsvc_pid) {
+		error = make_socks(nlmsvc_serv, proto);
 		goto out;
+	}
 
 	/*
 	 * Sanity check: if there's no pid,
@@ -242,11 +279,7 @@ lockd_up(void)
 		goto out;
 	}
 
-	if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0 
-#ifdef CONFIG_NFSD_TCP
-	 || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0
-#endif
-		) {
+	if ((error = make_socks(serv, proto)) < 0) {
 		if (warned++ == 0) 
 			printk(KERN_WARNING
 				"lockd_up: makesock failed, error=%d\n", error);

diff .prev/fs/nfs/super.c ./fs/nfs/super.c
--- .prev/fs/nfs/super.c	2006-07-03 12:32:30.000000000 +1000
+++ ./fs/nfs/super.c	2006-07-03 12:44:25.000000000 +1000
@@ -867,7 +867,8 @@ nfs_fill_super(struct super_block *sb, s
 
 	/* Start lockd here, before we might error out */
 	if (!(server->flags & NFS_MOUNT_NONLM))
-		lockd_up();
+		lockd_up((server->flags & NFS_MOUNT_TCP)
+			 ? IPPROTO_TCP : IPPROTO_UDP);
 
 	server->namelen  = data->namlen;
 	server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL);
@@ -1110,7 +1111,8 @@ static struct super_block *nfs_clone_sb(
 	nfs_copy_fh(&server->fh, data->fh);
 	sb = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
 	if (!IS_ERR(sb) && sb->s_root == NULL && !(server->flags & NFS_MOUNT_NONLM))
-		lockd_up();
+		lockd_up((server->flags & NFS_MOUNT_TCP)
+			 ? IPPROTO_TCP : IPPROTO_UDP);
 	return sb;
 }
 

diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c	2006-07-03 12:32:30.000000000 +1000
+++ ./fs/nfsd/nfssvc.c	2006-07-03 12:28:28.000000000 +1000
@@ -134,6 +134,9 @@ static int killsig = 0; /* signal that w
 static void nfsd_last_thread(struct svc_serv *serv)
 {
 	/* When last nfsd thread exits we need to do some clean-up */
+	struct svc_sock *svsk;
+	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+		lockd_down();
 	nfsd_serv = NULL;
 	nfsd_racache_shutdown();
 	nfs4_state_shutdown();
@@ -217,11 +220,16 @@ nfsd_svc(unsigned short port, int nrserv
 		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
 		if (error < 0)
 			goto failure;
-
+		error = lockd_up(IPPROTO_UDP);
+		if (error < 0)
+			goto failure;
 #ifdef CONFIG_NFSD_TCP
 		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
 		if (error < 0)
 			goto failure;
+		error = lockd_up(IPPROTO_TCP);
+		if (error < 0)
+			goto failure;
 #endif
 		do_gettimeofday(&nfssvc_boot);		/* record boot time */
 	} else
@@ -305,8 +313,6 @@ nfsd(struct svc_rqst *rqstp)
 
 	nfsdstats.th_cnt++;
 
-	lockd_up();				/* start lockd */
-
 	me.task = current;
 	list_add(&me.list, &nfsd_list);
 
@@ -363,13 +369,11 @@ nfsd(struct svc_rqst *rqstp)
 				break;
 		killsig = signo;
 	}
-	/* Clear signals before calling lockd_down() and svc_exit_thread() */
+	/* Clear signals before calling svc_exit_thread() */
 	flush_signals(current);
 
 	lock_kernel();
 
-	/* Release lockd */
-	lockd_down();
 	list_del(&me.list);
 	nfsdstats.th_cnt --;
 

diff .prev/include/linux/lockd/bind.h ./include/linux/lockd/bind.h
--- .prev/include/linux/lockd/bind.h	2006-07-03 12:40:37.000000000 +1000
+++ ./include/linux/lockd/bind.h	2006-07-03 12:40:46.000000000 +1000
@@ -30,7 +30,7 @@ extern struct nlmsvc_binding *	nlmsvc_op
  * Functions exported by the lockd module
  */
 extern int	nlmclnt_proc(struct inode *, int, struct file_lock *);
-extern int	lockd_up(void);
+extern int	lockd_up(int proto);
 extern void	lockd_down(void);
 
 #endif /* LINUX_LOCKD_BIND_H */

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 003 of 6] knfsd: Remove nfsd_versbits as intermediate storage for desired versions.
  2006-07-03  6:19 [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd NeilBrown
  2006-07-03  6:19 ` [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes NeilBrown
  2006-07-03  6:19 ` [PATCH 002 of 6] knfsd: Be more selective in which sockets lockd listens on NeilBrown
@ 2006-07-03  6:19 ` NeilBrown
  2006-07-03  6:19 ` [PATCH 004 of 6] knfsd: Separate out some parts of nfsd_svc, which start nfs servers NeilBrown
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2006-07-03  6:19 UTC (permalink / raw)
  To: nfs


We have an array 'nfsd_version' which lists the available versions
of nfsd, and 'nfsd_versions' (poor choice there :-() which lists
the currently active versions.

Then we have a bitmap - nfsd_versbits which says which versions are
wanted.  The bits in this bitset cause content to be copied from
nfsd_version to nfsd_versions when nfsd starts.

This patch removes nfsd_versbits and moves information directly from
nfsd_version to nfsd_versions when requests for version changes arrive.

Note that this doesn't make it possible to change versions while the
server is running.  This is because serv->sv_xdrsize is calculated when
a service is created, and used then threads are created, and xdrsize
depends on the active versions.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/nfsd/nfsctl.c             |   18 +++----
 ./fs/nfsd/nfssvc.c             |   93 ++++++++++++++++++++++-------------------
 ./include/linux/nfsd/nfsd.h    |    4 +
 ./include/linux/nfsd/syscall.h |   17 -------
 4 files changed, 62 insertions(+), 70 deletions(-)

diff .prev/fs/nfsd/nfsctl.c ./fs/nfsd/nfsctl.c
--- .prev/fs/nfsd/nfsctl.c	2006-07-03 15:00:32.000000000 +1000
+++ ./fs/nfsd/nfsctl.c	2006-07-03 15:01:17.000000000 +1000
@@ -35,8 +35,6 @@
 
 #include <asm/uaccess.h>
 
-unsigned int nfsd_versbits = ~0;
-
 /*
  *	We have a single directory with 9 nodes in it.
  */
@@ -372,6 +370,10 @@ static ssize_t write_versions(struct fil
 
 	if (size>0) {
 		if (nfsd_serv)
+			/* Cannot change versions without updating
+			 * nfsd_serv->sv_xdrsize, and reallocing
+			 * rq_argp and rq_resp
+			 */
 			return -EBUSY;
 		if (buf[size-1] != '\n')
 			return -EINVAL;
@@ -390,10 +392,7 @@ static ssize_t write_versions(struct fil
 			case 2:
 			case 3:
 			case 4:
-				if (sign != '-')
-					NFSCTL_VERSET(nfsd_versbits, num);
-				else
-					NFSCTL_VERUNSET(nfsd_versbits, num);
+				nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
 				break;
 			default:
 				return -EINVAL;
@@ -404,16 +403,15 @@ static ssize_t write_versions(struct fil
 		/* If all get turned off, turn them back on, as
 		 * having no versions is BAD
 		 */
-		if ((nfsd_versbits & NFSCTL_VERALL)==0)
-			nfsd_versbits = NFSCTL_VERALL;
+		nfsd_reset_versions();
 	}
 	/* Now write current state into reply buffer */
 	len = 0;
 	sep = "";
 	for (num=2 ; num <= 4 ; num++)
-		if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+		if (nfsd_vers(num, NFSD_AVAIL)) {
 			len += sprintf(buf+len, "%s%c%d", sep,
-				       NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+				       nfsd_vers(num, NFSD_TEST)?'+':'-',
 				       num);
 			sep = " ";
 		}

diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c	2006-07-03 15:00:32.000000000 +1000
+++ ./fs/nfsd/nfssvc.c	2006-07-03 14:50:11.000000000 +1000
@@ -117,6 +117,32 @@ struct svc_program		nfsd_program = {
 
 };
 
+int nfsd_vers(int vers, enum vers_op change)
+{
+	if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
+		return -1;
+	switch(change) {
+	case NFSD_SET:
+		nfsd_versions[vers] = nfsd_version[vers];
+		break;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+		if (vers < NFSD_ACL_NRVERS)
+			nfsd_acl_version[vers] = nfsd_acl_version[vers];
+#endif
+	case NFSD_CLEAR:
+		nfsd_versions[vers] = NULL;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+		if (vers < NFSD_ACL_NRVERS)
+			nfsd_acl_version[vers] = NULL;
+#endif
+		break;
+	case NFSD_TEST:
+		return nfsd_versions[vers] != NULL;
+	case NFSD_AVAIL:
+		return nfsd_version[vers] != NULL;
+	}
+	return 0;
+}
 /*
  * Maximum number of nfsd processes
  */
@@ -147,16 +173,36 @@ static void nfsd_last_thread(struct svc_
 		nfsd_export_flush();
 	}
 }
+
+void nfsd_reset_versions(void)
+{
+	int found_one = 0;
+	int i;
+
+	for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+		if (nfsd_program.pg_vers[i])
+			found_one = 1;
+	}
+
+	if (!found_one) {
+		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+			nfsd_program.pg_vers[i] = nfsd_version[i];
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+		for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
+			nfsd_acl_program.pg_vers[i] =
+				nfsd_acl_version[i];
+#endif
+	}
+}
+
 int
 nfsd_svc(unsigned short port, int nrservs)
 {
 	int	error;
-	int	found_one, i;
 	struct list_head *victim;
 	
 	lock_kernel();
-	dprintk("nfsd: creating service: vers 0x%x\n",
-		nfsd_versbits);
+	dprintk("nfsd: creating service\n");
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
@@ -171,46 +217,7 @@ nfsd_svc(unsigned short port, int nrserv
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
-		/*
-		 * Use the nfsd_ctlbits to define which
-		 * versions that will be advertised.
-		 * If nfsd_ctlbits doesn't list any version,
-		 * export them all.
-		 */
-		found_one = 0;
-
-		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
-			if (NFSCTL_VERISSET(nfsd_versbits, i)) {
-				nfsd_program.pg_vers[i] = nfsd_version[i];
-				found_one = 1;
-			} else
-				nfsd_program.pg_vers[i] = NULL;
-		}
-
-		if (!found_one) {
-			for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
-				nfsd_program.pg_vers[i] = nfsd_version[i];
-		}
-
-
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
-		found_one = 0;
-
-		for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
-			if (NFSCTL_VERISSET(nfsd_versbits, i)) {
-				nfsd_acl_program.pg_vers[i] =
-					nfsd_acl_version[i];
-				found_one = 1;
-			} else
-				nfsd_acl_program.pg_vers[i] = NULL;
-		}
-
-		if (!found_one) {
-			for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
-				nfsd_acl_program.pg_vers[i] =
-					nfsd_acl_version[i];
-		}
-#endif
+		nfsd_reset_versions();
 
 		atomic_set(&nfsd_busy, 0);
 		error = -ENOMEM;

diff .prev/include/linux/nfsd/nfsd.h ./include/linux/nfsd/nfsd.h
--- .prev/include/linux/nfsd/nfsd.h	2006-07-03 15:00:32.000000000 +1000
+++ ./include/linux/nfsd/nfsd.h	2006-07-03 14:48:36.000000000 +1000
@@ -140,6 +140,10 @@ struct posix_acl *nfsd_get_posix_acl(str
 int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
 #endif
 
+enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
+int nfsd_vers(int vers, enum vers_op change);
+void nfsd_reset_versions(void);
+
 
 /* 
  * NFSv4 State

diff .prev/include/linux/nfsd/syscall.h ./include/linux/nfsd/syscall.h
--- .prev/include/linux/nfsd/syscall.h	2006-07-03 15:00:32.000000000 +1000
+++ ./include/linux/nfsd/syscall.h	2006-07-03 13:21:25.000000000 +1000
@@ -38,21 +38,6 @@
 #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 */
 
-/*
- * Macros used to set version
- */
-#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |=  (1 << (_v)))
-#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
-#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
-
-#if defined(CONFIG_NFSD_V4)
-#define	NFSCTL_VERALL	(0x1c /* 0b011100 */)
-#elif defined(CONFIG_NFSD_V3)
-#define	NFSCTL_VERALL	(0x0c /* 0b001100 */)
-#else
-#define	NFSCTL_VERALL	(0x04 /* 0b000100 */)
-#endif
-
 /* SVC */
 struct nfsctl_svc {
 	unsigned short		svc_port;
@@ -134,8 +119,6 @@ extern int		exp_delclient(struct nfsctl_
 extern int		exp_export(struct nfsctl_export *nxp);
 extern int		exp_unexport(struct nfsctl_export *nxp);
 
-extern unsigned int nfsd_versbits;
-
 #endif /* __KERNEL__ */
 
 #endif /* NFSD_SYSCALL_H */

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 004 of 6] knfsd: Separate out some parts of nfsd_svc, which start nfs servers.
  2006-07-03  6:19 [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd NeilBrown
                   ` (2 preceding siblings ...)
  2006-07-03  6:19 ` [PATCH 003 of 6] knfsd: Remove nfsd_versbits as intermediate storage for desired versions NeilBrown
@ 2006-07-03  6:19 ` NeilBrown
  2006-07-03  6:19 ` [PATCH 005 of 6] knfsd: Define new nfsdfs file: portlist - contains list of ports NeilBrown
  2006-07-03  6:19 ` [PATCH 006 of 6] knfsd: Allow sockets to be passed to nfsd via 'portlist' NeilBrown
  5 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2006-07-03  6:19 UTC (permalink / raw)
  To: nfs


Sparate out the code for creating a new service, and for creating
initial sockets.

Some of these new functions will have multiple callers soon.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/nfsd/nfssvc.c |   79 ++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 24 deletions(-)

diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c	2006-07-03 14:50:11.000000000 +1000
+++ ./fs/nfsd/nfssvc.c	2006-07-03 15:16:40.000000000 +1000
@@ -195,6 +195,52 @@ void nfsd_reset_versions(void)
 	}
 }
 
+
+static inline int nfsd_create_serv(void)
+{
+	int err = 0;
+	lock_kernel();
+	if (nfsd_serv) {
+		nfsd_serv->sv_nrthreads++;
+		unlock_kernel();
+		return 0;
+	}
+
+	atomic_set(&nfsd_busy, 0);
+	nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, nfsd_last_thread);
+	if (nfsd_serv == NULL)
+		err = -ENOMEM;
+	else
+		nfsd_serv->sv_nrthreads++;
+	unlock_kernel();
+	do_gettimeofday(&nfssvc_boot);		/* record boot time */
+	return err;
+}
+
+static inline int nfsd_init_socks(int port)
+{
+	int error;
+	if (!list_empty(&nfsd_serv->sv_permsocks))
+		return 0;
+
+	error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+	if (error < 0)
+		return error;
+	error = lockd_up(IPPROTO_UDP);
+	if (error < 0)
+		return error;
+
+#ifdef CONFIG_NFSD_TCP
+	error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+	if (error < 0)
+		return error;
+	error = lockd_up(IPPROTO_TCP);
+	if (error < 0)
+		return error;
+#endif
+	return 0;
+}
+
 int
 nfsd_svc(unsigned short port, int nrservs)
 {
@@ -216,31 +262,16 @@ nfsd_svc(unsigned short port, int nrserv
 	error = nfs4_state_start();
 	if (error<0)
 		goto out;
-	if (!nfsd_serv) {
-		nfsd_reset_versions();
 
-		atomic_set(&nfsd_busy, 0);
-		error = -ENOMEM;
-		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, nfsd_last_thread);
-		if (nfsd_serv == NULL)
-			goto out;
-		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-		if (error < 0)
-			goto failure;
-		error = lockd_up(IPPROTO_UDP);
-		if (error < 0)
-			goto failure;
-#ifdef CONFIG_NFSD_TCP
-		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-		if (error < 0)
-			goto failure;
-		error = lockd_up(IPPROTO_TCP);
-		if (error < 0)
-			goto failure;
-#endif
-		do_gettimeofday(&nfssvc_boot);		/* record boot time */
-	} else
-		nfsd_serv->sv_nrthreads++;
+	nfsd_reset_versions();
+
+	error = nfsd_create_serv();
+	if (error)
+		goto out;
+	error = nfsd_init_socks(port);
+	if (error)
+		goto failure;
+
 	nrservs -= (nfsd_serv->sv_nrthreads-1);
 	while (nrservs > 0) {
 		nrservs--;

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 005 of 6] knfsd: Define new nfsdfs file: portlist - contains list of ports.
  2006-07-03  6:19 [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd NeilBrown
                   ` (3 preceding siblings ...)
  2006-07-03  6:19 ` [PATCH 004 of 6] knfsd: Separate out some parts of nfsd_svc, which start nfs servers NeilBrown
@ 2006-07-03  6:19 ` NeilBrown
  2006-07-03  6:19 ` [PATCH 006 of 6] knfsd: Allow sockets to be passed to nfsd via 'portlist' NeilBrown
  5 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2006-07-03  6:19 UTC (permalink / raw)
  To: nfs


This file will list all ports that nfsd has open.
Default when TCP enabled will be
   ipv4 udp 0.0.0.0 2049
   ipv4 tcp 0.0.0.0 2049

Later, the list of ports will be settable.

'portlist' chosen rather than 'ports', to avoid unnecessary confusion with
non-mainline patches which created 'ports' with different semantics.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/nfsd/nfsctl.c               |   19 +++++++++++++++++++
 ./include/linux/sunrpc/svcsock.h |    1 +
 ./net/sunrpc/svcsock.c           |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+)

diff .prev/fs/nfsd/nfsctl.c ./fs/nfsd/nfsctl.c
--- .prev/fs/nfsd/nfsctl.c	2006-07-03 15:46:47.000000000 +1000
+++ ./fs/nfsd/nfsctl.c	2006-07-03 15:46:44.000000000 +1000
@@ -27,6 +27,7 @@
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
 #include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/svcsock.h>
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
 #include <linux/nfsd/xdr.h>
@@ -51,6 +52,7 @@ enum {
 	NFSD_Fh,
 	NFSD_Threads,
 	NFSD_Versions,
+	NFSD_Ports,
 	/*
 	 * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
 	 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -74,6 +76,7 @@ static ssize_t write_getfs(struct file *
 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_versions(struct file *file, char *buf, size_t size);
+static ssize_t write_ports(struct file *file, char *buf, size_t size);
 #ifdef CONFIG_NFSD_V4
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
@@ -90,6 +93,7 @@ static ssize_t (*write_op[])(struct file
 	[NFSD_Fh] = write_filehandle,
 	[NFSD_Threads] = write_threads,
 	[NFSD_Versions] = write_versions,
+	[NFSD_Ports] = write_ports,
 #ifdef CONFIG_NFSD_V4
 	[NFSD_Leasetime] = write_leasetime,
 	[NFSD_RecoveryDir] = write_recoverydir,
@@ -419,6 +423,20 @@ static ssize_t write_versions(struct fil
 	return len;
 }
 
+static ssize_t write_ports(struct file *file, char *buf, size_t size)
+{
+	/* for now, ignore what was written and just
+	 * return known ports
+	 * AF proto address port
+	 */
+	int len = 0;
+	lock_kernel();
+	if (nfsd_serv)
+		len = svc_sock_names(buf, nfsd_serv);
+	unlock_kernel();
+	return len;
+}
+
 #ifdef CONFIG_NFSD_V4
 extern time_t nfs4_leasetime(void);
 
@@ -482,6 +500,7 @@ static int nfsd_fill_super(struct super_
 		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
 #ifdef CONFIG_NFSD_V4
 		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},

diff .prev/include/linux/sunrpc/svcsock.h ./include/linux/sunrpc/svcsock.h
--- .prev/include/linux/sunrpc/svcsock.h	2006-07-03 15:46:47.000000000 +1000
+++ ./include/linux/sunrpc/svcsock.h	2006-07-03 15:46:44.000000000 +1000
@@ -61,5 +61,6 @@ int		svc_recv(struct svc_serv *, struct 
 int		svc_send(struct svc_rqst *);
 void		svc_drop(struct svc_rqst *);
 void		svc_sock_update_bufs(struct svc_serv *serv);
+int		svc_sock_names(char *buf, struct svc_serv *serv);
 
 #endif /* SUNRPC_SVCSOCK_H */

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-07-03 15:46:47.000000000 +1000
+++ ./net/sunrpc/svcsock.c	2006-07-03 15:46:44.000000000 +1000
@@ -429,6 +429,43 @@ out:
 }
 
 /*
+ * Report socket names for nfsdfs
+ */
+int one_sock_name(char *buf, struct svc_sock *svsk)
+{
+	int len;
+	switch(svsk->sk_sk->sk_family) {
+	case AF_INET:
+		len = sprintf(buf, "ipv4 %s %u.%u.%u.%u %d\n",
+			      svsk->sk_sk->sk_protocol==IPPROTO_UDP?
+			      "udp" : "tcp",
+			      NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr),
+			      inet_sk(svsk->sk_sk)->num);
+		break;
+	default: len = sprintf(buf, "*unknown-%d*\n",
+			       svsk->sk_sk->sk_family);
+	}
+	return len;
+}
+
+int
+svc_sock_names(char *buf, struct svc_serv *serv)
+{
+	struct svc_sock *svsk;
+	int len = 0;
+
+	if (!serv) return 0;
+	spin_lock(&serv->sv_lock);
+	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
+		int onelen = one_sock_name(buf+len, svsk);
+		len += onelen;
+	}
+	spin_unlock(&serv->sv_lock);
+	return len;
+}
+EXPORT_SYMBOL(svc_sock_names);
+
+/*
  * Check input queue length
  */
 static int

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 006 of 6] knfsd: Allow sockets to be passed to nfsd via 'portlist'
  2006-07-03  6:19 [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd NeilBrown
                   ` (4 preceding siblings ...)
  2006-07-03  6:19 ` [PATCH 005 of 6] knfsd: Define new nfsdfs file: portlist - contains list of ports NeilBrown
@ 2006-07-03  6:19 ` NeilBrown
  5 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2006-07-03  6:19 UTC (permalink / raw)
  To: nfs


Userspace should create and bind a socket (but not connectted)
and write the 'fd' to portlist.  This will cause the nfs server
to listen on that socket.

To close a socket, the name of the socket - as read from 'portlist'
can be written to 'portlist' with a preceding '-'.


Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/nfsd/nfsctl.c               |   59 +++++++++++++++++++++++++++++++++------
 ./fs/nfsd/nfssvc.c               |    2 -
 ./include/linux/nfsd/nfsd.h      |    1 
 ./include/linux/sunrpc/svcsock.h |    6 +++
 ./net/sunrpc/svcsock.c           |   39 +++++++++++++++++++++++--
 5 files changed, 93 insertions(+), 14 deletions(-)

diff .prev/fs/nfsd/nfsctl.c ./fs/nfsd/nfsctl.c
--- .prev/fs/nfsd/nfsctl.c	2006-07-03 15:46:44.000000000 +1000
+++ ./fs/nfsd/nfsctl.c	2006-07-03 16:12:42.000000000 +1000
@@ -23,9 +23,11 @@
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/ctype.h>
 
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
+#include <linux/lockd/bind.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfsd/nfsd.h>
@@ -425,16 +427,55 @@ static ssize_t write_versions(struct fil
 
 static ssize_t write_ports(struct file *file, char *buf, size_t size)
 {
-	/* for now, ignore what was written and just
-	 * return known ports
-	 * AF proto address port
+	if (size == 0) {
+		int len = 0;
+		lock_kernel();
+		if (nfsd_serv)
+			len = svc_sock_names(buf, nfsd_serv, NULL);
+		unlock_kernel();
+		return len;
+	}
+	/* Either a single 'fd' number is written, in which
+	 * case it must be for a socket of a supported family/protocol,
+	 * and we use it as an nfsd socket, or
+	 * A '-' followed by the 'name' of a socket in which case
+	 * we close the socket.
 	 */
-	int len = 0;
-	lock_kernel();
-	if (nfsd_serv)
-		len = svc_sock_names(buf, nfsd_serv);
-	unlock_kernel();
-	return len;
+	if (isdigit(buf[0])) {
+		char *mesg = buf;
+		int fd;
+		int err;
+		err = get_int(&mesg, &fd);
+		if (err)
+			return -EINVAL;
+		if (fd < 0)
+			return -EINVAL;
+		err = nfsd_create_serv();
+		if (!err) {
+			int proto = 0;
+			err = svc_addsock(nfsd_serv, fd, buf, &proto);
+			/* Decrease the count, but don't shutdown the
+			 * the service
+			 */
+			if (!err >= 0)
+				lockd_up(proto);
+			nfsd_serv->sv_nrthreads--;
+		}
+		return err;
+	}
+	if (buf[0] == '-') {
+		char *toclose = kstrdup(buf+1, GFP_KERNEL);
+		int len = 0;
+		if (!toclose)
+			return -ENOMEM;
+		lock_kernel();
+		if (nfsd_serv)
+			len = svc_sock_names(buf, nfsd_serv, toclose);
+		unlock_kernel();
+		kfree(toclose);
+		return len;
+	}
+	return -EINVAL;
 }
 
 #ifdef CONFIG_NFSD_V4

diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c	2006-07-03 15:16:40.000000000 +1000
+++ ./fs/nfsd/nfssvc.c	2006-07-03 16:07:21.000000000 +1000
@@ -196,7 +196,7 @@ void nfsd_reset_versions(void)
 }
 
 
-static inline int nfsd_create_serv(void)
+int nfsd_create_serv(void)
 {
 	int err = 0;
 	lock_kernel();

diff .prev/include/linux/nfsd/nfsd.h ./include/linux/nfsd/nfsd.h
--- .prev/include/linux/nfsd/nfsd.h	2006-07-03 14:48:36.000000000 +1000
+++ ./include/linux/nfsd/nfsd.h	2006-07-03 16:07:36.000000000 +1000
@@ -143,6 +143,7 @@ int nfsd_set_posix_acl(struct svc_fh *, 
 enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
 int nfsd_vers(int vers, enum vers_op change);
 void nfsd_reset_versions(void);
+int nfsd_create_serv(void);
 
 
 /* 

diff .prev/include/linux/sunrpc/svcsock.h ./include/linux/sunrpc/svcsock.h
--- .prev/include/linux/sunrpc/svcsock.h	2006-07-03 15:46:44.000000000 +1000
+++ ./include/linux/sunrpc/svcsock.h	2006-07-03 16:11:05.000000000 +1000
@@ -61,6 +61,10 @@ int		svc_recv(struct svc_serv *, struct 
 int		svc_send(struct svc_rqst *);
 void		svc_drop(struct svc_rqst *);
 void		svc_sock_update_bufs(struct svc_serv *serv);
-int		svc_sock_names(char *buf, struct svc_serv *serv);
+int		svc_sock_names(char *buf, struct svc_serv *serv, char *toclose);
+int		svc_addsock(struct svc_serv *serv,
+			    int fd,
+			    char *name_return,
+			    int *proto);
 
 #endif /* SUNRPC_SVCSOCK_H */

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-07-03 15:46:44.000000000 +1000
+++ ./net/sunrpc/svcsock.c	2006-07-03 16:11:40.000000000 +1000
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/file.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -449,18 +450,23 @@ int one_sock_name(char *buf, struct svc_
 }
 
 int
-svc_sock_names(char *buf, struct svc_serv *serv)
+svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
 {
-	struct svc_sock *svsk;
+	struct svc_sock *svsk, *closesk = NULL;
 	int len = 0;
 
 	if (!serv) return 0;
 	spin_lock(&serv->sv_lock);
 	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
 		int onelen = one_sock_name(buf+len, svsk);
-		len += onelen;
+		if (toclose && strcmp(toclose, buf+len) == 0)
+			closesk = svsk;
+		else
+			len += onelen;
 	}
 	spin_unlock(&serv->sv_lock);
+	if (closesk)
+		svc_delete_socket(closesk);
 	return len;
 }
 EXPORT_SYMBOL(svc_sock_names);
@@ -1415,6 +1421,31 @@ svc_setup_socket(struct svc_serv *serv, 
 	return svsk;
 }
 
+int svc_addsock(struct svc_serv *serv,
+		int fd,
+		char *name_return,
+		int *proto)
+{
+	int err = 0;
+	struct socket *so = sockfd_lookup(fd, &err);
+	struct svc_sock *svsk;
+
+	if (!so)
+		return err;
+	if (so->sk->sk_family != AF_INET)
+		return -EAFNOSUPPORT;
+	if (so->sk->sk_protocol != IPPROTO_TCP &&
+	    so->sk->sk_protocol != IPPROTO_UDP)
+		return -EPROTONOSUPPORT;
+	/* Should check TCP socket is listening, not connected */
+	svsk = svc_setup_socket(serv, so, &err, 1);
+	if (!svsk)
+		return err;
+	if (proto) *proto = so->sk->sk_protocol;
+	return one_sock_name(name_return, svsk);
+}
+EXPORT_SYMBOL_GPL(svc_addsock);
+
 /*
  * Create socket for RPC service.
  */
@@ -1492,6 +1523,8 @@ svc_delete_socket(struct svc_sock *svsk)
 
 	if (!svsk->sk_inuse) {
 		spin_unlock_bh(&serv->sv_lock);
+		if (svsk->sk_sock->file)
+			sockfd_put(svsk->sk_sock);
 		sock_release(svsk->sk_sock);
 		kfree(svsk);
 	} else {

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* Re: [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
  2006-07-03  6:19 ` [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes NeilBrown
@ 2006-07-03 22:12   ` Christoph Hellwig
  2006-07-04  0:50     ` Neil Brown
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2006-07-03 22:12 UTC (permalink / raw)
  To: NeilBrown; +Cc: nfs

On Mon, Jul 03, 2006 at 04:19:11PM +1000, NeilBrown wrote:
> 
> nfsd has some cleanup that it wants to do when the last thread
> exits, and there will shortly be some more.
> So collect this all into one place and define a callback for
> an rpc service to call when the service is about to be destroyed.

Any chance you could convert all these svc threads to the kthread_
infrastructure before further complicating the already nasy interactions
it has with it's users?


Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* Re: [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
  2006-07-03 22:12   ` Christoph Hellwig
@ 2006-07-04  0:50     ` Neil Brown
  2006-07-04 11:56       ` Christoph Hellwig
  0 siblings, 1 reply; 10+ messages in thread
From: Neil Brown @ 2006-07-04  0:50 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: nfs

On Monday July 3, hch@infradead.org wrote:
> On Mon, Jul 03, 2006 at 04:19:11PM +1000, NeilBrown wrote:
> > 
> > nfsd has some cleanup that it wants to do when the last thread
> > exits, and there will shortly be some more.
> > So collect this all into one place and define a callback for
> > an rpc service to call when the service is about to be destroyed.
> 
> Any chance you could convert all these svc threads to the kthread_
> infrastructure before further complicating the already nasy interactions
> it has with it's users?

Maybe .... could you remind me of the particular value of kthread_
(other than general consistency which is obviously a good thing) to
make sure I leverage it during the conversion.

Thanks,
NeilBrown

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* Re: [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
  2006-07-04  0:50     ` Neil Brown
@ 2006-07-04 11:56       ` Christoph Hellwig
  0 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2006-07-04 11:56 UTC (permalink / raw)
  To: Neil Brown; +Cc: nfs

On Tue, Jul 04, 2006 at 10:50:11AM +1000, Neil Brown wrote:
> > Any chance you could convert all these svc threads to the kthread_
> > infrastructure before further complicating the already nasy interactions
> > it has with it's users?
> 
> Maybe .... could you remind me of the particular value of kthread_
> (other than general consistency which is obviously a good thing) to
> make sure I leverage it during the conversion.

 - it makes sure the threads are spawned by kevent so they are independent
   from the enviroment of the caller.  This is important for all the ongoin
   container work aswell as to avoid possible security issues.
 - it reduced complexity for thread creation and stopping a lot and thus
   eliminates various bugs crept in all over the place
(- we want to remove the kernel_thread export so people stop opencoding it
   in new code)

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

end of thread, other threads:[~2006-07-04 11:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-03  6:19 [RFC PATCH 000 of 6] knfsd: change how sockets are assigned to nfsd and lockd NeilBrown
2006-07-03  6:19 ` [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes NeilBrown
2006-07-03 22:12   ` Christoph Hellwig
2006-07-04  0:50     ` Neil Brown
2006-07-04 11:56       ` Christoph Hellwig
2006-07-03  6:19 ` [PATCH 002 of 6] knfsd: Be more selective in which sockets lockd listens on NeilBrown
2006-07-03  6:19 ` [PATCH 003 of 6] knfsd: Remove nfsd_versbits as intermediate storage for desired versions NeilBrown
2006-07-03  6:19 ` [PATCH 004 of 6] knfsd: Separate out some parts of nfsd_svc, which start nfs servers NeilBrown
2006-07-03  6:19 ` [PATCH 005 of 6] knfsd: Define new nfsdfs file: portlist - contains list of ports NeilBrown
2006-07-03  6:19 ` [PATCH 006 of 6] knfsd: Allow sockets to be passed to nfsd via 'portlist' NeilBrown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.