diff options
author | NeilBrown <neilb@suse.de> | 2006-10-02 05:17:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 10:57:17 -0400 |
commit | 24e36663c375df577d2dcae437713481ffd6850c (patch) | |
tree | dd738e582b663c433eef3a53eb593a518439a285 /fs/lockd/svc.c | |
parent | bc591ccff27e6a85d3a0d6fcb16cfadcc45267a8 (diff) |
[PATCH] knfsd: be more selective in which sockets lockd listens on
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>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/lockd/svc.c')
-rw-r--r-- | fs/lockd/svc.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 13feba45030e..8d19de6a14dc 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/sunrpc/clnt.h> | 31 | #include <linux/sunrpc/clnt.h> |
32 | #include <linux/sunrpc/svc.h> | 32 | #include <linux/sunrpc/svc.h> |
33 | #include <linux/sunrpc/svcsock.h> | 33 | #include <linux/sunrpc/svcsock.h> |
34 | #include <net/ip.h> | ||
34 | #include <linux/lockd/lockd.h> | 35 | #include <linux/lockd/lockd.h> |
35 | #include <linux/nfs.h> | 36 | #include <linux/nfs.h> |
36 | 37 | ||
@@ -46,6 +47,7 @@ EXPORT_SYMBOL(nlmsvc_ops); | |||
46 | static DEFINE_MUTEX(nlmsvc_mutex); | 47 | static DEFINE_MUTEX(nlmsvc_mutex); |
47 | static unsigned int nlmsvc_users; | 48 | static unsigned int nlmsvc_users; |
48 | static pid_t nlmsvc_pid; | 49 | static pid_t nlmsvc_pid; |
50 | static struct svc_serv *nlmsvc_serv; | ||
49 | int nlmsvc_grace_period; | 51 | int nlmsvc_grace_period; |
50 | unsigned long nlmsvc_timeout; | 52 | unsigned long nlmsvc_timeout; |
51 | 53 | ||
@@ -112,6 +114,7 @@ lockd(struct svc_rqst *rqstp) | |||
112 | * Let our maker know we're running. | 114 | * Let our maker know we're running. |
113 | */ | 115 | */ |
114 | nlmsvc_pid = current->pid; | 116 | nlmsvc_pid = current->pid; |
117 | nlmsvc_serv = serv; | ||
115 | complete(&lockd_start_done); | 118 | complete(&lockd_start_done); |
116 | 119 | ||
117 | daemonize("lockd"); | 120 | daemonize("lockd"); |
@@ -189,6 +192,7 @@ lockd(struct svc_rqst *rqstp) | |||
189 | nlmsvc_invalidate_all(); | 192 | nlmsvc_invalidate_all(); |
190 | nlm_shutdown_hosts(); | 193 | nlm_shutdown_hosts(); |
191 | nlmsvc_pid = 0; | 194 | nlmsvc_pid = 0; |
195 | nlmsvc_serv = NULL; | ||
192 | } else | 196 | } else |
193 | printk(KERN_DEBUG | 197 | printk(KERN_DEBUG |
194 | "lockd: new process, skipping host shutdown\n"); | 198 | "lockd: new process, skipping host shutdown\n"); |
@@ -205,11 +209,42 @@ lockd(struct svc_rqst *rqstp) | |||
205 | module_put_and_exit(0); | 209 | module_put_and_exit(0); |
206 | } | 210 | } |
207 | 211 | ||
212 | |||
213 | static int find_socket(struct svc_serv *serv, int proto) | ||
214 | { | ||
215 | struct svc_sock *svsk; | ||
216 | int found = 0; | ||
217 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) | ||
218 | if (svsk->sk_sk->sk_protocol == proto) { | ||
219 | found = 1; | ||
220 | break; | ||
221 | } | ||
222 | return found; | ||
223 | } | ||
224 | |||
225 | static int make_socks(struct svc_serv *serv, int proto) | ||
226 | { | ||
227 | /* Make any sockets that are needed but not present. | ||
228 | * If nlm_udpport or nlm_tcpport were set as module | ||
229 | * options, make those sockets unconditionally | ||
230 | */ | ||
231 | int err = 0; | ||
232 | if (proto == IPPROTO_UDP || nlm_udpport) | ||
233 | if (!find_socket(serv, IPPROTO_UDP)) | ||
234 | err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport); | ||
235 | if (err) | ||
236 | return err; | ||
237 | if (proto == IPPROTO_TCP || nlm_tcpport) | ||
238 | if (!find_socket(serv, IPPROTO_TCP)) | ||
239 | err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport); | ||
240 | return err; | ||
241 | } | ||
242 | |||
208 | /* | 243 | /* |
209 | * Bring up the lockd process if it's not already up. | 244 | * Bring up the lockd process if it's not already up. |
210 | */ | 245 | */ |
211 | int | 246 | int |
212 | lockd_up(void) | 247 | lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ |
213 | { | 248 | { |
214 | static int warned; | 249 | static int warned; |
215 | struct svc_serv * serv; | 250 | struct svc_serv * serv; |
@@ -224,8 +259,10 @@ lockd_up(void) | |||
224 | /* | 259 | /* |
225 | * Check whether we're already up and running. | 260 | * Check whether we're already up and running. |
226 | */ | 261 | */ |
227 | if (nlmsvc_pid) | 262 | if (nlmsvc_pid) { |
263 | error = make_socks(nlmsvc_serv, proto); | ||
228 | goto out; | 264 | goto out; |
265 | } | ||
229 | 266 | ||
230 | /* | 267 | /* |
231 | * Sanity check: if there's no pid, | 268 | * Sanity check: if there's no pid, |
@@ -242,11 +279,7 @@ lockd_up(void) | |||
242 | goto out; | 279 | goto out; |
243 | } | 280 | } |
244 | 281 | ||
245 | if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0 | 282 | if ((error = make_socks(serv, proto)) < 0) { |
246 | #ifdef CONFIG_NFSD_TCP | ||
247 | || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0 | ||
248 | #endif | ||
249 | ) { | ||
250 | if (warned++ == 0) | 283 | if (warned++ == 0) |
251 | printk(KERN_WARNING | 284 | printk(KERN_WARNING |
252 | "lockd_up: makesock failed, error=%d\n", error); | 285 | "lockd_up: makesock failed, error=%d\n", error); |