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 | /* |
