Commit 2bdec64f authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

jsonrpc: modify API to pass request to handler



This will enable asynchronous request handling in a future patch, and it
also removes the need for the RPC handlers to know about request id and
the JSON-RPC rules about notification-only requests.

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


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 26d6770f
Loading
Loading
Loading
Loading
+21 −20
Original line number Diff line number Diff line
@@ -146,24 +146,23 @@ dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct nvmf_tgt_subsystem *tg
}

static void
spdk_rpc_get_nvmf_subsystems(struct spdk_jsonrpc_server_conn *conn,
			     const struct spdk_json_val *params,
			     const struct spdk_json_val *id)
spdk_rpc_get_nvmf_subsystems(struct spdk_jsonrpc_request *request,
			     const struct spdk_json_val *params)
{
	struct spdk_json_write_ctx *w;
	struct nvmf_tgt_subsystem	*tgt_subsystem;

	if (params != NULL) {
		spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "get_nvmf_subsystems requires no parameters");
		return;
	}

	if (id == NULL) {
	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	w = spdk_jsonrpc_begin_result(conn, id);
	spdk_json_write_array_begin(w);
	tgt_subsystem = nvmf_tgt_subsystem_first();
	while (tgt_subsystem) {
@@ -171,7 +170,7 @@ spdk_rpc_get_nvmf_subsystems(struct spdk_jsonrpc_server_conn *conn,
		tgt_subsystem = nvmf_tgt_subsystem_next(tgt_subsystem);
	}
	spdk_json_write_array_end(w);
	spdk_jsonrpc_end_result(conn, w);
	spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("get_nvmf_subsystems", spdk_rpc_get_nvmf_subsystems)

@@ -310,9 +309,8 @@ static const struct spdk_json_object_decoder rpc_subsystem_decoders[] = {
};

static void
spdk_rpc_construct_nvmf_subsystem(struct spdk_jsonrpc_server_conn *conn,
				  const struct spdk_json_val *params,
				  const struct spdk_json_val *id)
spdk_rpc_construct_nvmf_subsystem(struct spdk_jsonrpc_request *request,
				  const struct spdk_json_val *params)
{
	struct rpc_subsystem req = {};
	struct spdk_json_write_ctx *w;
@@ -338,13 +336,17 @@ spdk_rpc_construct_nvmf_subsystem(struct spdk_jsonrpc_server_conn *conn,

	free_rpc_subsystem(&req);

	w = spdk_jsonrpc_begin_result(conn, id);
	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(conn, w);
	spdk_jsonrpc_end_result(request, w);
	return;

invalid:
	spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	free_rpc_subsystem(&req);
}
SPDK_RPC_REGISTER("construct_nvmf_subsystem", spdk_rpc_construct_nvmf_subsystem)
@@ -364,9 +366,8 @@ static const struct spdk_json_object_decoder rpc_delete_subsystem_decoders[] = {
};

static void
spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_server_conn *conn,
			       const struct spdk_json_val *params,
			       const struct spdk_json_val *id)
spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_request *request,
			       const struct spdk_json_val *params)
{
	struct rpc_delete_subsystem req = {};
	struct spdk_json_write_ctx *w;
@@ -390,17 +391,17 @@ spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_server_conn *conn,

	free_rpc_delete_subsystem(&req);

	if (id == NULL) {
	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	w = spdk_jsonrpc_begin_result(conn, id);
	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(conn, w);
	spdk_jsonrpc_end_result(request, w);
	return;

invalid:
	spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	free_rpc_delete_subsystem(&req);
}
SPDK_RPC_REGISTER("delete_nvmf_subsystem", spdk_rpc_delete_nvmf_subsystem)
+34 −9
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@
#define SPDK_JSONRPC_ERROR_INTERNAL_ERROR	-32603

struct spdk_jsonrpc_server;
struct spdk_jsonrpc_server_conn;
struct spdk_jsonrpc_request;

/**
 * User callback to handle a single JSON-RPC request.
@@ -59,10 +59,9 @@ struct spdk_jsonrpc_server_conn;
 *  spdk_jsonrpc_send_error_response().
 */
typedef void (*spdk_jsonrpc_handle_request_fn)(
	struct spdk_jsonrpc_server_conn *conn,
	struct spdk_jsonrpc_request *request,
	const struct spdk_json_val *method,
	const struct spdk_json_val *params,
	const struct spdk_json_val *id);
	const struct spdk_json_val *params);

struct spdk_jsonrpc_server *spdk_jsonrpc_server_listen(int domain, int protocol,
		struct sockaddr *listen_addr, socklen_t addrlen, spdk_jsonrpc_handle_request_fn handle_request);
@@ -71,11 +70,37 @@ int spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server);

void spdk_jsonrpc_server_shutdown(struct spdk_jsonrpc_server *server);

struct spdk_json_write_ctx *spdk_jsonrpc_begin_result(struct spdk_jsonrpc_server_conn *conn,
		const struct spdk_json_val *id);
void spdk_jsonrpc_end_result(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_write_ctx *w);
/**
 * Begin building a response to a JSON-RPC request.
 *
 * \param request JSON-RPC request to respond to.
 * \return JSON write context to write the response object to, or NULL if no response is necessary.
 *
 * If this function returns non-NULL, the user must call spdk_jsonrpc_end_result() on the request
 * after writing the desired response object to the spdk_json_write_ctx.
 */
struct spdk_json_write_ctx *spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request);

/**
 * Complete and send a JSON-RPC response.
 *
 * \param request Request to complete the response for.
 * \param w JSON write context returned from spdk_jsonrpc_begin_result().
 */
void spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w);

void spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_server_conn *conn,
				      const struct spdk_json_val *id, int error_code, const char *msg);
/**
 * Send an error response to a JSON-RPC request.
 *
 * \param request JSON-RPC request to respond to.
 * \param error_code Integer error code to return (may be one of the SPDK_JSONRPC_ERROR_ errors,
 *                   or a custom error code).
 * \param msg String error message to return.
 *
 * This is shorthand for spdk_jsonrpc_begin_result() + spdk_jsonrpc_end_result() with an error
 * object.
 */
void spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
				      int error_code, const char *msg);

#endif
+2 −3
Original line number Diff line number Diff line
@@ -42,9 +42,8 @@ int spdk_rpc_listen(const char *listen_addr);
void spdk_rpc_accept(void);
void spdk_rpc_close(void);

typedef void (*spdk_rpc_method_handler)(struct spdk_jsonrpc_server_conn *conn,
					const struct spdk_json_val *params,
					const struct spdk_json_val *id);
typedef void (*spdk_rpc_method_handler)(struct spdk_jsonrpc_request *request,
					const struct spdk_json_val *params);

void spdk_rpc_register_method(const char *method, spdk_rpc_method_handler func);

+6 −7
Original line number Diff line number Diff line
@@ -55,9 +55,8 @@ static const struct spdk_json_object_decoder rpc_construct_aio_decoders[] = {
};

static void
spdk_rpc_construct_aio_bdev(struct spdk_jsonrpc_server_conn *conn,
			    const struct spdk_json_val *params,
			    const struct spdk_json_val *id)
spdk_rpc_construct_aio_bdev(struct spdk_jsonrpc_request *request,
			    const struct spdk_json_val *params)
{
	struct rpc_construct_aio req = {};
	struct spdk_json_write_ctx *w;
@@ -77,19 +76,19 @@ spdk_rpc_construct_aio_bdev(struct spdk_jsonrpc_server_conn *conn,

	free_rpc_construct_aio(&req);

	if (id == NULL) {
	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	w = spdk_jsonrpc_begin_result(conn, id);
	spdk_json_write_array_begin(w);
	spdk_json_write_string(w, spdk_bdev_get_name(bdev));
	spdk_json_write_array_end(w);
	spdk_jsonrpc_end_result(conn, w);
	spdk_jsonrpc_end_result(request, w);
	return;

invalid:
	spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	free_rpc_construct_aio(&req);
}
SPDK_RPC_REGISTER("construct_aio_bdev", spdk_rpc_construct_aio_bdev)
+12 −14
Original line number Diff line number Diff line
@@ -77,9 +77,8 @@ static const struct spdk_json_object_decoder rpc_construct_error_bdev_decoders[]
};

static void
spdk_rpc_construct_error_bdev(struct spdk_jsonrpc_server_conn *conn,
			      const struct spdk_json_val *params,
			      const struct spdk_json_val *id)
spdk_rpc_construct_error_bdev(struct spdk_jsonrpc_request *request,
			      const struct spdk_json_val *params)
{
	struct rpc_construct_error_bdev req = {};
	struct spdk_json_write_ctx *w;
@@ -103,21 +102,21 @@ spdk_rpc_construct_error_bdev(struct spdk_jsonrpc_server_conn *conn,
		goto invalid;
	}

	if (id == NULL) {
	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		free_rpc_construct_error_bdev(&req);
		return;
	}

	w = spdk_jsonrpc_begin_result(conn, id);
	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(conn, w);
	spdk_jsonrpc_end_result(request, w);

	free_rpc_construct_error_bdev(&req);

	return;

invalid:
	spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	free_rpc_construct_error_bdev(&req);
}
SPDK_RPC_REGISTER("construct_error_bdev", spdk_rpc_construct_error_bdev)
@@ -142,9 +141,8 @@ free_rpc_error_information(struct rpc_error_information *p)
}

static void
spdk_rpc_bdev_inject_error(struct spdk_jsonrpc_server_conn *conn,
			   const struct spdk_json_val *params,
			   const struct spdk_json_val *id)
spdk_rpc_bdev_inject_error(struct spdk_jsonrpc_request *request,
			   const struct spdk_json_val *params)
{
	struct rpc_error_information req = {};
	struct spdk_json_write_ctx *w;
@@ -170,17 +168,17 @@ spdk_rpc_bdev_inject_error(struct spdk_jsonrpc_server_conn *conn,

	free_rpc_error_information(&req);

	if (id == NULL) {
	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	w = spdk_jsonrpc_begin_result(conn, id);
	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(conn, w);
	spdk_jsonrpc_end_result(request, w);
	return;

invalid:
	spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	free_rpc_error_information(&req);
}
SPDK_RPC_REGISTER("bdev_inject_error", spdk_rpc_bdev_inject_error)
Loading