From bbcb35f58b3a9e78b7b69adf4179e2cbd7beb7b3 Mon Sep 17 00:00:00 2001 From: Pawel Wodkowski Date: Wed, 23 Jan 2019 14:38:01 +0100 Subject: [PATCH] jsonrpc: support half closed connections Fix case when remote is doing SHUT_WR but we still have requests in progress. In this case we should finish requests, send response and then close the connection. Fixes #604 Change-Id: I009029c95e0557c7347a78c3a50d35b30fc8141e Signed-off-by: Pawel Wodkowski Reviewed-on: https://review.gerrithub.io/c/441718 Tested-by: SPDK CI Jenkins Reviewed-by: Tomasz Kulasek Reviewed-by: Ben Walker Reviewed-by: Darek Stojaczyk --- lib/jsonrpc/jsonrpc_server_tcp.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/jsonrpc/jsonrpc_server_tcp.c b/lib/jsonrpc/jsonrpc_server_tcp.c index 5794c6677..70b7a56b9 100644 --- a/lib/jsonrpc/jsonrpc_server_tcp.c +++ b/lib/jsonrpc/jsonrpc_server_tcp.c @@ -274,7 +274,8 @@ spdk_jsonrpc_server_conn_recv(struct spdk_jsonrpc_server_conn *conn) if (rc == 0) { SPDK_DEBUGLOG(SPDK_LOG_RPC, "remote closed connection\n"); - return -1; + conn->closed = true; + return 0; } conn->recv_len += rc; @@ -386,7 +387,12 @@ spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server) struct spdk_jsonrpc_server_conn *conn, *conn_tmp; TAILQ_FOREACH_SAFE(conn, &server->conns, link, conn_tmp) { - if (conn->closed) { + /* If we can't receive and there are no outstanding requests close the connection. */ + if (conn->closed == true && conn->outstanding_requests == 0) { + spdk_jsonrpc_server_conn_close(conn); + } + + if (conn->sockfd == -1) { struct spdk_jsonrpc_request *request; /* @@ -416,7 +422,7 @@ spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server) } TAILQ_FOREACH(conn, &server->conns, link) { - if (conn->closed) { + if (conn->sockfd == -1) { continue; } @@ -426,10 +432,11 @@ spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server) continue; } - rc = spdk_jsonrpc_server_conn_recv(conn); - if (rc != 0) { - spdk_jsonrpc_server_conn_close(conn); - continue; + if (!conn->closed) { + rc = spdk_jsonrpc_server_conn_recv(conn); + if (rc != 0) { + spdk_jsonrpc_server_conn_close(conn); + } } }