diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ef82107..efdef0b3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,9 @@ library now no longer exists. The contents of the app_rpc library have been moved to the event library. The app_rpc library now no longer exists. +The contents of the bdev_rpc library have been moved to the bdev library. The app_rpc +library now no longer exists. + ## v20.07: SPDK CSI driver, new accel_fw commands, I/O abort support ### accel diff --git a/app/iscsi_tgt/Makefile b/app/iscsi_tgt/Makefile index 3a86fb969..00cec78cd 100644 --- a/app/iscsi_tgt/Makefile +++ b/app/iscsi_tgt/Makefile @@ -45,7 +45,7 @@ C_SRCS := iscsi_tgt.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) event_iscsi event_net event_scsi event -SPDK_LIB_LIST += jsonrpc json rpc bdev_rpc bdev iscsi scsi accel trace conf +SPDK_LIB_LIST += jsonrpc json rpc bdev iscsi scsi accel trace conf SPDK_LIB_LIST += thread util log net sock notify ifeq ($(SPDK_ROOT_DIR)/lib/env_dpdk,$(CONFIG_ENV)) diff --git a/app/nvmf_tgt/Makefile b/app/nvmf_tgt/Makefile index a30e56d47..a20737cec 100644 --- a/app/nvmf_tgt/Makefile +++ b/app/nvmf_tgt/Makefile @@ -42,7 +42,7 @@ C_SRCS := nvmf_main.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) event_nvmf event_net SPDK_LIB_LIST += nvmf event log trace conf thread util bdev accel rpc jsonrpc json net sock -SPDK_LIB_LIST += bdev_rpc notify +SPDK_LIB_LIST += notify ifeq ($(SPDK_ROOT_DIR)/lib/env_dpdk,$(CONFIG_ENV)) SPDK_LIB_LIST += env_dpdk_rpc diff --git a/app/spdk_tgt/Makefile b/app/spdk_tgt/Makefile index 454cda4a6..c69a1688d 100644 --- a/app/spdk_tgt/Makefile +++ b/app/spdk_tgt/Makefile @@ -52,7 +52,7 @@ endif SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) event_iscsi event_net event_scsi event_nvmf event SPDK_LIB_LIST += nvmf trace log conf thread util bdev iscsi scsi accel rpc jsonrpc json -SPDK_LIB_LIST += bdev_rpc net sock notify +SPDK_LIB_LIST += net sock notify ifeq ($(SPDK_ROOT_DIR)/lib/env_dpdk,$(CONFIG_ENV)) SPDK_LIB_LIST += env_dpdk_rpc diff --git a/app/vhost/Makefile b/app/vhost/Makefile index e0d48db42..0954e223c 100644 --- a/app/vhost/Makefile +++ b/app/vhost/Makefile @@ -47,7 +47,7 @@ SPDK_LIB_LIST += rte_vhost endif SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) event_net event_scsi event -SPDK_LIB_LIST += jsonrpc json rpc bdev_rpc bdev scsi accel trace conf +SPDK_LIB_LIST += jsonrpc json rpc bdev scsi accel trace conf SPDK_LIB_LIST += thread util log SPDK_LIB_LIST += event_nbd nbd net sock notify diff --git a/examples/bdev/fio_plugin/Makefile b/examples/bdev/fio_plugin/Makefile index 18c39d2f8..109745e49 100644 --- a/examples/bdev/fio_plugin/Makefile +++ b/examples/bdev/fio_plugin/Makefile @@ -41,7 +41,7 @@ FIO_PLUGIN := spdk_bdev C_SRCS = fio_plugin.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) -SPDK_LIB_LIST += thread util bdev bdev_rpc conf accel rpc jsonrpc json log sock trace notify +SPDK_LIB_LIST += thread util bdev conf accel rpc jsonrpc json log sock trace notify SPDK_LIB_LIST += event $(EVENT_BDEV_SUBSYSTEM) include $(SPDK_ROOT_DIR)/mk/spdk.fio.mk diff --git a/examples/bdev/hello_world/Makefile b/examples/bdev/hello_world/Makefile index f4a5a5b69..8b853dbeb 100644 --- a/examples/bdev/hello_world/Makefile +++ b/examples/bdev/hello_world/Makefile @@ -39,6 +39,6 @@ C_SRCS := hello_bdev.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) -SPDK_LIB_LIST += bdev_rpc bdev accel event thread util conf trace log jsonrpc json rpc sock notify +SPDK_LIB_LIST += bdev accel event thread util conf trace log jsonrpc json rpc sock notify include $(SPDK_ROOT_DIR)/mk/spdk.app.mk diff --git a/lib/bdev/bdev_rpc.c b/lib/bdev/bdev_rpc.c index 5c8cfa469..a628b3132 100644 --- a/lib/bdev/bdev_rpc.c +++ b/lib/bdev/bdev_rpc.c @@ -33,9 +33,12 @@ #include "spdk/bdev.h" +#include "spdk/env.h" #include "spdk/rpc.h" #include "spdk/util.h" #include "spdk/string.h" +#include "spdk/base64.h" +#include "spdk/bdev_module.h" #include "spdk_internal/log.h" @@ -141,3 +144,637 @@ cleanup: free_rpc_bdev_examine(&req); } SPDK_RPC_REGISTER("bdev_examine", rpc_bdev_examine_bdev, SPDK_RPC_RUNTIME) + +struct rpc_bdev_get_iostat_ctx { + int bdev_count; + struct spdk_jsonrpc_request *request; + struct spdk_json_write_ctx *w; +}; + +static void +rpc_bdev_get_iostat_cb(struct spdk_bdev *bdev, + struct spdk_bdev_io_stat *stat, void *cb_arg, int rc) +{ + struct rpc_bdev_get_iostat_ctx *ctx = cb_arg; + struct spdk_json_write_ctx *w = ctx->w; + const char *bdev_name; + + if (rc != 0) { + goto done; + } + + bdev_name = spdk_bdev_get_name(bdev); + if (bdev_name != NULL) { + spdk_json_write_object_begin(w); + + spdk_json_write_named_string(w, "name", bdev_name); + + spdk_json_write_named_uint64(w, "bytes_read", stat->bytes_read); + + spdk_json_write_named_uint64(w, "num_read_ops", stat->num_read_ops); + + spdk_json_write_named_uint64(w, "bytes_written", stat->bytes_written); + + spdk_json_write_named_uint64(w, "num_write_ops", stat->num_write_ops); + + spdk_json_write_named_uint64(w, "bytes_unmapped", stat->bytes_unmapped); + + spdk_json_write_named_uint64(w, "num_unmap_ops", stat->num_unmap_ops); + + spdk_json_write_named_uint64(w, "read_latency_ticks", stat->read_latency_ticks); + + spdk_json_write_named_uint64(w, "write_latency_ticks", stat->write_latency_ticks); + + spdk_json_write_named_uint64(w, "unmap_latency_ticks", stat->unmap_latency_ticks); + + if (spdk_bdev_get_qd_sampling_period(bdev)) { + spdk_json_write_named_uint64(w, "queue_depth_polling_period", + spdk_bdev_get_qd_sampling_period(bdev)); + + spdk_json_write_named_uint64(w, "queue_depth", spdk_bdev_get_qd(bdev)); + + spdk_json_write_named_uint64(w, "io_time", spdk_bdev_get_io_time(bdev)); + + spdk_json_write_named_uint64(w, "weighted_io_time", + spdk_bdev_get_weighted_io_time(bdev)); + } + + spdk_json_write_object_end(w); + } + +done: + free(stat); + if (--ctx->bdev_count == 0) { + spdk_json_write_array_end(ctx->w); + spdk_json_write_object_end(w); + spdk_jsonrpc_end_result(ctx->request, ctx->w); + free(ctx); + } +} + +struct rpc_bdev_get_iostat { + char *name; +}; + +static void +free_rpc_bdev_get_iostat(struct rpc_bdev_get_iostat *r) +{ + free(r->name); +} + +static const struct spdk_json_object_decoder rpc_bdev_get_iostat_decoders[] = { + {"name", offsetof(struct rpc_bdev_get_iostat, name), spdk_json_decode_string, true}, +}; + +static void +rpc_bdev_get_iostat(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_bdev_get_iostat req = {}; + struct spdk_bdev *bdev = NULL; + struct spdk_json_write_ctx *w; + struct spdk_bdev_io_stat *stat; + struct rpc_bdev_get_iostat_ctx *ctx; + + if (params != NULL) { + if (spdk_json_decode_object(params, rpc_bdev_get_iostat_decoders, + SPDK_COUNTOF(rpc_bdev_get_iostat_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "spdk_json_decode_object failed"); + free_rpc_bdev_get_iostat(&req); + return; + } + + if (req.name) { + bdev = spdk_bdev_get_by_name(req.name); + if (bdev == NULL) { + SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); + spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); + free_rpc_bdev_get_iostat(&req); + return; + } + } + } + + free_rpc_bdev_get_iostat(&req); + + ctx = calloc(1, sizeof(struct rpc_bdev_get_iostat_ctx)); + if (ctx == NULL) { + SPDK_ERRLOG("Failed to allocate rpc_bdev_get_iostat_ctx struct\n"); + spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); + return; + } + + w = spdk_jsonrpc_begin_result(request); + /* + * Increment initial bdev_count so that it will never reach 0 in the middle + * of iterating. + */ + ctx->bdev_count++; + ctx->request = request; + ctx->w = w; + + + spdk_json_write_object_begin(w); + spdk_json_write_named_uint64(w, "tick_rate", spdk_get_ticks_hz()); + spdk_json_write_named_uint64(w, "ticks", spdk_get_ticks()); + + spdk_json_write_named_array_begin(w, "bdevs"); + + if (bdev != NULL) { + stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); + if (stat == NULL) { + SPDK_ERRLOG("Failed to allocate rpc_bdev_get_iostat_ctx struct\n"); + } else { + ctx->bdev_count++; + spdk_bdev_get_device_stat(bdev, stat, rpc_bdev_get_iostat_cb, ctx); + } + } else { + for (bdev = spdk_bdev_first(); bdev != NULL; bdev = spdk_bdev_next(bdev)) { + stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); + if (stat == NULL) { + SPDK_ERRLOG("Failed to allocate spdk_bdev_io_stat struct\n"); + break; + } + ctx->bdev_count++; + spdk_bdev_get_device_stat(bdev, stat, rpc_bdev_get_iostat_cb, ctx); + } + } + + if (--ctx->bdev_count == 0) { + spdk_json_write_array_end(w); + spdk_json_write_object_end(w); + spdk_jsonrpc_end_result(request, w); + free(ctx); + } +} +SPDK_RPC_REGISTER("bdev_get_iostat", rpc_bdev_get_iostat, SPDK_RPC_RUNTIME) +SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_get_iostat, get_bdevs_iostat) + +static void +rpc_dump_bdev_info(struct spdk_json_write_ctx *w, + struct spdk_bdev *bdev) +{ + struct spdk_bdev_alias *tmp; + uint64_t qos_limits[SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES]; + int i; + + spdk_json_write_object_begin(w); + + spdk_json_write_named_string(w, "name", spdk_bdev_get_name(bdev)); + + spdk_json_write_named_array_begin(w, "aliases"); + + TAILQ_FOREACH(tmp, spdk_bdev_get_aliases(bdev), tailq) { + spdk_json_write_string(w, tmp->alias); + } + + spdk_json_write_array_end(w); + + spdk_json_write_named_string(w, "product_name", spdk_bdev_get_product_name(bdev)); + + spdk_json_write_named_uint32(w, "block_size", spdk_bdev_get_block_size(bdev)); + + spdk_json_write_named_uint64(w, "num_blocks", spdk_bdev_get_num_blocks(bdev)); + + if (!spdk_mem_all_zero(&bdev->uuid, sizeof(bdev->uuid))) { + char uuid_str[SPDK_UUID_STRING_LEN]; + + spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &bdev->uuid); + spdk_json_write_named_string(w, "uuid", uuid_str); + } + + if (spdk_bdev_get_md_size(bdev) != 0) { + spdk_json_write_named_uint32(w, "md_size", spdk_bdev_get_md_size(bdev)); + spdk_json_write_named_bool(w, "md_interleave", spdk_bdev_is_md_interleaved(bdev)); + spdk_json_write_named_uint32(w, "dif_type", spdk_bdev_get_dif_type(bdev)); + if (spdk_bdev_get_dif_type(bdev) != SPDK_DIF_DISABLE) { + spdk_json_write_named_bool(w, "dif_is_head_of_md", spdk_bdev_is_dif_head_of_md(bdev)); + spdk_json_write_named_object_begin(w, "enabled_dif_check_types"); + spdk_json_write_named_bool(w, "reftag", + spdk_bdev_is_dif_check_enabled(bdev, SPDK_DIF_CHECK_TYPE_REFTAG)); + spdk_json_write_named_bool(w, "apptag", + spdk_bdev_is_dif_check_enabled(bdev, SPDK_DIF_CHECK_TYPE_APPTAG)); + spdk_json_write_named_bool(w, "guard", + spdk_bdev_is_dif_check_enabled(bdev, SPDK_DIF_CHECK_TYPE_GUARD)); + spdk_json_write_object_end(w); + } + } + + spdk_json_write_named_object_begin(w, "assigned_rate_limits"); + spdk_bdev_get_qos_rate_limits(bdev, qos_limits); + for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) { + spdk_json_write_named_uint64(w, spdk_bdev_get_qos_rpc_type(i), qos_limits[i]); + } + spdk_json_write_object_end(w); + + spdk_json_write_named_bool(w, "claimed", (bdev->internal.claim_module != NULL)); + + spdk_json_write_named_bool(w, "zoned", bdev->zoned); + if (bdev->zoned) { + spdk_json_write_named_uint64(w, "zone_size", bdev->zone_size); + spdk_json_write_named_uint64(w, "max_open_zones", bdev->max_open_zones); + spdk_json_write_named_uint64(w, "optimal_open_zones", bdev->optimal_open_zones); + } + + spdk_json_write_named_object_begin(w, "supported_io_types"); + spdk_json_write_named_bool(w, "read", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_READ)); + spdk_json_write_named_bool(w, "write", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_WRITE)); + spdk_json_write_named_bool(w, "unmap", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)); + spdk_json_write_named_bool(w, "write_zeroes", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_WRITE_ZEROES)); + spdk_json_write_named_bool(w, "flush", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_FLUSH)); + spdk_json_write_named_bool(w, "reset", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_RESET)); + spdk_json_write_named_bool(w, "nvme_admin", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_NVME_ADMIN)); + spdk_json_write_named_bool(w, "nvme_io", + spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_NVME_IO)); + spdk_json_write_object_end(w); + + spdk_json_write_named_object_begin(w, "driver_specific"); + spdk_bdev_dump_info_json(bdev, w); + spdk_json_write_object_end(w); + + spdk_json_write_object_end(w); +} + +struct rpc_bdev_get_bdevs { + char *name; +}; + +static void +free_rpc_bdev_get_bdevs(struct rpc_bdev_get_bdevs *r) +{ + free(r->name); +} + +static const struct spdk_json_object_decoder rpc_bdev_get_bdevs_decoders[] = { + {"name", offsetof(struct rpc_bdev_get_bdevs, name), spdk_json_decode_string, true}, +}; + +static void +rpc_bdev_get_bdevs(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_bdev_get_bdevs req = {}; + struct spdk_json_write_ctx *w; + struct spdk_bdev *bdev = NULL; + + if (params && spdk_json_decode_object(params, rpc_bdev_get_bdevs_decoders, + SPDK_COUNTOF(rpc_bdev_get_bdevs_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "spdk_json_decode_object failed"); + free_rpc_bdev_get_bdevs(&req); + return; + } + + if (req.name) { + bdev = spdk_bdev_get_by_name(req.name); + if (bdev == NULL) { + SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); + spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); + free_rpc_bdev_get_bdevs(&req); + return; + } + } + + free_rpc_bdev_get_bdevs(&req); + w = spdk_jsonrpc_begin_result(request); + spdk_json_write_array_begin(w); + + if (bdev != NULL) { + rpc_dump_bdev_info(w, bdev); + } else { + for (bdev = spdk_bdev_first(); bdev != NULL; bdev = spdk_bdev_next(bdev)) { + rpc_dump_bdev_info(w, bdev); + } + } + + spdk_json_write_array_end(w); + + spdk_jsonrpc_end_result(request, w); +} +SPDK_RPC_REGISTER("bdev_get_bdevs", rpc_bdev_get_bdevs, SPDK_RPC_RUNTIME) +SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_get_bdevs, get_bdevs) + +struct rpc_bdev_set_qd_sampling_period { + char *name; + uint64_t period; +}; + +static void +free_rpc_bdev_set_qd_sampling_period(struct rpc_bdev_set_qd_sampling_period *r) +{ + free(r->name); +} + +static const struct spdk_json_object_decoder + rpc_bdev_set_qd_sampling_period_decoders[] = { + {"name", offsetof(struct rpc_bdev_set_qd_sampling_period, name), spdk_json_decode_string}, + {"period", offsetof(struct rpc_bdev_set_qd_sampling_period, period), spdk_json_decode_uint64}, +}; + +static void +rpc_bdev_set_qd_sampling_period(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_bdev_set_qd_sampling_period req = {0}; + struct spdk_bdev *bdev; + struct spdk_json_write_ctx *w; + + if (spdk_json_decode_object(params, rpc_bdev_set_qd_sampling_period_decoders, + SPDK_COUNTOF(rpc_bdev_set_qd_sampling_period_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "spdk_json_decode_object failed"); + goto cleanup; + } + + bdev = spdk_bdev_get_by_name(req.name); + if (bdev == NULL) { + SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); + spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); + goto cleanup; + } + + w = spdk_jsonrpc_begin_result(request); + spdk_bdev_set_qd_sampling_period(bdev, req.period); + + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); + +cleanup: + free_rpc_bdev_set_qd_sampling_period(&req); +} +SPDK_RPC_REGISTER("bdev_set_qd_sampling_period", + rpc_bdev_set_qd_sampling_period, + SPDK_RPC_RUNTIME) +SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_set_qd_sampling_period, + set_bdev_qd_sampling_period) + +struct rpc_bdev_set_qos_limit { + char *name; + uint64_t limits[SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES]; +}; + +static void +free_rpc_bdev_set_qos_limit(struct rpc_bdev_set_qos_limit *r) +{ + free(r->name); +} + +static const struct spdk_json_object_decoder rpc_bdev_set_qos_limit_decoders[] = { + {"name", offsetof(struct rpc_bdev_set_qos_limit, name), spdk_json_decode_string}, + { + "rw_ios_per_sec", offsetof(struct rpc_bdev_set_qos_limit, + limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT]), + spdk_json_decode_uint64, true + }, + { + "rw_mbytes_per_sec", offsetof(struct rpc_bdev_set_qos_limit, + limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT]), + spdk_json_decode_uint64, true + }, + { + "r_mbytes_per_sec", offsetof(struct rpc_bdev_set_qos_limit, + limits[SPDK_BDEV_QOS_R_BPS_RATE_LIMIT]), + spdk_json_decode_uint64, true + }, + { + "w_mbytes_per_sec", offsetof(struct rpc_bdev_set_qos_limit, + limits[SPDK_BDEV_QOS_W_BPS_RATE_LIMIT]), + spdk_json_decode_uint64, true + }, +}; + +static void +rpc_bdev_set_qos_limit_complete(void *cb_arg, int status) +{ + struct spdk_jsonrpc_request *request = cb_arg; + struct spdk_json_write_ctx *w; + + if (status != 0) { + spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Failed to configure rate limit: %s", + spdk_strerror(-status)); + return; + } + + w = spdk_jsonrpc_begin_result(request); + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); +} + +static void +rpc_bdev_set_qos_limit(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_bdev_set_qos_limit req = {NULL, {UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX}}; + struct spdk_bdev *bdev; + int i; + + if (spdk_json_decode_object(params, rpc_bdev_set_qos_limit_decoders, + SPDK_COUNTOF(rpc_bdev_set_qos_limit_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "spdk_json_decode_object failed"); + goto cleanup; + } + + bdev = spdk_bdev_get_by_name(req.name); + if (bdev == NULL) { + SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); + spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); + goto cleanup; + } + + for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) { + if (req.limits[i] != UINT64_MAX) { + break; + } + } + if (i == SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES) { + SPDK_ERRLOG("no rate limits specified\n"); + spdk_jsonrpc_send_error_response(request, -EINVAL, "No rate limits specified"); + goto cleanup; + } + + spdk_bdev_set_qos_rate_limits(bdev, req.limits, rpc_bdev_set_qos_limit_complete, request); + +cleanup: + free_rpc_bdev_set_qos_limit(&req); +} + +SPDK_RPC_REGISTER("bdev_set_qos_limit", rpc_bdev_set_qos_limit, SPDK_RPC_RUNTIME) +SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_set_qos_limit, set_bdev_qos_limit) + +/* SPDK_RPC_ENABLE_BDEV_HISTOGRAM */ + +struct rpc_bdev_enable_histogram_request { + char *name; + bool enable; +}; + +static void +free_rpc_bdev_enable_histogram_request(struct rpc_bdev_enable_histogram_request *r) +{ + free(r->name); +} + +static const struct spdk_json_object_decoder rpc_bdev_enable_histogram_request_decoders[] = { + {"name", offsetof(struct rpc_bdev_enable_histogram_request, name), spdk_json_decode_string}, + {"enable", offsetof(struct rpc_bdev_enable_histogram_request, enable), spdk_json_decode_bool}, +}; + +static void +bdev_histogram_status_cb(void *cb_arg, int status) +{ + struct spdk_jsonrpc_request *request = cb_arg; + struct spdk_json_write_ctx *w = spdk_jsonrpc_begin_result(request); + + spdk_json_write_bool(w, status == 0); + spdk_jsonrpc_end_result(request, w); +} + +static void +rpc_bdev_enable_histogram(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_bdev_enable_histogram_request req = {NULL}; + struct spdk_bdev *bdev; + + if (spdk_json_decode_object(params, rpc_bdev_enable_histogram_request_decoders, + SPDK_COUNTOF(rpc_bdev_enable_histogram_request_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "spdk_json_decode_object failed"); + goto cleanup; + } + + bdev = spdk_bdev_get_by_name(req.name); + if (bdev == NULL) { + spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); + goto cleanup; + } + + spdk_bdev_histogram_enable(bdev, bdev_histogram_status_cb, request, req.enable); + +cleanup: + free_rpc_bdev_enable_histogram_request(&req); +} + +SPDK_RPC_REGISTER("bdev_enable_histogram", rpc_bdev_enable_histogram, SPDK_RPC_RUNTIME) +SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_enable_histogram, enable_bdev_histogram) + +/* SPDK_RPC_GET_BDEV_HISTOGRAM */ + +struct rpc_bdev_get_histogram_request { + char *name; +}; + +static const struct spdk_json_object_decoder rpc_bdev_get_histogram_request_decoders[] = { + {"name", offsetof(struct rpc_bdev_get_histogram_request, name), spdk_json_decode_string} +}; + +static void +free_rpc_bdev_get_histogram_request(struct rpc_bdev_get_histogram_request *r) +{ + free(r->name); +} + +static void +_rpc_bdev_histogram_data_cb(void *cb_arg, int status, struct spdk_histogram_data *histogram) +{ + struct spdk_jsonrpc_request *request = cb_arg; + struct spdk_json_write_ctx *w; + int rc; + char *encoded_histogram; + size_t src_len, dst_len; + + + if (status != 0) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + spdk_strerror(-status)); + goto invalid; + } + + src_len = SPDK_HISTOGRAM_NUM_BUCKETS(histogram) * sizeof(uint64_t); + dst_len = spdk_base64_get_encoded_strlen(src_len) + 1; + + encoded_histogram = malloc(dst_len); + if (encoded_histogram == NULL) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + spdk_strerror(ENOMEM)); + goto invalid; + } + + rc = spdk_base64_encode(encoded_histogram, histogram->bucket, src_len); + if (rc != 0) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + spdk_strerror(-rc)); + goto free_encoded_histogram; + } + + w = spdk_jsonrpc_begin_result(request); + spdk_json_write_object_begin(w); + spdk_json_write_named_string(w, "histogram", encoded_histogram); + spdk_json_write_named_int64(w, "bucket_shift", histogram->bucket_shift); + spdk_json_write_named_int64(w, "tsc_rate", spdk_get_ticks_hz()); + spdk_json_write_object_end(w); + spdk_jsonrpc_end_result(request, w); + +free_encoded_histogram: + free(encoded_histogram); +invalid: + spdk_histogram_data_free(histogram); +} + +static void +rpc_bdev_get_histogram(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_bdev_get_histogram_request req = {NULL}; + struct spdk_histogram_data *histogram; + struct spdk_bdev *bdev; + + if (spdk_json_decode_object(params, rpc_bdev_get_histogram_request_decoders, + SPDK_COUNTOF(rpc_bdev_get_histogram_request_decoders), + &req)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "spdk_json_decode_object failed"); + goto cleanup; + } + + bdev = spdk_bdev_get_by_name(req.name); + if (bdev == NULL) { + spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); + goto cleanup; + } + + histogram = spdk_histogram_data_alloc(); + if (histogram == NULL) { + spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); + goto cleanup; + } + + spdk_bdev_histogram_get(bdev, histogram, _rpc_bdev_histogram_data_cb, request); + +cleanup: + free_rpc_bdev_get_histogram_request(&req); +} + +SPDK_RPC_REGISTER("bdev_get_histogram", rpc_bdev_get_histogram, SPDK_RPC_RUNTIME) +SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_get_histogram, get_bdev_histogram) diff --git a/lib/rocksdb/spdk.rocksdb.mk b/lib/rocksdb/spdk.rocksdb.mk index c55017303..fce569b86 100644 --- a/lib/rocksdb/spdk.rocksdb.mk +++ b/lib/rocksdb/spdk.rocksdb.mk @@ -56,7 +56,7 @@ endif SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) SPDK_LIB_LIST += bdev accel event util conf trace log jsonrpc json rpc sock thread notify -SPDK_LIB_LIST += bdev_rpc blobfs_bdev +SPDK_LIB_LIST += blobfs_bdev AM_LINK += $(SPDK_LIB_LINKER_ARGS) $(ENV_LINKER_ARGS) AM_LINK += $(SYS_LIBS) diff --git a/module/bdev/Makefile b/module/bdev/Makefile index 2e30470ec..bbf33fdfe 100644 --- a/module/bdev/Makefile +++ b/module/bdev/Makefile @@ -34,7 +34,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -DIRS-y += delay error gpt lvol malloc null nvme passthru raid rpc split zone_block +DIRS-y += delay error gpt lvol malloc null nvme passthru raid split zone_block DIRS-$(CONFIG_CRYPTO) += crypto diff --git a/module/bdev/rpc/Makefile b/module/bdev/rpc/Makefile deleted file mode 100644 index 15de4fef9..000000000 --- a/module/bdev/rpc/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# BSD LICENSE -# -# Copyright (c) Intel Corporation. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../..) -include $(SPDK_ROOT_DIR)/mk/spdk.common.mk - -SO_VER := 2 -SO_MINOR := 0 - -C_SRCS = bdev_rpc.c -LIBNAME = bdev_rpc - -SPDK_MAP_FILE = $(SPDK_ROOT_DIR)/mk/spdk_blank.map - -include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk diff --git a/module/bdev/rpc/bdev_rpc.c b/module/bdev/rpc/bdev_rpc.c deleted file mode 100644 index 166ab1a42..000000000 --- a/module/bdev/rpc/bdev_rpc.c +++ /dev/null @@ -1,676 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright (c) Intel Corporation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "spdk/env.h" -#include "spdk/log.h" -#include "spdk/rpc.h" -#include "spdk/string.h" -#include "spdk/util.h" -#include "spdk/histogram_data.h" -#include "spdk/base64.h" - -#include "spdk/bdev_module.h" - -struct rpc_bdev_get_iostat_ctx { - int bdev_count; - struct spdk_jsonrpc_request *request; - struct spdk_json_write_ctx *w; -}; - -static void -rpc_bdev_get_iostat_cb(struct spdk_bdev *bdev, - struct spdk_bdev_io_stat *stat, void *cb_arg, int rc) -{ - struct rpc_bdev_get_iostat_ctx *ctx = cb_arg; - struct spdk_json_write_ctx *w = ctx->w; - const char *bdev_name; - - if (rc != 0) { - goto done; - } - - bdev_name = spdk_bdev_get_name(bdev); - if (bdev_name != NULL) { - spdk_json_write_object_begin(w); - - spdk_json_write_named_string(w, "name", bdev_name); - - spdk_json_write_named_uint64(w, "bytes_read", stat->bytes_read); - - spdk_json_write_named_uint64(w, "num_read_ops", stat->num_read_ops); - - spdk_json_write_named_uint64(w, "bytes_written", stat->bytes_written); - - spdk_json_write_named_uint64(w, "num_write_ops", stat->num_write_ops); - - spdk_json_write_named_uint64(w, "bytes_unmapped", stat->bytes_unmapped); - - spdk_json_write_named_uint64(w, "num_unmap_ops", stat->num_unmap_ops); - - spdk_json_write_named_uint64(w, "read_latency_ticks", stat->read_latency_ticks); - - spdk_json_write_named_uint64(w, "write_latency_ticks", stat->write_latency_ticks); - - spdk_json_write_named_uint64(w, "unmap_latency_ticks", stat->unmap_latency_ticks); - - if (spdk_bdev_get_qd_sampling_period(bdev)) { - spdk_json_write_named_uint64(w, "queue_depth_polling_period", - spdk_bdev_get_qd_sampling_period(bdev)); - - spdk_json_write_named_uint64(w, "queue_depth", spdk_bdev_get_qd(bdev)); - - spdk_json_write_named_uint64(w, "io_time", spdk_bdev_get_io_time(bdev)); - - spdk_json_write_named_uint64(w, "weighted_io_time", - spdk_bdev_get_weighted_io_time(bdev)); - } - - spdk_json_write_object_end(w); - } - -done: - free(stat); - if (--ctx->bdev_count == 0) { - spdk_json_write_array_end(ctx->w); - spdk_json_write_object_end(w); - spdk_jsonrpc_end_result(ctx->request, ctx->w); - free(ctx); - } -} - -struct rpc_bdev_get_iostat { - char *name; -}; - -static void -free_rpc_bdev_get_iostat(struct rpc_bdev_get_iostat *r) -{ - free(r->name); -} - -static const struct spdk_json_object_decoder rpc_bdev_get_iostat_decoders[] = { - {"name", offsetof(struct rpc_bdev_get_iostat, name), spdk_json_decode_string, true}, -}; - -static void -rpc_bdev_get_iostat(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) -{ - struct rpc_bdev_get_iostat req = {}; - struct spdk_bdev *bdev = NULL; - struct spdk_json_write_ctx *w; - struct spdk_bdev_io_stat *stat; - struct rpc_bdev_get_iostat_ctx *ctx; - - if (params != NULL) { - if (spdk_json_decode_object(params, rpc_bdev_get_iostat_decoders, - SPDK_COUNTOF(rpc_bdev_get_iostat_decoders), - &req)) { - SPDK_ERRLOG("spdk_json_decode_object failed\n"); - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - "spdk_json_decode_object failed"); - free_rpc_bdev_get_iostat(&req); - return; - } - - if (req.name) { - bdev = spdk_bdev_get_by_name(req.name); - if (bdev == NULL) { - SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); - spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); - free_rpc_bdev_get_iostat(&req); - return; - } - } - } - - free_rpc_bdev_get_iostat(&req); - - ctx = calloc(1, sizeof(struct rpc_bdev_get_iostat_ctx)); - if (ctx == NULL) { - SPDK_ERRLOG("Failed to allocate rpc_bdev_get_iostat_ctx struct\n"); - spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); - return; - } - - w = spdk_jsonrpc_begin_result(request); - /* - * Increment initial bdev_count so that it will never reach 0 in the middle - * of iterating. - */ - ctx->bdev_count++; - ctx->request = request; - ctx->w = w; - - - spdk_json_write_object_begin(w); - spdk_json_write_named_uint64(w, "tick_rate", spdk_get_ticks_hz()); - spdk_json_write_named_uint64(w, "ticks", spdk_get_ticks()); - - spdk_json_write_named_array_begin(w, "bdevs"); - - if (bdev != NULL) { - stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); - if (stat == NULL) { - SPDK_ERRLOG("Failed to allocate rpc_bdev_get_iostat_ctx struct\n"); - } else { - ctx->bdev_count++; - spdk_bdev_get_device_stat(bdev, stat, rpc_bdev_get_iostat_cb, ctx); - } - } else { - for (bdev = spdk_bdev_first(); bdev != NULL; bdev = spdk_bdev_next(bdev)) { - stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); - if (stat == NULL) { - SPDK_ERRLOG("Failed to allocate spdk_bdev_io_stat struct\n"); - break; - } - ctx->bdev_count++; - spdk_bdev_get_device_stat(bdev, stat, rpc_bdev_get_iostat_cb, ctx); - } - } - - if (--ctx->bdev_count == 0) { - spdk_json_write_array_end(w); - spdk_json_write_object_end(w); - spdk_jsonrpc_end_result(request, w); - free(ctx); - } -} -SPDK_RPC_REGISTER("bdev_get_iostat", rpc_bdev_get_iostat, SPDK_RPC_RUNTIME) -SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_get_iostat, get_bdevs_iostat) - -static void -rpc_dump_bdev_info(struct spdk_json_write_ctx *w, - struct spdk_bdev *bdev) -{ - struct spdk_bdev_alias *tmp; - uint64_t qos_limits[SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES]; - int i; - - spdk_json_write_object_begin(w); - - spdk_json_write_named_string(w, "name", spdk_bdev_get_name(bdev)); - - spdk_json_write_named_array_begin(w, "aliases"); - - TAILQ_FOREACH(tmp, spdk_bdev_get_aliases(bdev), tailq) { - spdk_json_write_string(w, tmp->alias); - } - - spdk_json_write_array_end(w); - - spdk_json_write_named_string(w, "product_name", spdk_bdev_get_product_name(bdev)); - - spdk_json_write_named_uint32(w, "block_size", spdk_bdev_get_block_size(bdev)); - - spdk_json_write_named_uint64(w, "num_blocks", spdk_bdev_get_num_blocks(bdev)); - - if (!spdk_mem_all_zero(&bdev->uuid, sizeof(bdev->uuid))) { - char uuid_str[SPDK_UUID_STRING_LEN]; - - spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &bdev->uuid); - spdk_json_write_named_string(w, "uuid", uuid_str); - } - - if (spdk_bdev_get_md_size(bdev) != 0) { - spdk_json_write_named_uint32(w, "md_size", spdk_bdev_get_md_size(bdev)); - spdk_json_write_named_bool(w, "md_interleave", spdk_bdev_is_md_interleaved(bdev)); - spdk_json_write_named_uint32(w, "dif_type", spdk_bdev_get_dif_type(bdev)); - if (spdk_bdev_get_dif_type(bdev) != SPDK_DIF_DISABLE) { - spdk_json_write_named_bool(w, "dif_is_head_of_md", spdk_bdev_is_dif_head_of_md(bdev)); - spdk_json_write_named_object_begin(w, "enabled_dif_check_types"); - spdk_json_write_named_bool(w, "reftag", - spdk_bdev_is_dif_check_enabled(bdev, SPDK_DIF_CHECK_TYPE_REFTAG)); - spdk_json_write_named_bool(w, "apptag", - spdk_bdev_is_dif_check_enabled(bdev, SPDK_DIF_CHECK_TYPE_APPTAG)); - spdk_json_write_named_bool(w, "guard", - spdk_bdev_is_dif_check_enabled(bdev, SPDK_DIF_CHECK_TYPE_GUARD)); - spdk_json_write_object_end(w); - } - } - - spdk_json_write_named_object_begin(w, "assigned_rate_limits"); - spdk_bdev_get_qos_rate_limits(bdev, qos_limits); - for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) { - spdk_json_write_named_uint64(w, spdk_bdev_get_qos_rpc_type(i), qos_limits[i]); - } - spdk_json_write_object_end(w); - - spdk_json_write_named_bool(w, "claimed", (bdev->internal.claim_module != NULL)); - - spdk_json_write_named_bool(w, "zoned", bdev->zoned); - if (bdev->zoned) { - spdk_json_write_named_uint64(w, "zone_size", bdev->zone_size); - spdk_json_write_named_uint64(w, "max_open_zones", bdev->max_open_zones); - spdk_json_write_named_uint64(w, "optimal_open_zones", bdev->optimal_open_zones); - } - - spdk_json_write_named_object_begin(w, "supported_io_types"); - spdk_json_write_named_bool(w, "read", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_READ)); - spdk_json_write_named_bool(w, "write", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_WRITE)); - spdk_json_write_named_bool(w, "unmap", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)); - spdk_json_write_named_bool(w, "write_zeroes", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_WRITE_ZEROES)); - spdk_json_write_named_bool(w, "flush", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_FLUSH)); - spdk_json_write_named_bool(w, "reset", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_RESET)); - spdk_json_write_named_bool(w, "nvme_admin", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_NVME_ADMIN)); - spdk_json_write_named_bool(w, "nvme_io", - spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_NVME_IO)); - spdk_json_write_object_end(w); - - spdk_json_write_named_object_begin(w, "driver_specific"); - spdk_bdev_dump_info_json(bdev, w); - spdk_json_write_object_end(w); - - spdk_json_write_object_end(w); -} - -struct rpc_bdev_get_bdevs { - char *name; -}; - -static void -free_rpc_bdev_get_bdevs(struct rpc_bdev_get_bdevs *r) -{ - free(r->name); -} - -static const struct spdk_json_object_decoder rpc_bdev_get_bdevs_decoders[] = { - {"name", offsetof(struct rpc_bdev_get_bdevs, name), spdk_json_decode_string, true}, -}; - -static void -rpc_bdev_get_bdevs(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) -{ - struct rpc_bdev_get_bdevs req = {}; - struct spdk_json_write_ctx *w; - struct spdk_bdev *bdev = NULL; - - if (params && spdk_json_decode_object(params, rpc_bdev_get_bdevs_decoders, - SPDK_COUNTOF(rpc_bdev_get_bdevs_decoders), - &req)) { - SPDK_ERRLOG("spdk_json_decode_object failed\n"); - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - "spdk_json_decode_object failed"); - free_rpc_bdev_get_bdevs(&req); - return; - } - - if (req.name) { - bdev = spdk_bdev_get_by_name(req.name); - if (bdev == NULL) { - SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); - spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); - free_rpc_bdev_get_bdevs(&req); - return; - } - } - - free_rpc_bdev_get_bdevs(&req); - w = spdk_jsonrpc_begin_result(request); - spdk_json_write_array_begin(w); - - if (bdev != NULL) { - rpc_dump_bdev_info(w, bdev); - } else { - for (bdev = spdk_bdev_first(); bdev != NULL; bdev = spdk_bdev_next(bdev)) { - rpc_dump_bdev_info(w, bdev); - } - } - - spdk_json_write_array_end(w); - - spdk_jsonrpc_end_result(request, w); -} -SPDK_RPC_REGISTER("bdev_get_bdevs", rpc_bdev_get_bdevs, SPDK_RPC_RUNTIME) -SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_get_bdevs, get_bdevs) - -struct rpc_bdev_set_qd_sampling_period { - char *name; - uint64_t period; -}; - -static void -free_rpc_bdev_set_qd_sampling_period(struct rpc_bdev_set_qd_sampling_period *r) -{ - free(r->name); -} - -static const struct spdk_json_object_decoder - rpc_bdev_set_qd_sampling_period_decoders[] = { - {"name", offsetof(struct rpc_bdev_set_qd_sampling_period, name), spdk_json_decode_string}, - {"period", offsetof(struct rpc_bdev_set_qd_sampling_period, period), spdk_json_decode_uint64}, -}; - -static void -rpc_bdev_set_qd_sampling_period(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) -{ - struct rpc_bdev_set_qd_sampling_period req = {0}; - struct spdk_bdev *bdev; - struct spdk_json_write_ctx *w; - - if (spdk_json_decode_object(params, rpc_bdev_set_qd_sampling_period_decoders, - SPDK_COUNTOF(rpc_bdev_set_qd_sampling_period_decoders), - &req)) { - SPDK_ERRLOG("spdk_json_decode_object failed\n"); - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - "spdk_json_decode_object failed"); - goto cleanup; - } - - bdev = spdk_bdev_get_by_name(req.name); - if (bdev == NULL) { - SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); - spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); - goto cleanup; - } - - w = spdk_jsonrpc_begin_result(request); - spdk_bdev_set_qd_sampling_period(bdev, req.period); - - spdk_json_write_bool(w, true); - spdk_jsonrpc_end_result(request, w); - -cleanup: - free_rpc_bdev_set_qd_sampling_period(&req); -} -SPDK_RPC_REGISTER("bdev_set_qd_sampling_period", - rpc_bdev_set_qd_sampling_period, - SPDK_RPC_RUNTIME) -SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_set_qd_sampling_period, - set_bdev_qd_sampling_period) - -struct rpc_bdev_set_qos_limit { - char *name; - uint64_t limits[SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES]; -}; - -static void -free_rpc_bdev_set_qos_limit(struct rpc_bdev_set_qos_limit *r) -{ - free(r->name); -} - -static const struct spdk_json_object_decoder rpc_bdev_set_qos_limit_decoders[] = { - {"name", offsetof(struct rpc_bdev_set_qos_limit, name), spdk_json_decode_string}, - { - "rw_ios_per_sec", offsetof(struct rpc_bdev_set_qos_limit, - limits[SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT]), - spdk_json_decode_uint64, true - }, - { - "rw_mbytes_per_sec", offsetof(struct rpc_bdev_set_qos_limit, - limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT]), - spdk_json_decode_uint64, true - }, - { - "r_mbytes_per_sec", offsetof(struct rpc_bdev_set_qos_limit, - limits[SPDK_BDEV_QOS_R_BPS_RATE_LIMIT]), - spdk_json_decode_uint64, true - }, - { - "w_mbytes_per_sec", offsetof(struct rpc_bdev_set_qos_limit, - limits[SPDK_BDEV_QOS_W_BPS_RATE_LIMIT]), - spdk_json_decode_uint64, true - }, -}; - -static void -rpc_bdev_set_qos_limit_complete(void *cb_arg, int status) -{ - struct spdk_jsonrpc_request *request = cb_arg; - struct spdk_json_write_ctx *w; - - if (status != 0) { - spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, - "Failed to configure rate limit: %s", - spdk_strerror(-status)); - return; - } - - w = spdk_jsonrpc_begin_result(request); - spdk_json_write_bool(w, true); - spdk_jsonrpc_end_result(request, w); -} - -static void -rpc_bdev_set_qos_limit(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) -{ - struct rpc_bdev_set_qos_limit req = {NULL, {UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX}}; - struct spdk_bdev *bdev; - int i; - - if (spdk_json_decode_object(params, rpc_bdev_set_qos_limit_decoders, - SPDK_COUNTOF(rpc_bdev_set_qos_limit_decoders), - &req)) { - SPDK_ERRLOG("spdk_json_decode_object failed\n"); - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - "spdk_json_decode_object failed"); - goto cleanup; - } - - bdev = spdk_bdev_get_by_name(req.name); - if (bdev == NULL) { - SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); - spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); - goto cleanup; - } - - for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) { - if (req.limits[i] != UINT64_MAX) { - break; - } - } - if (i == SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES) { - SPDK_ERRLOG("no rate limits specified\n"); - spdk_jsonrpc_send_error_response(request, -EINVAL, "No rate limits specified"); - goto cleanup; - } - - spdk_bdev_set_qos_rate_limits(bdev, req.limits, rpc_bdev_set_qos_limit_complete, request); - -cleanup: - free_rpc_bdev_set_qos_limit(&req); -} - -SPDK_RPC_REGISTER("bdev_set_qos_limit", rpc_bdev_set_qos_limit, SPDK_RPC_RUNTIME) -SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_set_qos_limit, set_bdev_qos_limit) - -/* SPDK_RPC_ENABLE_BDEV_HISTOGRAM */ - -struct rpc_bdev_enable_histogram_request { - char *name; - bool enable; -}; - -static void -free_rpc_bdev_enable_histogram_request(struct rpc_bdev_enable_histogram_request *r) -{ - free(r->name); -} - -static const struct spdk_json_object_decoder rpc_bdev_enable_histogram_request_decoders[] = { - {"name", offsetof(struct rpc_bdev_enable_histogram_request, name), spdk_json_decode_string}, - {"enable", offsetof(struct rpc_bdev_enable_histogram_request, enable), spdk_json_decode_bool}, -}; - -static void -bdev_histogram_status_cb(void *cb_arg, int status) -{ - struct spdk_jsonrpc_request *request = cb_arg; - struct spdk_json_write_ctx *w = spdk_jsonrpc_begin_result(request); - - spdk_json_write_bool(w, status == 0); - spdk_jsonrpc_end_result(request, w); -} - -static void -rpc_bdev_enable_histogram(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) -{ - struct rpc_bdev_enable_histogram_request req = {NULL}; - struct spdk_bdev *bdev; - - if (spdk_json_decode_object(params, rpc_bdev_enable_histogram_request_decoders, - SPDK_COUNTOF(rpc_bdev_enable_histogram_request_decoders), - &req)) { - SPDK_ERRLOG("spdk_json_decode_object failed\n"); - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - "spdk_json_decode_object failed"); - goto cleanup; - } - - bdev = spdk_bdev_get_by_name(req.name); - if (bdev == NULL) { - spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); - goto cleanup; - } - - spdk_bdev_histogram_enable(bdev, bdev_histogram_status_cb, request, req.enable); - -cleanup: - free_rpc_bdev_enable_histogram_request(&req); -} - -SPDK_RPC_REGISTER("bdev_enable_histogram", rpc_bdev_enable_histogram, SPDK_RPC_RUNTIME) -SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_enable_histogram, enable_bdev_histogram) - -/* SPDK_RPC_GET_BDEV_HISTOGRAM */ - -struct rpc_bdev_get_histogram_request { - char *name; -}; - -static const struct spdk_json_object_decoder rpc_bdev_get_histogram_request_decoders[] = { - {"name", offsetof(struct rpc_bdev_get_histogram_request, name), spdk_json_decode_string} -}; - -static void -free_rpc_bdev_get_histogram_request(struct rpc_bdev_get_histogram_request *r) -{ - free(r->name); -} - -static void -_rpc_bdev_histogram_data_cb(void *cb_arg, int status, struct spdk_histogram_data *histogram) -{ - struct spdk_jsonrpc_request *request = cb_arg; - struct spdk_json_write_ctx *w; - int rc; - char *encoded_histogram; - size_t src_len, dst_len; - - - if (status != 0) { - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - spdk_strerror(-status)); - goto invalid; - } - - src_len = SPDK_HISTOGRAM_NUM_BUCKETS(histogram) * sizeof(uint64_t); - dst_len = spdk_base64_get_encoded_strlen(src_len) + 1; - - encoded_histogram = malloc(dst_len); - if (encoded_histogram == NULL) { - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - spdk_strerror(ENOMEM)); - goto invalid; - } - - rc = spdk_base64_encode(encoded_histogram, histogram->bucket, src_len); - if (rc != 0) { - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - spdk_strerror(-rc)); - goto free_encoded_histogram; - } - - w = spdk_jsonrpc_begin_result(request); - spdk_json_write_object_begin(w); - spdk_json_write_named_string(w, "histogram", encoded_histogram); - spdk_json_write_named_int64(w, "bucket_shift", histogram->bucket_shift); - spdk_json_write_named_int64(w, "tsc_rate", spdk_get_ticks_hz()); - spdk_json_write_object_end(w); - spdk_jsonrpc_end_result(request, w); - -free_encoded_histogram: - free(encoded_histogram); -invalid: - spdk_histogram_data_free(histogram); -} - -static void -rpc_bdev_get_histogram(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) -{ - struct rpc_bdev_get_histogram_request req = {NULL}; - struct spdk_histogram_data *histogram; - struct spdk_bdev *bdev; - - if (spdk_json_decode_object(params, rpc_bdev_get_histogram_request_decoders, - SPDK_COUNTOF(rpc_bdev_get_histogram_request_decoders), - &req)) { - SPDK_ERRLOG("spdk_json_decode_object failed\n"); - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - "spdk_json_decode_object failed"); - goto cleanup; - } - - bdev = spdk_bdev_get_by_name(req.name); - if (bdev == NULL) { - spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); - goto cleanup; - } - - histogram = spdk_histogram_data_alloc(); - if (histogram == NULL) { - spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); - goto cleanup; - } - - spdk_bdev_histogram_get(bdev, histogram, _rpc_bdev_histogram_data_cb, request); - -cleanup: - free_rpc_bdev_get_histogram_request(&req); -} - -SPDK_RPC_REGISTER("bdev_get_histogram", rpc_bdev_get_histogram, SPDK_RPC_RUNTIME) -SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_get_histogram, get_bdev_histogram) diff --git a/test/app/bdev_svc/Makefile b/test/app/bdev_svc/Makefile index 2ff54d1c1..5ef0dfc79 100644 --- a/test/app/bdev_svc/Makefile +++ b/test/app/bdev_svc/Makefile @@ -42,7 +42,7 @@ C_SRCS := bdev_svc.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) SPDK_LIB_LIST += nvmf event log trace conf thread util bdev accel rpc jsonrpc json sock blobfs_bdev -SPDK_LIB_LIST += bdev_rpc notify +SPDK_LIB_LIST += notify ifeq ($(OS),Linux) SPDK_LIB_LIST += event_nbd nbd diff --git a/test/bdev/bdevio/Makefile b/test/bdev/bdevio/Makefile index 902096939..c64e2774a 100644 --- a/test/bdev/bdevio/Makefile +++ b/test/bdev/bdevio/Makefile @@ -41,7 +41,7 @@ C_SRCS := bdevio.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) -SPDK_LIB_LIST += bdev bdev_rpc accel event trace log conf thread util rpc jsonrpc json sock notify +SPDK_LIB_LIST += bdev accel event trace log conf thread util rpc jsonrpc json sock notify LIBS += -lcunit diff --git a/test/bdev/bdevperf/Makefile b/test/bdev/bdevperf/Makefile index fb2d03eae..f6cd81a5e 100644 --- a/test/bdev/bdevperf/Makefile +++ b/test/bdev/bdevperf/Makefile @@ -42,7 +42,7 @@ C_SRCS := bdevperf.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) SPDK_LIB_LIST += bdev accel event trace log conf thread util sock notify -SPDK_LIB_LIST += rpc jsonrpc json bdev_rpc +SPDK_LIB_LIST += rpc jsonrpc json ifeq ($(OS),Linux) SPDK_LIB_LIST += event_nbd nbd diff --git a/test/event/app_repeat/Makefile b/test/event/app_repeat/Makefile index 3fc9fc509..f7c9b2747 100644 --- a/test/event/app_repeat/Makefile +++ b/test/event/app_repeat/Makefile @@ -42,7 +42,7 @@ C_SRCS := app_repeat.c # the repeatable ones. SPDK_LIB_LIST = event_bdev event_accel event_vmd event_sock SPDK_LIB_LIST += event log trace conf thread util bdev accel rpc jsonrpc json sock vmd -SPDK_LIB_LIST += bdev_rpc notify +SPDK_LIB_LIST += notify SPDK_LIB_LIST += event_nbd nbd BLOCKDEV_LIST = bdev_malloc bdev_null