diff --git a/include/spdk_internal/event.h b/include/spdk_internal/event.h index 7be3a0ea1c..25bdc04eff 100644 --- a/include/spdk_internal/event.h +++ b/include/spdk_internal/event.h @@ -58,7 +58,14 @@ struct spdk_subsystem { void (*init)(void); void (*fini)(void); void (*config)(FILE *fp); - void (*write_config_json)(struct spdk_json_write_ctx *w); + + /** + * Write JSON configuration handler. + * + * \param w JSON write context + * \param done_ev Done event to be called when writing is done. + */ + void (*write_config_json)(struct spdk_json_write_ctx *w, struct spdk_event *done_ev); TAILQ_ENTRY(spdk_subsystem) tailq; }; @@ -86,13 +93,17 @@ void spdk_subsystem_fini_next(void); void spdk_subsystem_config(FILE *fp); /** - * Save pointed subsystem configuration to the JSON write context. In case of - * error \c null is written to the JSON context. + * Save pointed \c subsystem configuration to the JSON write context \c w. In case of + * error \c null is written to the JSON context. Writing might be done in async way + * so caller need to pass event that subsystem will call when it finish writing + * configuration. * * \param w JSON write context * \param subsystem the subsystem to query + * \param done_ev event to be called when writing is done */ -void spdk_subsystem_config_json(struct spdk_json_write_ctx *w, struct spdk_subsystem *subsystem); +void spdk_subsystem_config_json(struct spdk_json_write_ctx *w, struct spdk_subsystem *subsystem, + struct spdk_event *done_ev); void spdk_rpc_initialize(const char *listen_addr); void spdk_rpc_finish(void); diff --git a/lib/event/rpc/subsystem_rpc.c b/lib/event/rpc/subsystem_rpc.c index 36635e2bbe..c38b371a7f 100644 --- a/lib/event/rpc/subsystem_rpc.c +++ b/lib/event/rpc/subsystem_rpc.c @@ -35,6 +35,7 @@ #include "spdk/rpc.h" #include "spdk/string.h" #include "spdk/util.h" +#include "spdk/env.h" static void spdk_rpc_get_subsystems(struct spdk_jsonrpc_request *request, @@ -84,6 +85,15 @@ static const struct spdk_json_object_decoder rpc_get_subsystem_config[] = { {"name", offsetof(struct rpc_get_subsystem_config, name), spdk_json_decode_string}, }; +static void +rpc_get_subsystem_config_done(void *arg1, void *arg2) +{ + struct spdk_jsonrpc_request *request = arg1; + struct spdk_json_write_ctx *w = arg2; + + spdk_jsonrpc_end_result(request, w); +} + static void spdk_rpc_get_subsystem_config(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) @@ -91,6 +101,7 @@ spdk_rpc_get_subsystem_config(struct spdk_jsonrpc_request *request, struct rpc_get_subsystem_config req = {}; struct spdk_json_write_ctx *w; struct spdk_subsystem *subsystem; + struct spdk_event *ev; if (spdk_json_decode_object(params, rpc_get_subsystem_config, SPDK_COUNTOF(rpc_get_subsystem_config), &req)) { @@ -102,17 +113,17 @@ spdk_rpc_get_subsystem_config(struct spdk_jsonrpc_request *request, if (!subsystem) { spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Subsystem '%s' not found", req.name); - goto out; + free(req.name); + return; } + free(req.name); + w = spdk_jsonrpc_begin_result(request); if (w) { - spdk_subsystem_config_json(w, subsystem); - spdk_jsonrpc_end_result(request, w); + ev = spdk_event_allocate(spdk_env_get_current_core(), rpc_get_subsystem_config_done, request, w); + spdk_subsystem_config_json(w, subsystem, ev); } - -out: - free(req.name); } SPDK_RPC_REGISTER("get_subsystem_config", spdk_rpc_get_subsystem_config) diff --git a/lib/event/subsystem.c b/lib/event/subsystem.c index 4c34544da0..438e7f543c 100644 --- a/lib/event/subsystem.c +++ b/lib/event/subsystem.c @@ -244,11 +244,13 @@ spdk_subsystem_config(FILE *fp) } void -spdk_subsystem_config_json(struct spdk_json_write_ctx *w, struct spdk_subsystem *subsystem) +spdk_subsystem_config_json(struct spdk_json_write_ctx *w, struct spdk_subsystem *subsystem, + struct spdk_event *done_ev) { if (subsystem && subsystem->write_config_json) { - subsystem->write_config_json(w); + subsystem->write_config_json(w, done_ev); } else { spdk_json_write_null(w); + spdk_event_call(done_ev); } } diff --git a/lib/event/subsystems/bdev/bdev.c b/lib/event/subsystems/bdev/bdev.c index da58a6473f..e98ba351c0 100644 --- a/lib/event/subsystems/bdev/bdev.c +++ b/lib/event/subsystems/bdev/bdev.c @@ -64,12 +64,19 @@ spdk_bdev_subsystem_finish(void) spdk_bdev_finish(spdk_bdev_subsystem_finish_done, NULL); } +static void +_spdk_bdev_subsystem_config_json(struct spdk_json_write_ctx *w, struct spdk_event *done_ev) +{ + spdk_bdev_subsystem_config_json(w); + spdk_event_call(done_ev); +} + static struct spdk_subsystem g_spdk_subsystem_bdev = { .name = "bdev", .init = spdk_bdev_subsystem_initialize, .fini = spdk_bdev_subsystem_finish, .config = spdk_bdev_config_text, - .write_config_json = spdk_bdev_subsystem_config_json, + .write_config_json = _spdk_bdev_subsystem_config_json, }; SPDK_SUBSYSTEM_REGISTER(g_spdk_subsystem_bdev);