diff --git a/include/spdk/vhost.h b/include/spdk/vhost.h index 30bd8b13d..7af284d84 100644 --- a/include/spdk/vhost.h +++ b/include/spdk/vhost.h @@ -42,6 +42,7 @@ #include "spdk/stdinc.h" #include "spdk/event.h" +#include "spdk/json.h" #ifdef __cplusplus extern "C" { @@ -77,6 +78,15 @@ int spdk_vhost_init(void); */ void spdk_vhost_fini(spdk_vhost_fini_cb fini_cb); + +/** + * Write vhost subsystem configuration into provided JSON context. + * + * \param w JSON write context + * \param done_ev call this event when done. + */ +void spdk_vhost_config_json(struct spdk_json_write_ctx *w, struct spdk_event *done_ev); + /** * Deinit vhost application. This is called once by SPDK app layer. */ diff --git a/lib/event/subsystems/vhost/vhost.c b/lib/event/subsystems/vhost/vhost.c index 078c3664a..1fdbc6aa5 100644 --- a/lib/event/subsystems/vhost/vhost.c +++ b/lib/event/subsystems/vhost/vhost.c @@ -64,6 +64,7 @@ static struct spdk_subsystem g_spdk_subsystem_vhost = { .init = spdk_vhost_subsystem_init, .fini = spdk_vhost_subsystem_fini, .config = NULL, + .write_config_json = spdk_vhost_config_json, }; SPDK_SUBSYSTEM_REGISTER(g_spdk_subsystem_vhost); diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index cf4c3cead..5679a1847 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -1158,11 +1158,10 @@ session_shutdown(void *arg) } void -spdk_vhost_dump_config_json(struct spdk_vhost_dev *vdev, - struct spdk_json_write_ctx *w) +spdk_vhost_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) { - assert(vdev->backend->dump_config_json != NULL); - vdev->backend->dump_config_json(vdev, w); + assert(vdev->backend->dump_info_json != NULL); + vdev->backend->dump_info_json(vdev, w); } int @@ -1368,5 +1367,39 @@ spdk_vhost_fini(spdk_vhost_fini_cb fini_cb) pthread_detach(tid); } +struct spdk_vhost_write_config_json_ctx { + struct spdk_json_write_ctx *w; + struct spdk_event *done_ev; +}; + +static int +spdk_vhost_config_json_cb(struct spdk_vhost_dev *vdev, void *arg) +{ + struct spdk_vhost_write_config_json_ctx *ctx = arg; + + if (vdev == NULL) { + spdk_json_write_array_end(ctx->w); + spdk_event_call(ctx->done_ev); + free(ctx); + return 0; + } + + vdev->backend->write_config_json(vdev, ctx->w); + return 0; +} + +void +spdk_vhost_config_json(struct spdk_json_write_ctx *w, struct spdk_event *done_ev) +{ + struct spdk_vhost_write_config_json_ctx *ctx = calloc(1, sizeof(*ctx)); + + ctx->w = w; + ctx->done_ev = done_ev; + + spdk_json_write_array_begin(w); + + spdk_vhost_call_external_event_foreach(spdk_vhost_config_json_cb, ctx); +} + SPDK_LOG_REGISTER_COMPONENT("vhost", SPDK_LOG_VHOST) SPDK_LOG_REGISTER_COMPONENT("vhost_ring", SPDK_LOG_VHOST_RING) diff --git a/lib/vhost/vhost_blk.c b/lib/vhost/vhost_blk.c index 179d54a36..9cbd6c8ab 100644 --- a/lib/vhost/vhost_blk.c +++ b/lib/vhost/vhost_blk.c @@ -595,7 +595,7 @@ err: } static void -spdk_vhost_blk_dump_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) +spdk_vhost_blk_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) { struct spdk_bdev *bdev = spdk_vhost_blk_get_dev(vdev); struct spdk_vhost_blk_dev *bvdev = to_blk_dev(vdev); @@ -617,6 +617,28 @@ spdk_vhost_blk_dump_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_wr spdk_json_write_object_end(w); } +static void +spdk_vhost_blk_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) +{ + struct spdk_vhost_blk_dev *bvdev = to_blk_dev(vdev); + + if (!bvdev->bdev) { + return; + } + + spdk_json_write_object_begin(w); + spdk_json_write_named_string(w, "method", "construct_vhost_blk_controller"); + + spdk_json_write_named_object_begin(w, "params"); + spdk_json_write_named_string(w, "ctrlr", vdev->name); + spdk_json_write_named_string(w, "dev_name", spdk_bdev_get_name(bvdev->bdev)); + spdk_json_write_named_string(w, "cpumask", spdk_cpuset_fmt(vdev->cpumask)); + spdk_json_write_named_bool(w, "readonly", bvdev->readonly); + spdk_json_write_object_end(w); + + spdk_json_write_object_end(w); +} + static int spdk_vhost_blk_destroy(struct spdk_vhost_dev *dev); static int @@ -672,7 +694,8 @@ static const struct spdk_vhost_dev_backend vhost_blk_device_backend = { .start_device = spdk_vhost_blk_start, .stop_device = spdk_vhost_blk_stop, .vhost_get_config = spdk_vhost_blk_get_config, - .dump_config_json = spdk_vhost_blk_dump_config_json, + .dump_info_json = spdk_vhost_blk_dump_info_json, + .write_config_json = spdk_vhost_blk_write_config_json, .remove_device = spdk_vhost_blk_destroy, }; diff --git a/lib/vhost/vhost_internal.h b/lib/vhost/vhost_internal.h index 0cd1e6dda..4d0daaf9d 100644 --- a/lib/vhost/vhost_internal.h +++ b/lib/vhost/vhost_internal.h @@ -128,7 +128,8 @@ struct spdk_vhost_dev_backend { int (*vhost_set_config)(struct spdk_vhost_dev *vdev, uint8_t *config, uint32_t offset, uint32_t size, uint32_t flags); - void (*dump_config_json)(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w); + void (*dump_info_json)(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w); + void (*write_config_json)(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w); int (*remove_device)(struct spdk_vhost_dev *vdev); }; @@ -248,7 +249,7 @@ int spdk_vhost_dev_unregister(struct spdk_vhost_dev *vdev); int spdk_vhost_scsi_controller_construct(void); int spdk_vhost_blk_controller_construct(void); -void spdk_vhost_dump_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w); +void spdk_vhost_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w); void spdk_vhost_dev_backend_event_done(void *event_ctx, int response); void spdk_vhost_lock(void); void spdk_vhost_unlock(void); diff --git a/lib/vhost/vhost_nvme.c b/lib/vhost/vhost_nvme.c index cee9910ef..e50ea0d40 100644 --- a/lib/vhost/vhost_nvme.c +++ b/lib/vhost/vhost_nvme.c @@ -1005,7 +1005,7 @@ err: } static void -spdk_vhost_nvme_dump_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) +spdk_vhost_nvme_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) { struct spdk_vhost_nvme_dev *nvme = to_nvme_dev(vdev); struct spdk_vhost_nvme_ns *ns_dev; @@ -1043,7 +1043,7 @@ spdk_vhost_nvme_dump_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_w static const struct spdk_vhost_dev_backend spdk_vhost_nvme_device_backend = { .start_device = spdk_vhost_nvme_start_device, .stop_device = spdk_vhost_nvme_stop_device, - .dump_config_json = spdk_vhost_nvme_dump_config_json, + .dump_info_json = spdk_vhost_nvme_dump_info_json, .remove_device = spdk_vhost_nvme_dev_remove, }; diff --git a/lib/vhost/vhost_rpc.c b/lib/vhost/vhost_rpc.c index 01b2260b9..b76482047 100644 --- a/lib/vhost/vhost_rpc.c +++ b/lib/vhost/vhost_rpc.c @@ -476,7 +476,7 @@ spdk_rpc_get_vhost_controllers_cb(struct spdk_vhost_dev *vdev, void *arg) spdk_json_write_name(ctx->w, "backend_specific"); spdk_json_write_object_begin(ctx->w); - spdk_vhost_dump_config_json(vdev, ctx->w); + spdk_vhost_dump_info_json(vdev, ctx->w); spdk_json_write_object_end(ctx->w); spdk_json_write_object_end(ctx->w); // ctrl diff --git a/lib/vhost/vhost_scsi.c b/lib/vhost/vhost_scsi.c index bf340bd42..20f9b82cb 100644 --- a/lib/vhost/vhost_scsi.c +++ b/lib/vhost/vhost_scsi.c @@ -107,7 +107,10 @@ struct spdk_vhost_scsi_task { static int spdk_vhost_scsi_start(struct spdk_vhost_dev *, void *); static int spdk_vhost_scsi_stop(struct spdk_vhost_dev *, void *); -static void spdk_vhost_scsi_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w); +static void spdk_vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, + struct spdk_json_write_ctx *w); +static void spdk_vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, + struct spdk_json_write_ctx *w); static int spdk_vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev); const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = { @@ -115,7 +118,8 @@ const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = { .disabled_features = SPDK_VHOST_SCSI_DISABLED_FEATURES, .start_device = spdk_vhost_scsi_start, .stop_device = spdk_vhost_scsi_stop, - .dump_config_json = spdk_vhost_scsi_config_json, + .dump_info_json = spdk_vhost_scsi_dump_info_json, + .write_config_json = spdk_vhost_scsi_write_config_json, .remove_device = spdk_vhost_scsi_dev_remove, }; @@ -1167,7 +1171,7 @@ err: } static void -spdk_vhost_scsi_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) +spdk_vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) { struct spdk_scsi_dev *sdev; struct spdk_scsi_lun *lun; @@ -1221,6 +1225,44 @@ spdk_vhost_scsi_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ spdk_json_write_array_end(w); } +static void +spdk_vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) +{ + struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev); + struct spdk_scsi_lun *lun; + uint32_t i; + + spdk_json_write_object_begin(w); + spdk_json_write_named_string(w, "method", "construct_vhost_scsi_controller"); + + spdk_json_write_named_object_begin(w, "params"); + spdk_json_write_named_string(w, "ctrlr", vdev->name); + spdk_json_write_named_string(w, "cpumask", spdk_cpuset_fmt(vdev->cpumask)); + spdk_json_write_object_end(w); + + spdk_json_write_object_end(w); + + for (i = 0; i < SPDK_COUNTOF(svdev->scsi_dev); i++) { + if (svdev->scsi_dev[i] == NULL || svdev->scsi_dev_state[i].removed) { + continue; + } + + lun = spdk_scsi_dev_get_lun(svdev->scsi_dev[i], 0); + + spdk_json_write_object_begin(w); + spdk_json_write_named_string(w, "method", "add_vhost_scsi_lun"); + + spdk_json_write_named_object_begin(w, "params"); + spdk_json_write_named_string(w, "ctrlr", vdev->name); + spdk_json_write_named_uint32(w, "scsi_target_num", i); + + spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun)); + spdk_json_write_object_end(w); + + spdk_json_write_object_end(w); + } +} + SPDK_LOG_REGISTER_COMPONENT("vhost_scsi", SPDK_LOG_VHOST_SCSI) SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_queue", SPDK_LOG_VHOST_SCSI_QUEUE) SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_data", SPDK_LOG_VHOST_SCSI_DATA) diff --git a/test/unit/lib/vhost/test_vhost.c b/test/unit/lib/vhost/test_vhost.c index ba88688c7..e6cf7c900 100644 --- a/test/unit/lib/vhost/test_vhost.c +++ b/test/unit/lib/vhost/test_vhost.c @@ -38,6 +38,8 @@ #include "spdk_internal/mock.h" #include "spdk/io_channel.h" +#include "unit/lib/json_mock.c" + struct spdk_conf_section { struct spdk_conf_section *next; char *name; @@ -87,16 +89,6 @@ DEFINE_STUB_V(spdk_vhost_call_external_event, (const char *ctrlr_name, spdk_vhos DEFINE_STUB(spdk_vhost_vring_desc_has_next, bool, (struct vring_desc *cur_desc), false); DEFINE_STUB_VP(spdk_vhost_gpa_to_vva, (struct spdk_vhost_dev *vdev, uint64_t addr), {0}); DEFINE_STUB(spdk_scsi_dev_get_id, int, (const struct spdk_scsi_dev *dev), {0}); -DEFINE_STUB(spdk_json_write_null, int, (struct spdk_json_write_ctx *w), 0); -DEFINE_STUB(spdk_json_write_bool, int, (struct spdk_json_write_ctx *w, bool val), 0); -DEFINE_STUB(spdk_json_write_name, int, (struct spdk_json_write_ctx *w, const char *name), 0); -DEFINE_STUB(spdk_json_write_object_begin, int, (struct spdk_json_write_ctx *w), 0); -DEFINE_STUB(spdk_json_write_uint32, int, (struct spdk_json_write_ctx *w, uint32_t val), 0); -DEFINE_STUB(spdk_json_write_int32, int, (struct spdk_json_write_ctx *w, int32_t val), 0); -DEFINE_STUB(spdk_json_write_string, int, (struct spdk_json_write_ctx *w, const char *val), 0); -DEFINE_STUB(spdk_json_write_array_begin, int, (struct spdk_json_write_ctx *w), 0); -DEFINE_STUB(spdk_json_write_object_end, int, (struct spdk_json_write_ctx *w), 0); -DEFINE_STUB(spdk_json_write_array_end, int, (struct spdk_json_write_ctx *w), 0); /* This sets spdk_vhost_dev_unregister to either to fail or success */ DEFINE_STUB(spdk_vhost_dev_unregister_fail, bool, (void), false); diff --git a/test/unit/lib/vhost/vhost.c/vhost_ut.c b/test/unit/lib/vhost/vhost.c/vhost_ut.c index 10717ffee..ce87a3302 100644 --- a/test/unit/lib/vhost/vhost.c/vhost_ut.c +++ b/test/unit/lib/vhost/vhost.c/vhost_ut.c @@ -38,6 +38,7 @@ #include "spdk/io_channel.h" #include "spdk_internal/mock.h" #include "common/lib/test_env.c" +#include "unit/lib/json_mock.c" #include "vhost/vhost.c"