Commit c7852cf9 authored by Daniel Verkamp's avatar Daniel Verkamp Committed by Jim Harris
Browse files

jsonrpc: allow send_buf to grow as needed



Reallocate the send buffer if more data is written by the RPC handler
than currently fits in the buffer.

Change-Id: I590dd173b843aba48c768adfafaf87e4b47bcc19
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/399925


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 114a91fd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -7,6 +7,9 @@
The Rpc configuration file section, which was deprecated in v18.01, has been removed.
Users should switch to the `-r` command-line parameter instead.

The JSON-RPC server implementation now allows up to 32 megabyte responses, growing as
needed; previously, the response was limited to 32 kilobytes.

### NVMe Driver

EXPERIMENTAL: Adds support for WDS and RDS capable CMBs in NVMe controllers. This support is
+9 −2
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@
#include "spdk_internal/log.h"

#define SPDK_JSONRPC_RECV_BUF_SIZE	(32 * 1024)
#define SPDK_JSONRPC_SEND_BUF_SIZE	(32 * 1024)
#define SPDK_JSONRPC_SEND_BUF_SIZE_INIT	(32 * 1024)
#define SPDK_JSONRPC_SEND_BUF_SIZE_MAX	(32 * 1024 * 1024)
#define SPDK_JSONRPC_ID_MAX_LEN		128
#define SPDK_JSONRPC_MAX_CONNS		64
#define SPDK_JSONRPC_MAX_VALUES		1024
@@ -54,9 +55,15 @@ struct spdk_jsonrpc_request {
	struct spdk_json_val id;
	uint8_t id_data[SPDK_JSONRPC_ID_MAX_LEN];

	/* Total space allocated for send_buf */
	size_t send_buf_size;

	/* Number of bytes used in send_buf (<= send_buf_size) */
	size_t send_len;

	size_t send_offset;
	uint8_t send_buf[SPDK_JSONRPC_SEND_BUF_SIZE];

	uint8_t *send_buf;
};

struct spdk_jsonrpc_server_conn {
+31 −3
Original line number Diff line number Diff line
@@ -144,6 +144,13 @@ spdk_jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, void *json, si
	request->id.type = SPDK_JSON_VAL_INVALID;
	request->send_offset = 0;
	request->send_len = 0;
	request->send_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT;
	request->send_buf = malloc(request->send_buf_size);
	if (request->send_buf == NULL) {
		SPDK_ERRLOG("Failed to allocate send_buf (%zu bytes)\n", request->send_buf_size);
		free(request);
		return -1;
	}

	if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
		SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error\n");
@@ -184,12 +191,32 @@ static int
spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size)
{
	struct spdk_jsonrpc_request *request = cb_ctx;
	size_t new_size = request->send_buf_size;

	if (SPDK_JSONRPC_SEND_BUF_SIZE - request->send_len < size) {
		SPDK_ERRLOG("Not enough space in send buf\n");
	while (new_size - request->send_len < size) {
		if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) {
			SPDK_ERRLOG("Send buf exceeded maximum size (%zu)\n",
				    (size_t)SPDK_JSONRPC_SEND_BUF_SIZE_MAX);
			return -1;
		}

		new_size *= 2;
	}

	if (new_size != request->send_buf_size) {
		uint8_t *new_buf;

		new_buf = realloc(request->send_buf, new_size);
		if (new_buf == NULL) {
			SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n",
				    request->send_buf_size, new_size);
			return -1;
		}

		request->send_buf = new_buf;
		request->send_buf_size = new_size;
	}

	memcpy(request->send_buf + request->send_len, data, size);
	request->send_len += size;

@@ -229,6 +256,7 @@ void
spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request)
{
	request->conn->outstanding_requests--;
	free(request->send_buf);
	free(request);
}

+13 −3
Original line number Diff line number Diff line
@@ -61,14 +61,21 @@ static size_t g_num_reqs;
	memcpy(g_buf, in, sizeof(in) - 1); \
	g_num_reqs = 0; \
	g_cur_req = NULL; \
	CU_ASSERT(spdk_jsonrpc_parse_request(conn, g_buf, sizeof(in) - 1) == sizeof(in) - sizeof(trailing))
	CU_ASSERT(spdk_jsonrpc_parse_request(conn, g_buf, sizeof(in) - 1) == sizeof(in) - sizeof(trailing)); \
	if (g_cur_req && g_cur_req->request) { \
		free(g_cur_req->request->send_buf); \
		g_cur_req->request->send_buf = NULL; \
	}

#define PARSE_FAIL(in) \
	memcpy(g_buf, in, sizeof(in) - 1); \
	g_num_reqs = 0; \
	g_cur_req = 0; \
	CU_ASSERT(spdk_jsonrpc_parse_request(conn, g_buf, sizeof(in) - 1) < 0)

	CU_ASSERT(spdk_jsonrpc_parse_request(conn, g_buf, sizeof(in) - 1) < 0); \
	if (g_cur_req && g_cur_req->request) { \
		free(g_cur_req->request->send_buf); \
		g_cur_req->request->send_buf = NULL; \
	}

#define REQ_BEGIN(expected_error) \
	if (g_cur_req == NULL) { \
@@ -148,6 +155,9 @@ static size_t g_num_reqs;
	g_params++

#define FREE_REQUEST() \
	if (g_reqs->request) { \
		free(g_reqs->request->send_buf); \
	} \
	free(g_reqs->request); \
	g_reqs->request = NULL