diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index e2540dc20..ca498fb37 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -56,6 +56,7 @@ struct spdk_bdev_io; struct spdk_bdev_fn_table; +struct spdk_json_write_ctx; /** * \brief SPDK block device. @@ -286,6 +287,8 @@ struct spdk_bdev *spdk_bdev_next(struct spdk_bdev *prev); bool spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type); +int spdk_bdev_dump_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w); + struct spdk_bdev_io *spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch, void *buf, uint64_t offset, uint64_t nbytes, spdk_bdev_io_completion_cb cb, void *cb_arg); diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index c93290597..d85c5eeae 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -511,6 +511,16 @@ spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_ty return bdev->fn_table->io_type_supported(bdev, io_type); } +int +spdk_bdev_dump_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w) +{ + if (bdev->fn_table->dump_config_json) { + return bdev->fn_table->dump_config_json(bdev, w); + } + + return 0; +} + struct spdk_io_channel * spdk_bdev_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) { diff --git a/lib/bdev/bdev_module.h b/lib/bdev/bdev_module.h index ebc3f8e5d..fc627d032 100644 --- a/lib/bdev/bdev_module.h +++ b/lib/bdev/bdev_module.h @@ -139,6 +139,15 @@ struct spdk_bdev_fn_table { /** Get an I/O channel for the specific bdev for the calling thread. */ struct spdk_io_channel *(*get_io_channel)(struct spdk_bdev *bdev, uint32_t priority); + + /** + * Output driver-specific configuration to a JSON stream. Optional - may be NULL. + * + * The JSON write context will be initialized with an open object, so the bdev + * driver should write a name (based on the driver name) followed by a JSON value + * (most likely another nested object). + */ + int (*dump_config_json)(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w); }; void spdk_bdev_register(struct spdk_bdev *bdev); diff --git a/lib/bdev/nvme/blockdev_nvme.c b/lib/bdev/nvme/blockdev_nvme.c index b348fbd49..ecf7d6dc8 100644 --- a/lib/bdev/nvme/blockdev_nvme.c +++ b/lib/bdev/nvme/blockdev_nvme.c @@ -45,6 +45,7 @@ #include "spdk/conf.h" #include "spdk/endian.h" #include "spdk/bdev.h" +#include "spdk/json.h" #include "spdk/nvme.h" #include "spdk/io_channel.h" @@ -332,11 +333,28 @@ blockdev_nvme_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) return spdk_get_io_channel(nvme_bdev->ctrlr, priority, false, NULL); } +static int +blockdev_nvme_dump_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w) +{ + struct nvme_blockdev *nvme_bdev = (struct nvme_blockdev *)bdev; + + spdk_json_write_name(w, "nvme"); + spdk_json_write_object_begin(w); + + spdk_json_write_name(w, "nsid"); + spdk_json_write_uint32(w, spdk_nvme_ns_get_id(nvme_bdev->ns)); + + spdk_json_write_object_end(w); + + return 0; +} + static const struct spdk_bdev_fn_table nvmelib_fn_table = { .destruct = blockdev_nvme_destruct, .submit_request = blockdev_nvme_submit_request, .io_type_supported = blockdev_nvme_io_type_supported, .get_io_channel = blockdev_nvme_get_io_channel, + .dump_config_json = blockdev_nvme_dump_config_json, }; static bool diff --git a/lib/bdev/rpc/bdev_rpc.c b/lib/bdev/rpc/bdev_rpc.c index 8d9ccb390..c183a0a0d 100644 --- a/lib/bdev/rpc/bdev_rpc.c +++ b/lib/bdev/rpc/bdev_rpc.c @@ -74,6 +74,11 @@ spdk_rpc_get_bdevs(struct spdk_jsonrpc_server_conn *conn, spdk_json_write_name(w, "claimed"); spdk_json_write_bool(w, bdev->claimed); + spdk_json_write_name(w, "driver_specific"); + spdk_json_write_object_begin(w); + spdk_bdev_dump_config_json(bdev, w); + spdk_json_write_object_end(w); + spdk_json_write_object_end(w); } spdk_json_write_array_end(w); diff --git a/test/iscsi_tgt/rpc_config/rpc_config.sh b/test/iscsi_tgt/rpc_config/rpc_config.sh index e3faab353..8d21bb056 100755 --- a/test/iscsi_tgt/rpc_config/rpc_config.sh +++ b/test/iscsi_tgt/rpc_config/rpc_config.sh @@ -40,6 +40,8 @@ echo "iscsi_tgt is listening. Running tests..." $rpc_config_py $rpc_py +$rpc_py get_bdevs + trap - SIGINT SIGTERM EXIT iscsicleanup