xref: /spdk/module/bdev/malloc/bdev_malloc_rpc.c (revision 7506a7aa53d239f533af3bc768f0d2af55e735fe)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
7  *
8  *   Redistribution and use in source and binary forms, with or without
9  *   modification, are permitted provided that the following conditions
10  *   are met:
11  *
12  *     * Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *     * Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in
16  *       the documentation and/or other materials provided with the
17  *       distribution.
18  *     * Neither the name of Intel Corporation nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "bdev_malloc.h"
36 #include "spdk/rpc.h"
37 #include "spdk/util.h"
38 #include "spdk/uuid.h"
39 #include "spdk/string.h"
40 #include "spdk/log.h"
41 
42 struct rpc_construct_malloc {
43 	char *name;
44 	char *uuid;
45 	uint64_t num_blocks;
46 	uint32_t block_size;
47 	uint32_t optimal_io_boundary;
48 };
49 
50 static void
51 free_rpc_construct_malloc(struct rpc_construct_malloc *r)
52 {
53 	free(r->name);
54 	free(r->uuid);
55 }
56 
57 static const struct spdk_json_object_decoder rpc_construct_malloc_decoders[] = {
58 	{"name", offsetof(struct rpc_construct_malloc, name), spdk_json_decode_string, true},
59 	{"uuid", offsetof(struct rpc_construct_malloc, uuid), spdk_json_decode_string, true},
60 	{"num_blocks", offsetof(struct rpc_construct_malloc, num_blocks), spdk_json_decode_uint64},
61 	{"block_size", offsetof(struct rpc_construct_malloc, block_size), spdk_json_decode_uint32},
62 	{"optimal_io_boundary", offsetof(struct rpc_construct_malloc, optimal_io_boundary), spdk_json_decode_uint32, true},
63 };
64 
65 static void
66 rpc_bdev_malloc_create(struct spdk_jsonrpc_request *request,
67 		       const struct spdk_json_val *params)
68 {
69 	struct rpc_construct_malloc req = {NULL};
70 	struct spdk_json_write_ctx *w;
71 	struct spdk_uuid *uuid = NULL;
72 	struct spdk_uuid decoded_uuid;
73 	struct spdk_bdev *bdev;
74 	int rc = 0;
75 
76 	if (spdk_json_decode_object(params, rpc_construct_malloc_decoders,
77 				    SPDK_COUNTOF(rpc_construct_malloc_decoders),
78 				    &req)) {
79 		SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
80 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
81 						 "spdk_json_decode_object failed");
82 		goto cleanup;
83 	}
84 
85 	if (req.num_blocks == 0) {
86 		spdk_jsonrpc_send_error_response(request, -EINVAL,
87 						 "Disk num_blocks must be greater than 0");
88 		goto cleanup;
89 	}
90 
91 	if (req.uuid) {
92 		if (spdk_uuid_parse(&decoded_uuid, req.uuid)) {
93 			spdk_jsonrpc_send_error_response(request, -EINVAL,
94 							 "Failed to parse bdev UUID");
95 			goto cleanup;
96 		}
97 		uuid = &decoded_uuid;
98 	}
99 
100 	rc = create_malloc_disk(&bdev, req.name, uuid, req.num_blocks, req.block_size,
101 				req.optimal_io_boundary);
102 	if (rc) {
103 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
104 		goto cleanup;
105 	}
106 
107 	free_rpc_construct_malloc(&req);
108 
109 	w = spdk_jsonrpc_begin_result(request);
110 	spdk_json_write_string(w, spdk_bdev_get_name(bdev));
111 	spdk_jsonrpc_end_result(request, w);
112 	return;
113 
114 cleanup:
115 	free_rpc_construct_malloc(&req);
116 }
117 SPDK_RPC_REGISTER("bdev_malloc_create", rpc_bdev_malloc_create, SPDK_RPC_RUNTIME)
118 
119 struct rpc_delete_malloc {
120 	char *name;
121 };
122 
123 static void
124 free_rpc_delete_malloc(struct rpc_delete_malloc *r)
125 {
126 	free(r->name);
127 }
128 
129 static const struct spdk_json_object_decoder rpc_delete_malloc_decoders[] = {
130 	{"name", offsetof(struct rpc_delete_malloc, name), spdk_json_decode_string},
131 };
132 
133 static void
134 rpc_bdev_malloc_delete_cb(void *cb_arg, int bdeverrno)
135 {
136 	struct spdk_jsonrpc_request *request = cb_arg;
137 
138 	if (bdeverrno == 0) {
139 		spdk_jsonrpc_send_bool_response(request, true);
140 	} else {
141 		spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
142 	}
143 }
144 
145 static void
146 rpc_bdev_malloc_delete(struct spdk_jsonrpc_request *request,
147 		       const struct spdk_json_val *params)
148 {
149 	struct rpc_delete_malloc req = {NULL};
150 
151 	if (spdk_json_decode_object(params, rpc_delete_malloc_decoders,
152 				    SPDK_COUNTOF(rpc_delete_malloc_decoders),
153 				    &req)) {
154 		SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
155 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
156 						 "spdk_json_decode_object failed");
157 		goto cleanup;
158 	}
159 
160 	delete_malloc_disk(req.name, rpc_bdev_malloc_delete_cb, request);
161 
162 cleanup:
163 	free_rpc_delete_malloc(&req);
164 }
165 SPDK_RPC_REGISTER("bdev_malloc_delete", rpc_bdev_malloc_delete, SPDK_RPC_RUNTIME)
166