diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2008-10-03 17:15:23 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-10-04 17:08:16 -0400 |
commit | 8c3916f4bdf9c8388bd70d0b399b3a43daf2087a (patch) | |
tree | 738c44f56265c6fbca20ce8c7ec8aa655ce56803 | |
parent | 9a38a83880c224c6a3fd973ac9ae30a043487f0f (diff) |
NLM: Always start both UDP and TCP listeners
Commit 24e36663, which first appeared in 2.6.19, changed lockd so that
the client side starts a UDP listener only if there is a UDP NFSv2/v3
mount. Its description notes:
This... 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.
Unfortunately it is a problem for Linux itself. The rpc.statd daemon
on Linux uses UDP for contacting the local lockd, no matter which
protocol is used for NFS mounts. Without a local lockd UDP listener,
NFSv2/v3 lock recovery from Linux NFS clients always fails.
Revert parts of commit 24e36663 so lockd_up() always starts both
listeners.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r-- | fs/lockd/svc.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index f013aed11533..36396fc058c5 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -189,25 +189,28 @@ lockd(void *vrqstp) | |||
189 | } | 189 | } |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * Make any sockets that are needed but not present. | 192 | * Ensure there are active UDP and TCP listeners for lockd. |
193 | * If nlm_udpport or nlm_tcpport were set as module | 193 | * |
194 | * options, make those sockets unconditionally | 194 | * Even if we have only TCP NFS mounts and/or TCP NFSDs, some |
195 | * local services (such as rpc.statd) still require UDP, and | ||
196 | * some NFS servers do not yet support NLM over TCP. | ||
197 | * | ||
198 | * Returns zero if all listeners are available; otherwise a | ||
199 | * negative errno value is returned. | ||
195 | */ | 200 | */ |
196 | static int make_socks(struct svc_serv *serv, int proto) | 201 | static int make_socks(struct svc_serv *serv) |
197 | { | 202 | { |
198 | static int warned; | 203 | static int warned; |
199 | struct svc_xprt *xprt; | 204 | struct svc_xprt *xprt; |
200 | int err = 0; | 205 | int err = 0; |
201 | 206 | ||
202 | if (proto == IPPROTO_UDP || nlm_udpport) { | 207 | xprt = svc_find_xprt(serv, "udp", 0, 0); |
203 | xprt = svc_find_xprt(serv, "udp", 0, 0); | 208 | if (!xprt) |
204 | if (!xprt) | 209 | err = svc_create_xprt(serv, "udp", nlm_udpport, |
205 | err = svc_create_xprt(serv, "udp", nlm_udpport, | 210 | SVC_SOCK_DEFAULTS); |
206 | SVC_SOCK_DEFAULTS); | 211 | else |
207 | else | 212 | svc_xprt_put(xprt); |
208 | svc_xprt_put(xprt); | 213 | if (err >= 0) { |
209 | } | ||
210 | if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport)) { | ||
211 | xprt = svc_find_xprt(serv, "tcp", 0, 0); | 214 | xprt = svc_find_xprt(serv, "tcp", 0, 0); |
212 | if (!xprt) | 215 | if (!xprt) |
213 | err = svc_create_xprt(serv, "tcp", nlm_tcpport, | 216 | err = svc_create_xprt(serv, "tcp", nlm_tcpport, |
@@ -237,11 +240,8 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | |||
237 | /* | 240 | /* |
238 | * Check whether we're already up and running. | 241 | * Check whether we're already up and running. |
239 | */ | 242 | */ |
240 | if (nlmsvc_rqst) { | 243 | if (nlmsvc_rqst) |
241 | if (proto) | ||
242 | error = make_socks(nlmsvc_rqst->rq_server, proto); | ||
243 | goto out; | 244 | goto out; |
244 | } | ||
245 | 245 | ||
246 | /* | 246 | /* |
247 | * Sanity check: if there's no pid, | 247 | * Sanity check: if there's no pid, |
@@ -258,7 +258,8 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | |||
258 | goto out; | 258 | goto out; |
259 | } | 259 | } |
260 | 260 | ||
261 | if ((error = make_socks(serv, proto)) < 0) | 261 | error = make_socks(serv); |
262 | if (error < 0) | ||
262 | goto destroy_and_out; | 263 | goto destroy_and_out; |
263 | 264 | ||
264 | /* | 265 | /* |