diff options
author | Shreyas Siravara <sshreyas@fb.com> | 2016-02-26 20:59:00 -0800 |
---|---|---|
committer | Jeff Darcy <jeff@pl.atyp.us> | 2017-04-26 23:31:21 +0000 |
commit | 63a39c764181e60bc7bd8236996cf9abe353d906 (patch) | |
tree | 6bdee54011b19f970a0892e061afcfbca2a41255 /xlators/nfs | |
parent | 9e57016757f1fb431dee8196c781b5d15b51cd43 (diff) |
nfs: Tear down transports for requests that arrive before the volume is initialized
Summary:
- Disconnects RPC transports for requests that cannot be serviced
because volumes are not ready.
- This is a cherry-pick of D2991403
Signed-off-by: Shreyas Siravara <sshreyas@fb.com>
Change-Id: I07ff0795b81d25624541ff981b5f2586d078e9a6
BUG: 1428068
Reviewed-on: http://review.gluster.org/16154
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Kevin Vigor <kvigor@fb.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-on: https://review.gluster.org/16805
Reviewed-by: Amar Tumballi <amarts@redhat.com>
Tested-by: Jeff Darcy <jeff@pl.atyp.us>
Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
Diffstat (limited to 'xlators/nfs')
-rw-r--r-- | xlators/nfs/server/src/nfs3.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index cbc69c7af7f..729f811c917 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -413,6 +413,28 @@ out: } +/* + * This macro checks if the volume is started or not. + * If it is not started, it closes the client connection & logs it. + * + * Why do we do this? + * + * There is a "race condition" where gNFSd may start listening for RPC requests + * prior to the volume being started. Presumably, that is why this macro exists + * in the first place. In the NFS kernel client (specifically Linux's NFS + * kernel client), they establish a TCP connection to our endpoint and + * (re-)send requests. If we ignore the request, and return nothing back, + * the NFS kernel client waits forever for our response. If for some reason, + * the TCP connection were to die, and re-establish, the requests are + * retransmitted and everything begins working as expected + * + * Now, this is clearly bad behavior on the client side, + * but in order to make every user's life easier, + * gNFSd should simply disconnect the TCP connection if it sees requests + * before it is ready to accept them. + * + */ + #define nfs3_volume_started_check(nf3stt, vlm, rtval, erlbl) \ do { \ if ((!nfs_subvolume_started (nfs_state (nf3stt->nfsx), vlm))){\ @@ -420,11 +442,32 @@ out: NFS_MSG_VOL_DISABLE, \ "Volume is disabled: %s", \ vlm->name); \ + nfs3_disconnect_transport (req->trans); \ rtval = RPCSVC_ACTOR_IGNORE; \ goto erlbl; \ } \ } while (0) \ +void +nfs3_disconnect_transport (rpc_transport_t *transport) +{ + int ret = 0; + + GF_VALIDATE_OR_GOTO (GF_NFS3, transport, out); + + ret = rpc_transport_disconnect (transport, _gf_false); + if (ret != 0) { + gf_log (GF_NFS3, GF_LOG_WARNING, + "Unable to close client connection to %s.", + transport->peerinfo.identifier); + } else { + gf_log (GF_NFS3, GF_LOG_WARNING, + "Closed client connection to %s.", + transport->peerinfo.identifier); + } +out: + return; +} int nfs3_export_sync_trusted (struct nfs3_state *nfs3, uuid_t exportid) |