1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/rpc.h" 7 #include "spdk/util.h" 8 #include "spdk/bdev_module.h" 9 #include "spdk/string.h" 10 #include "spdk/log.h" 11 12 #include "bdev_ftl.h" 13 14 static int 15 rpc_bdev_ftl_decode_uuid(const struct spdk_json_val *val, void *out) 16 { 17 char *uuid_str; 18 int ret; 19 20 uuid_str = spdk_json_strdup(val); 21 if (!uuid_str) { 22 return -ENOMEM; 23 } 24 25 ret = spdk_uuid_parse(out, uuid_str); 26 27 free(uuid_str); 28 return ret; 29 } 30 31 static const struct spdk_json_object_decoder rpc_bdev_ftl_create_decoders[] = { 32 {"name", offsetof(struct spdk_ftl_conf, name), spdk_json_decode_string}, 33 {"base_bdev", offsetof(struct spdk_ftl_conf, base_bdev), spdk_json_decode_string}, 34 {"uuid", offsetof(struct spdk_ftl_conf, uuid), rpc_bdev_ftl_decode_uuid, true}, 35 {"cache", offsetof(struct spdk_ftl_conf, cache_bdev), spdk_json_decode_string}, 36 { 37 "overprovisioning", offsetof(struct spdk_ftl_conf, overprovisioning), 38 spdk_json_decode_uint64, true 39 }, 40 { 41 "core_mask", offsetof(struct spdk_ftl_conf, core_mask), 42 spdk_json_decode_string, true 43 }, 44 }; 45 46 static void 47 rpc_bdev_ftl_create_cb(const struct ftl_bdev_info *bdev_info, void *ctx, int status) 48 { 49 struct spdk_jsonrpc_request *request = ctx; 50 char bdev_uuid[SPDK_UUID_STRING_LEN]; 51 struct spdk_json_write_ctx *w; 52 53 if (status) { 54 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 55 "Failed to create FTL bdev: %s", 56 spdk_strerror(-status)); 57 return; 58 } 59 60 w = spdk_jsonrpc_begin_result(request); 61 spdk_uuid_fmt_lower(bdev_uuid, sizeof(bdev_uuid), &bdev_info->uuid); 62 spdk_json_write_object_begin(w); 63 spdk_json_write_named_string(w, "name", bdev_info->name); 64 spdk_json_write_named_string(w, "uuid", bdev_uuid); 65 spdk_json_write_object_end(w); 66 spdk_jsonrpc_end_result(request, w); 67 } 68 69 static void 70 rpc_bdev_ftl_create(struct spdk_jsonrpc_request *request, 71 const struct spdk_json_val *params) 72 { 73 struct spdk_ftl_conf conf = {}; 74 struct spdk_json_write_ctx *w; 75 int rc; 76 77 spdk_ftl_get_default_conf(&conf); 78 79 if (spdk_json_decode_object(params, rpc_bdev_ftl_create_decoders, 80 SPDK_COUNTOF(rpc_bdev_ftl_create_decoders), 81 &conf)) { 82 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 83 "Invalid parameters"); 84 goto out; 85 } 86 87 if (spdk_mem_all_zero(&conf.uuid, sizeof(conf.uuid))) { 88 conf.mode |= SPDK_FTL_MODE_CREATE; 89 } 90 91 rc = bdev_ftl_create_bdev(&conf, rpc_bdev_ftl_create_cb, request); 92 if (rc == -ENODEV) { 93 rc = bdev_ftl_defer_init(&conf); 94 if (rc == 0) { 95 w = spdk_jsonrpc_begin_result(request); 96 spdk_json_write_string_fmt(w, "FTL bdev: %s creation deferred", conf.name); 97 spdk_jsonrpc_end_result(request, w); 98 } 99 } 100 101 if (rc) { 102 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 103 "Failed to create FTL bdev: %s", 104 spdk_strerror(-rc)); 105 } 106 out: 107 spdk_ftl_conf_deinit(&conf); 108 } 109 SPDK_RPC_REGISTER("bdev_ftl_create", rpc_bdev_ftl_create, SPDK_RPC_RUNTIME) 110 111 static void 112 rpc_bdev_ftl_load(struct spdk_jsonrpc_request *request, 113 const struct spdk_json_val *params) 114 { 115 rpc_bdev_ftl_create(request, params); 116 } 117 SPDK_RPC_REGISTER("bdev_ftl_load", rpc_bdev_ftl_load, SPDK_RPC_RUNTIME) 118 119 struct rpc_delete_ftl { 120 char *name; 121 }; 122 123 static const struct spdk_json_object_decoder rpc_delete_ftl_decoders[] = { 124 {"name", offsetof(struct rpc_delete_ftl, name), spdk_json_decode_string}, 125 }; 126 127 static void 128 rpc_bdev_ftl_delete_cb(void *cb_arg, int bdeverrno) 129 { 130 struct spdk_jsonrpc_request *request = cb_arg; 131 132 spdk_jsonrpc_send_bool_response(request, bdeverrno == 0); 133 } 134 135 static void 136 rpc_bdev_ftl_delete(struct spdk_jsonrpc_request *request, 137 const struct spdk_json_val *params) 138 { 139 struct rpc_delete_ftl attrs = {}; 140 141 if (spdk_json_decode_object(params, rpc_delete_ftl_decoders, 142 SPDK_COUNTOF(rpc_delete_ftl_decoders), 143 &attrs)) { 144 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 145 "Invalid parameters"); 146 goto invalid; 147 } 148 149 bdev_ftl_delete_bdev(attrs.name, rpc_bdev_ftl_delete_cb, request); 150 invalid: 151 free(attrs.name); 152 } 153 SPDK_RPC_REGISTER("bdev_ftl_delete", rpc_bdev_ftl_delete, SPDK_RPC_RUNTIME) 154 155 static void 156 rpc_bdev_ftl_unload(struct spdk_jsonrpc_request *request, 157 const struct spdk_json_val *params) 158 { 159 rpc_bdev_ftl_delete(request, params); 160 } 161 SPDK_RPC_REGISTER("bdev_ftl_unload", rpc_bdev_ftl_unload, SPDK_RPC_RUNTIME) 162