knfsd: change how sockets are assigned to nfsd and lockd
Subsystems (3)
RFC PATCH 1/1 knfsd: change how sockets are assigned to nfsd and lockd
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Add a callback for when last rpc thread finishes.
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.
### 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(-)
fs/lockd/svc.c +1 -1
@@ -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;
fs/nfsd/nfssvc.c +17 -22
@@ -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 nrservatomic_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 (¤t->pending.signal, signo) && !sigismember (¤t->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 --;
net/sunrpc/svc.c +6 -1
@@ -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,
include/linux/sunrpc/svc.h +7 -1
@@ -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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Re: [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
Quoted 5 lines · NeilBrown
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Re: [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
Quoted 10 lines · On Monday July 3, [email protected] wrote:
Quoted 5 lines · NeilBrown
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Re: [PATCH 001 of 6] knfsd: Add a callback for when last rpc thread finishes.
Quoted 7 lines · Neil Brown
Quoted 3 lines
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Be more selective in which sockets lockd listens on.
In reply to NeilBrownCurrently 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.
### 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(-)
fs/lockd/clntlock.c +1 -1
@@ -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. */
fs/lockd/svc.c +40 -7
94 lines not on this page · raw message
fs/nfs/super.c +4 -2
@@ -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; }
fs/nfsd/nfssvc.c +10 -6
@@ -134,6 +134,9 @@ static int killsig = 0; /* signal that wstatic 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 --;
include/linux/lockd/bind.h +1 -1
@@ -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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Remove nfsd_versbits as intermediate storage for desired versions.
In reply to NeilBrownWe 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.
### 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(-)
fs/nfsd/nfsctl.c +8 -10
@@ -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 filif (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 filcase 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 =" " ; }
fs/nfsd/nfssvc.c +50 -43
118 lines not on this page · raw message
include/linux/nfsd/nfsd.h +4 -0
@@ -140,6 +140,10 @@ struct posix_acl *nfsd_get_posix_acl(strint 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
include/linux/nfsd/syscall.h +0 -17
@@ -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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Separate out some parts of nfsd_svc, which start nfs servers.
In reply to NeilBrownSparate out the code for creating a new service, and for creating initial sockets.
Some of these new functions will have multiple callers soon.
### Diffstat output
./fs/nfsd/nfssvc.c | 79 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 24 deletions(-)
fs/nfsd/nfssvc.c +55 -24
@@ -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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Define new nfsdfs file: portlist - contains list of ports.
In reply to NeilBrownThis 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.
### Diffstat output
./fs/nfsd/nfsctl.c | 19 +++++++++++++++++++ ./include/linux/sunrpc/svcsock.h | 1 + ./net/sunrpc/svcsock.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+)
fs/nfsd/nfsctl.c +19 -0
@@ -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 filreturn 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},
include/linux/sunrpc/svcsock.h +1 -0
@@ -61,5 +61,6 @@ int svc_recv(struct svc_serv *, structint 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 */
net/sunrpc/svcsock.c +37 -0
@@ -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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Allow sockets to be passed to nfsd via 'portlist'
In reply to NeilBrownUserspace 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 '-'.
### 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(-)
fs/nfsd/nfsctl.c +50 -9
@@ -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 filstatic 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
fs/nfsd/nfssvc.c +1 -1
@@ -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 ();
include/linux/nfsd/nfsd.h +1 -0
@@ -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 );/*
include/linux/sunrpc/svcsock.h +5 -1
@@ -61,6 +61,10 @@ int svc_recv(struct svc_serv *, structint 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 */
net/sunrpc/svcsock.c +36 -3
@@ -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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs