summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src
diff options
context:
space:
mode:
authorShreyas Siravara <sshreyas@fb.com>2016-02-26 20:59:00 -0800
committerJeff Darcy <jeff@pl.atyp.us>2017-04-26 23:31:21 +0000
commit63a39c764181e60bc7bd8236996cf9abe353d906 (patch)
tree6bdee54011b19f970a0892e061afcfbca2a41255 /xlators/nfs/server/src
parent9e57016757f1fb431dee8196c781b5d15b51cd43 (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/server/src')
-rw-r--r--xlators/nfs/server/src/nfs3.c43
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)