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.
|
The Rpc configuration file section, which was deprecated in v18.01, has been removed.
|
||||||
Users should switch to the `-r` command-line parameter instead.
|
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
|
### NVMe Driver
|
||||||
|
|
||||||
EXPERIMENTAL: Adds support for WDS and RDS capable CMBs in NVMe controllers. This support is
|
EXPERIMENTAL: Adds support for WDS and RDS capable CMBs in NVMe controllers. This support is
|
||||||
|
@ -42,7 +42,8 @@
|
|||||||
#include "spdk_internal/log.h"
|
#include "spdk_internal/log.h"
|
||||||
|
|
||||||
#define SPDK_JSONRPC_RECV_BUF_SIZE (32 * 1024)
|
#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_ID_MAX_LEN 128
|
||||||
#define SPDK_JSONRPC_MAX_CONNS 64
|
#define SPDK_JSONRPC_MAX_CONNS 64
|
||||||
#define SPDK_JSONRPC_MAX_VALUES 1024
|
#define SPDK_JSONRPC_MAX_VALUES 1024
|
||||||
@ -54,9 +55,15 @@ struct spdk_jsonrpc_request {
|
|||||||
struct spdk_json_val id;
|
struct spdk_json_val id;
|
||||||
uint8_t id_data[SPDK_JSONRPC_ID_MAX_LEN];
|
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_len;
|
||||||
|
|
||||||
size_t send_offset;
|
size_t send_offset;
|
||||||
uint8_t send_buf[SPDK_JSONRPC_SEND_BUF_SIZE];
|
|
||||||
|
uint8_t *send_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spdk_jsonrpc_server_conn {
|
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->id.type = SPDK_JSON_VAL_INVALID;
|
||||||
request->send_offset = 0;
|
request->send_offset = 0;
|
||||||
request->send_len = 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) {
|
if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error\n");
|
SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error\n");
|
||||||
@ -184,10 +191,30 @@ static int
|
|||||||
spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size)
|
spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct spdk_jsonrpc_request *request = cb_ctx;
|
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) {
|
while (new_size - request->send_len < size) {
|
||||||
SPDK_ERRLOG("Not enough space in send buf\n");
|
if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) {
|
||||||
return -1;
|
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);
|
memcpy(request->send_buf + request->send_len, data, size);
|
||||||
@ -229,6 +256,7 @@ void
|
|||||||
spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request)
|
spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request)
|
||||||
{
|
{
|
||||||
request->conn->outstanding_requests--;
|
request->conn->outstanding_requests--;
|
||||||
|
free(request->send_buf);
|
||||||
free(request);
|
free(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,14 +61,21 @@ static size_t g_num_reqs;
|
|||||||
memcpy(g_buf, in, sizeof(in) - 1); \
|
memcpy(g_buf, in, sizeof(in) - 1); \
|
||||||
g_num_reqs = 0; \
|
g_num_reqs = 0; \
|
||||||
g_cur_req = NULL; \
|
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) \
|
#define PARSE_FAIL(in) \
|
||||||
memcpy(g_buf, in, sizeof(in) - 1); \
|
memcpy(g_buf, in, sizeof(in) - 1); \
|
||||||
g_num_reqs = 0; \
|
g_num_reqs = 0; \
|
||||||
g_cur_req = 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) \
|
#define REQ_BEGIN(expected_error) \
|
||||||
if (g_cur_req == NULL) { \
|
if (g_cur_req == NULL) { \
|
||||||
@ -148,6 +155,9 @@ static size_t g_num_reqs;
|
|||||||
g_params++
|
g_params++
|
||||||
|
|
||||||
#define FREE_REQUEST() \
|
#define FREE_REQUEST() \
|
||||||
|
if (g_reqs->request) { \
|
||||||
|
free(g_reqs->request->send_buf); \
|
||||||
|
} \
|
||||||
free(g_reqs->request); \
|
free(g_reqs->request); \
|
||||||
g_reqs->request = NULL
|
g_reqs->request = NULL
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user