1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/rpc.h" 7 #include "spdk/util.h" 8 #include "spdk/string.h" 9 10 #include "vbdev_split.h" 11 #include "spdk/log.h" 12 13 struct rpc_construct_split { 14 char *base_bdev; 15 uint32_t split_count; 16 uint64_t split_size_mb; 17 }; 18 19 static const struct spdk_json_object_decoder rpc_construct_split_decoders[] = { 20 {"base_bdev", offsetof(struct rpc_construct_split, base_bdev), spdk_json_decode_string}, 21 {"split_count", offsetof(struct rpc_construct_split, split_count), spdk_json_decode_uint32}, 22 {"split_size_mb", offsetof(struct rpc_construct_split, split_size_mb), spdk_json_decode_uint64, true}, 23 }; 24 25 static void 26 dummy_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *ctx) 27 { 28 } 29 30 static void 31 rpc_bdev_split_create(struct spdk_jsonrpc_request *request, 32 const struct spdk_json_val *params) 33 { 34 struct rpc_construct_split req = {}; 35 struct spdk_json_write_ctx *w; 36 struct spdk_bdev_desc *base_desc; 37 struct spdk_bdev *base_bdev; 38 int rc; 39 40 if (spdk_json_decode_object(params, rpc_construct_split_decoders, 41 SPDK_COUNTOF(rpc_construct_split_decoders), 42 &req)) { 43 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 44 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 45 goto out; 46 } 47 48 rc = create_vbdev_split(req.base_bdev, req.split_count, req.split_size_mb); 49 if (rc < 0) { 50 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 51 "Failed to create %"PRIu32" split bdevs from '%s': %s", 52 req.split_count, req.base_bdev, spdk_strerror(-rc)); 53 goto out; 54 } 55 56 w = spdk_jsonrpc_begin_result(request); 57 spdk_json_write_array_begin(w); 58 59 rc = spdk_bdev_open_ext(req.base_bdev, false, dummy_bdev_event_cb, NULL, &base_desc); 60 if (rc == 0) { 61 struct spdk_bdev_part_base *split_base; 62 struct bdev_part_tailq *split_base_tailq; 63 struct spdk_bdev_part *split_part; 64 struct spdk_bdev *split_bdev; 65 66 base_bdev = spdk_bdev_desc_get_bdev(base_desc); 67 68 split_base = vbdev_split_get_part_base(base_bdev); 69 70 assert(split_base != NULL); 71 72 split_base_tailq = spdk_bdev_part_base_get_tailq(split_base); 73 TAILQ_FOREACH(split_part, split_base_tailq, tailq) { 74 split_bdev = spdk_bdev_part_get_bdev(split_part); 75 spdk_json_write_string(w, spdk_bdev_get_name(split_bdev)); 76 } 77 78 spdk_bdev_close(base_desc); 79 } 80 81 spdk_json_write_array_end(w); 82 spdk_jsonrpc_end_result(request, w); 83 84 out: 85 free(req.base_bdev); 86 } 87 SPDK_RPC_REGISTER("bdev_split_create", rpc_bdev_split_create, SPDK_RPC_RUNTIME) 88 89 struct rpc_delete_split { 90 char *base_bdev; 91 }; 92 93 static const struct spdk_json_object_decoder rpc_delete_split_decoders[] = { 94 {"base_bdev", offsetof(struct rpc_delete_split, base_bdev), spdk_json_decode_string}, 95 }; 96 97 static void 98 rpc_bdev_split_delete(struct spdk_jsonrpc_request *request, 99 const struct spdk_json_val *params) 100 { 101 struct rpc_delete_split req = {}; 102 int rc; 103 104 if (spdk_json_decode_object(params, rpc_delete_split_decoders, 105 SPDK_COUNTOF(rpc_delete_split_decoders), 106 &req)) { 107 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 108 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 109 goto out; 110 } 111 112 rc = vbdev_split_destruct(req.base_bdev); 113 if (rc < 0) { 114 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc)); 115 goto out; 116 } 117 118 spdk_jsonrpc_send_bool_response(request, true); 119 out: 120 free(req.base_bdev); 121 } 122 SPDK_RPC_REGISTER("bdev_split_delete", rpc_bdev_split_delete, SPDK_RPC_RUNTIME) 123