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: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/399925 Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
114a91fdea
commit
c7852cf98d
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user