xref: /spdk/lib/nvmf/nvmf_rpc.c (revision aa7a13afc7fbc0663c32833e4a5b3b3606d86fca)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation. All rights reserved.
5  *   Copyright (c) 2018-2020 Mellanox Technologies LTD. All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/bdev.h"
35 #include "spdk/log.h"
36 #include "spdk/rpc.h"
37 #include "spdk/env.h"
38 #include "spdk/nvme.h"
39 #include "spdk/nvmf.h"
40 #include "spdk/string.h"
41 #include "spdk/util.h"
42 
43 #include "spdk_internal/event.h"
44 #include "spdk_internal/log.h"
45 
46 #include "nvmf_internal.h"
47 
48 static int
49 json_write_hex_str(struct spdk_json_write_ctx *w, const void *data, size_t size)
50 {
51 	static const char hex_char[16] = "0123456789ABCDEF";
52 	const uint8_t *buf = data;
53 	char *str, *out;
54 	int rc;
55 
56 	str = malloc(size * 2 + 1);
57 	if (str == NULL) {
58 		return -1;
59 	}
60 
61 	out = str;
62 	while (size--) {
63 		unsigned byte = *buf++;
64 
65 		out[0] = hex_char[(byte >> 4) & 0xF];
66 		out[1] = hex_char[byte & 0xF];
67 
68 		out += 2;
69 	}
70 	*out = '\0';
71 
72 	rc = spdk_json_write_string(w, str);
73 	free(str);
74 
75 	return rc;
76 }
77 
78 static int
79 hex_nybble_to_num(char c)
80 {
81 	if (c >= '0' && c <= '9') {
82 		return c - '0';
83 	}
84 
85 	if (c >= 'a' && c <= 'f') {
86 		return c - 'a' + 0xA;
87 	}
88 
89 	if (c >= 'A' && c <= 'F') {
90 		return c - 'A' + 0xA;
91 	}
92 
93 	return -1;
94 }
95 
96 static int
97 hex_byte_to_num(const char *str)
98 {
99 	int hi, lo;
100 
101 	hi = hex_nybble_to_num(str[0]);
102 	if (hi < 0) {
103 		return hi;
104 	}
105 
106 	lo = hex_nybble_to_num(str[1]);
107 	if (lo < 0) {
108 		return lo;
109 	}
110 
111 	return hi * 16 + lo;
112 }
113 
114 static int
115 decode_hex_string_be(const char *str, uint8_t *out, size_t size)
116 {
117 	size_t i;
118 
119 	/* Decode a string in "ABCDEF012345" format to its binary representation */
120 	for (i = 0; i < size; i++) {
121 		int num = hex_byte_to_num(str);
122 
123 		if (num < 0) {
124 			/* Invalid hex byte or end of string */
125 			return -1;
126 		}
127 
128 		out[i] = (uint8_t)num;
129 		str += 2;
130 	}
131 
132 	if (i != size || *str != '\0') {
133 		/* Length mismatch */
134 		return -1;
135 	}
136 
137 	return 0;
138 }
139 
140 static int
141 decode_ns_nguid(const struct spdk_json_val *val, void *out)
142 {
143 	char *str = NULL;
144 	int rc;
145 
146 	rc = spdk_json_decode_string(val, &str);
147 	if (rc == 0) {
148 		/* 16-byte NGUID */
149 		rc = decode_hex_string_be(str, out, 16);
150 	}
151 
152 	free(str);
153 	return rc;
154 }
155 
156 static int
157 decode_ns_eui64(const struct spdk_json_val *val, void *out)
158 {
159 	char *str = NULL;
160 	int rc;
161 
162 	rc = spdk_json_decode_string(val, &str);
163 	if (rc == 0) {
164 		/* 8-byte EUI-64 */
165 		rc = decode_hex_string_be(str, out, 8);
166 	}
167 
168 	free(str);
169 	return rc;
170 }
171 
172 static int
173 decode_ns_uuid(const struct spdk_json_val *val, void *out)
174 {
175 	char *str = NULL;
176 	int rc;
177 
178 	rc = spdk_json_decode_string(val, &str);
179 	if (rc == 0) {
180 		rc = spdk_uuid_parse(out, str);
181 	}
182 
183 	free(str);
184 	return rc;
185 }
186 
187 struct rpc_get_subsystem {
188 	char *tgt_name;
189 };
190 
191 static const struct spdk_json_object_decoder rpc_get_subsystem_decoders[] = {
192 	{"tgt_name", offsetof(struct rpc_get_subsystem, tgt_name), spdk_json_decode_string, true},
193 };
194 
195 static void
196 dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct spdk_nvmf_subsystem *subsystem)
197 {
198 	struct spdk_nvmf_host		*host;
199 	struct spdk_nvmf_listener	*listener;
200 
201 	spdk_json_write_object_begin(w);
202 
203 	spdk_json_write_named_string(w, "nqn", spdk_nvmf_subsystem_get_nqn(subsystem));
204 	spdk_json_write_name(w, "subtype");
205 	if (spdk_nvmf_subsystem_get_type(subsystem) == SPDK_NVMF_SUBTYPE_NVME) {
206 		spdk_json_write_string(w, "NVMe");
207 	} else {
208 		spdk_json_write_string(w, "Discovery");
209 	}
210 
211 	spdk_json_write_named_array_begin(w, "listen_addresses");
212 
213 	for (listener = spdk_nvmf_subsystem_get_first_listener(subsystem); listener != NULL;
214 	     listener = spdk_nvmf_subsystem_get_next_listener(subsystem, listener)) {
215 		const struct spdk_nvme_transport_id *trid;
216 		const char *adrfam;
217 
218 		trid = spdk_nvmf_listener_get_trid(listener);
219 
220 		spdk_json_write_object_begin(w);
221 		adrfam = spdk_nvme_transport_id_adrfam_str(trid->adrfam);
222 		if (adrfam == NULL) {
223 			adrfam = "unknown";
224 		}
225 		/* NOTE: "transport" is kept for compatibility; new code should use "trtype" */
226 		spdk_json_write_named_string(w, "transport", trid->trstring);
227 		spdk_json_write_named_string(w, "trtype", trid->trstring);
228 		spdk_json_write_named_string(w, "adrfam", adrfam);
229 		spdk_json_write_named_string(w, "traddr", trid->traddr);
230 		spdk_json_write_named_string(w, "trsvcid", trid->trsvcid);
231 		spdk_json_write_object_end(w);
232 	}
233 	spdk_json_write_array_end(w);
234 
235 	spdk_json_write_named_bool(w, "allow_any_host",
236 				   spdk_nvmf_subsystem_get_allow_any_host(subsystem));
237 
238 	spdk_json_write_named_array_begin(w, "hosts");
239 
240 	for (host = spdk_nvmf_subsystem_get_first_host(subsystem); host != NULL;
241 	     host = spdk_nvmf_subsystem_get_next_host(subsystem, host)) {
242 		spdk_json_write_object_begin(w);
243 		spdk_json_write_named_string(w, "nqn", spdk_nvmf_host_get_nqn(host));
244 		spdk_json_write_object_end(w);
245 	}
246 	spdk_json_write_array_end(w);
247 
248 	if (spdk_nvmf_subsystem_get_type(subsystem) == SPDK_NVMF_SUBTYPE_NVME) {
249 		struct spdk_nvmf_ns *ns;
250 		struct spdk_nvmf_ns_opts ns_opts;
251 		uint32_t max_namespaces;
252 
253 		spdk_json_write_named_string(w, "serial_number", spdk_nvmf_subsystem_get_sn(subsystem));
254 
255 		spdk_json_write_named_string(w, "model_number", spdk_nvmf_subsystem_get_mn(subsystem));
256 
257 		max_namespaces = spdk_nvmf_subsystem_get_max_namespaces(subsystem);
258 		if (max_namespaces != 0) {
259 			spdk_json_write_named_uint32(w, "max_namespaces", max_namespaces);
260 		}
261 
262 		spdk_json_write_named_array_begin(w, "namespaces");
263 		for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL;
264 		     ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) {
265 			spdk_nvmf_ns_get_opts(ns, &ns_opts, sizeof(ns_opts));
266 			spdk_json_write_object_begin(w);
267 			spdk_json_write_named_int32(w, "nsid", spdk_nvmf_ns_get_id(ns));
268 			spdk_json_write_named_string(w, "bdev_name",
269 						     spdk_bdev_get_name(spdk_nvmf_ns_get_bdev(ns)));
270 			/* NOTE: "name" is kept for compatibility only - new code should use bdev_name. */
271 			spdk_json_write_named_string(w, "name",
272 						     spdk_bdev_get_name(spdk_nvmf_ns_get_bdev(ns)));
273 
274 			if (!spdk_mem_all_zero(ns_opts.nguid, sizeof(ns_opts.nguid))) {
275 				spdk_json_write_name(w, "nguid");
276 				json_write_hex_str(w, ns_opts.nguid, sizeof(ns_opts.nguid));
277 			}
278 
279 			if (!spdk_mem_all_zero(ns_opts.eui64, sizeof(ns_opts.eui64))) {
280 				spdk_json_write_name(w, "eui64");
281 				json_write_hex_str(w, ns_opts.eui64, sizeof(ns_opts.eui64));
282 			}
283 
284 			if (!spdk_mem_all_zero(&ns_opts.uuid, sizeof(ns_opts.uuid))) {
285 				char uuid_str[SPDK_UUID_STRING_LEN];
286 
287 				spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &ns_opts.uuid);
288 				spdk_json_write_named_string(w, "uuid", uuid_str);
289 			}
290 
291 			spdk_json_write_object_end(w);
292 		}
293 		spdk_json_write_array_end(w);
294 	}
295 	spdk_json_write_object_end(w);
296 }
297 
298 static void
299 spdk_rpc_nvmf_get_subsystems(struct spdk_jsonrpc_request *request,
300 			     const struct spdk_json_val *params)
301 {
302 	struct rpc_get_subsystem req = { 0 };
303 	struct spdk_json_write_ctx *w;
304 	struct spdk_nvmf_subsystem *subsystem;
305 	struct spdk_nvmf_tgt *tgt;
306 
307 	if (params) {
308 		if (spdk_json_decode_object(params, rpc_get_subsystem_decoders,
309 					    SPDK_COUNTOF(rpc_get_subsystem_decoders),
310 					    &req)) {
311 			SPDK_ERRLOG("spdk_json_decode_object failed\n");
312 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
313 			return;
314 		}
315 	}
316 
317 	tgt = spdk_nvmf_get_tgt(req.tgt_name);
318 	if (!tgt) {
319 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
320 						 "Unable to find a target.");
321 		free(req.tgt_name);
322 		return;
323 	}
324 
325 	w = spdk_jsonrpc_begin_result(request);
326 	spdk_json_write_array_begin(w);
327 	subsystem = spdk_nvmf_subsystem_get_first(tgt);
328 	while (subsystem) {
329 		dump_nvmf_subsystem(w, subsystem);
330 		subsystem = spdk_nvmf_subsystem_get_next(subsystem);
331 	}
332 	spdk_json_write_array_end(w);
333 	spdk_jsonrpc_end_result(request, w);
334 	free(req.tgt_name);
335 }
336 SPDK_RPC_REGISTER("nvmf_get_subsystems", spdk_rpc_nvmf_get_subsystems, SPDK_RPC_RUNTIME)
337 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_get_subsystems, get_nvmf_subsystems)
338 
339 struct rpc_subsystem_create {
340 	char *nqn;
341 	char *serial_number;
342 	char *model_number;
343 	char *tgt_name;
344 	uint32_t max_namespaces;
345 	bool allow_any_host;
346 };
347 
348 static const struct spdk_json_object_decoder rpc_subsystem_create_decoders[] = {
349 	{"nqn", offsetof(struct rpc_subsystem_create, nqn), spdk_json_decode_string},
350 	{"serial_number", offsetof(struct rpc_subsystem_create, serial_number), spdk_json_decode_string, true},
351 	{"model_number", offsetof(struct rpc_subsystem_create, model_number), spdk_json_decode_string, true},
352 	{"tgt_name", offsetof(struct rpc_subsystem_create, tgt_name), spdk_json_decode_string, true},
353 	{"max_namespaces", offsetof(struct rpc_subsystem_create, max_namespaces), spdk_json_decode_uint32, true},
354 	{"allow_any_host", offsetof(struct rpc_subsystem_create, allow_any_host), spdk_json_decode_bool, true},
355 };
356 
357 static void
358 spdk_rpc_nvmf_subsystem_started(struct spdk_nvmf_subsystem *subsystem,
359 				void *cb_arg, int status)
360 {
361 	struct spdk_jsonrpc_request *request = cb_arg;
362 
363 	if (!status) {
364 		struct spdk_json_write_ctx *w = spdk_jsonrpc_begin_result(request);
365 		spdk_json_write_bool(w, true);
366 		spdk_jsonrpc_end_result(request, w);
367 	} else {
368 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
369 						     "Subsystem %s start failed",
370 						     subsystem->subnqn);
371 		spdk_nvmf_subsystem_destroy(subsystem);
372 	}
373 }
374 
375 static void
376 spdk_rpc_nvmf_create_subsystem(struct spdk_jsonrpc_request *request,
377 			       const struct spdk_json_val *params)
378 {
379 	struct rpc_subsystem_create *req;
380 	struct spdk_nvmf_subsystem *subsystem = NULL;
381 	struct spdk_nvmf_tgt *tgt;
382 	int rc = -1;
383 
384 	req = calloc(1, sizeof(*req));
385 	if (!req) {
386 		SPDK_ERRLOG("Memory allocation failed\n");
387 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
388 						 "Memory allocation failed");
389 		return;
390 	}
391 
392 	if (spdk_json_decode_object(params, rpc_subsystem_create_decoders,
393 				    SPDK_COUNTOF(rpc_subsystem_create_decoders),
394 				    req)) {
395 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
396 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
397 		goto cleanup;
398 	}
399 
400 	tgt = spdk_nvmf_get_tgt(req->tgt_name);
401 	if (!tgt) {
402 		SPDK_ERRLOG("Unable to find target %s\n", req->tgt_name);
403 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
404 						     "Unable to find target %s", req->tgt_name);
405 		goto cleanup;
406 	}
407 
408 	subsystem = spdk_nvmf_subsystem_create(tgt, req->nqn, SPDK_NVMF_SUBTYPE_NVME,
409 					       req->max_namespaces);
410 	if (!subsystem) {
411 		SPDK_ERRLOG("Unable to create subsystem %s\n", req->nqn);
412 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
413 						     "Unable to create subsystem %s", req->nqn);
414 		goto cleanup;
415 	}
416 
417 	if (req->serial_number) {
418 		if (spdk_nvmf_subsystem_set_sn(subsystem, req->serial_number)) {
419 			SPDK_ERRLOG("Subsystem %s: invalid serial number '%s'\n", req->nqn, req->serial_number);
420 			spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
421 							     "Invalid SN %s", req->serial_number);
422 			goto cleanup;
423 		}
424 	}
425 
426 	if (req->model_number) {
427 		if (spdk_nvmf_subsystem_set_mn(subsystem, req->model_number)) {
428 			SPDK_ERRLOG("Subsystem %s: invalid model number '%s'\n", req->nqn, req->model_number);
429 			spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
430 							     "Invalid MN %s", req->model_number);
431 			goto cleanup;
432 		}
433 	}
434 
435 	spdk_nvmf_subsystem_set_allow_any_host(subsystem, req->allow_any_host);
436 
437 	rc = spdk_nvmf_subsystem_start(subsystem,
438 				       spdk_rpc_nvmf_subsystem_started,
439 				       request);
440 
441 cleanup:
442 	free(req->nqn);
443 	free(req->tgt_name);
444 	free(req->serial_number);
445 	free(req->model_number);
446 	free(req);
447 
448 	if (rc && subsystem) {
449 		spdk_nvmf_subsystem_destroy(subsystem);
450 	}
451 }
452 SPDK_RPC_REGISTER("nvmf_create_subsystem", spdk_rpc_nvmf_create_subsystem, SPDK_RPC_RUNTIME)
453 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_create_subsystem, nvmf_subsystem_create)
454 
455 struct rpc_delete_subsystem {
456 	char *nqn;
457 	char *tgt_name;
458 };
459 
460 static void
461 free_rpc_delete_subsystem(struct rpc_delete_subsystem *r)
462 {
463 	free(r->nqn);
464 	free(r->tgt_name);
465 }
466 
467 static void
468 spdk_rpc_nvmf_subsystem_stopped(struct spdk_nvmf_subsystem *subsystem,
469 				void *cb_arg, int status)
470 {
471 	struct spdk_jsonrpc_request *request = cb_arg;
472 	struct spdk_json_write_ctx *w;
473 
474 	spdk_nvmf_subsystem_remove_all_listeners(subsystem, true);
475 	spdk_nvmf_subsystem_destroy(subsystem);
476 
477 	w = spdk_jsonrpc_begin_result(request);
478 	spdk_json_write_bool(w, true);
479 	spdk_jsonrpc_end_result(request, w);
480 }
481 
482 static const struct spdk_json_object_decoder rpc_delete_subsystem_decoders[] = {
483 	{"nqn", offsetof(struct rpc_delete_subsystem, nqn), spdk_json_decode_string},
484 	{"tgt_name", offsetof(struct rpc_delete_subsystem, tgt_name), spdk_json_decode_string, true},
485 };
486 
487 static void
488 spdk_rpc_nvmf_delete_subsystem(struct spdk_jsonrpc_request *request,
489 			       const struct spdk_json_val *params)
490 {
491 	struct rpc_delete_subsystem req = { 0 };
492 	struct spdk_nvmf_subsystem *subsystem;
493 	struct spdk_nvmf_tgt *tgt;
494 
495 	if (spdk_json_decode_object(params, rpc_delete_subsystem_decoders,
496 				    SPDK_COUNTOF(rpc_delete_subsystem_decoders),
497 				    &req)) {
498 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
499 		goto invalid;
500 	}
501 
502 	if (req.nqn == NULL) {
503 		SPDK_ERRLOG("missing name param\n");
504 		goto invalid;
505 	}
506 
507 	tgt = spdk_nvmf_get_tgt(req.tgt_name);
508 	if (!tgt) {
509 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
510 						 "Unable to find a target.");
511 		goto invalid_custom_response;
512 	}
513 
514 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, req.nqn);
515 	if (!subsystem) {
516 		goto invalid;
517 	}
518 
519 	free_rpc_delete_subsystem(&req);
520 
521 	spdk_nvmf_subsystem_stop(subsystem,
522 				 spdk_rpc_nvmf_subsystem_stopped,
523 				 request);
524 
525 	return;
526 
527 invalid:
528 	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
529 invalid_custom_response:
530 	free_rpc_delete_subsystem(&req);
531 }
532 SPDK_RPC_REGISTER("nvmf_delete_subsystem", spdk_rpc_nvmf_delete_subsystem, SPDK_RPC_RUNTIME)
533 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_delete_subsystem, delete_nvmf_subsystem)
534 
535 struct rpc_listen_address {
536 	char *transport;
537 	char *adrfam;
538 	char *traddr;
539 	char *trsvcid;
540 };
541 
542 #define RPC_MAX_LISTEN_ADDRESSES 255
543 #define RPC_MAX_NAMESPACES 255
544 
545 struct rpc_listen_addresses {
546 	size_t num_listen_address;
547 	struct rpc_listen_address addresses[RPC_MAX_LISTEN_ADDRESSES];
548 };
549 
550 static const struct spdk_json_object_decoder rpc_listen_address_decoders[] = {
551 	/* NOTE: "transport" is kept for compatibility; new code should use "trtype" */
552 	{"transport", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true},
553 	{"trtype", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true},
554 	{"adrfam", offsetof(struct rpc_listen_address, adrfam), spdk_json_decode_string, true},
555 	{"traddr", offsetof(struct rpc_listen_address, traddr), spdk_json_decode_string},
556 	{"trsvcid", offsetof(struct rpc_listen_address, trsvcid), spdk_json_decode_string},
557 };
558 
559 static int
560 decode_rpc_listen_address(const struct spdk_json_val *val, void *out)
561 {
562 	struct rpc_listen_address *req = (struct rpc_listen_address *)out;
563 	if (spdk_json_decode_object(val, rpc_listen_address_decoders,
564 				    SPDK_COUNTOF(rpc_listen_address_decoders),
565 				    req)) {
566 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
567 		return -1;
568 	}
569 	return 0;
570 }
571 
572 static void
573 free_rpc_listen_address(struct rpc_listen_address *r)
574 {
575 	free(r->transport);
576 	free(r->adrfam);
577 	free(r->traddr);
578 	free(r->trsvcid);
579 }
580 
581 enum nvmf_rpc_listen_op {
582 	NVMF_RPC_LISTEN_ADD,
583 	NVMF_RPC_LISTEN_REMOVE,
584 };
585 
586 struct nvmf_rpc_listener_ctx {
587 	char				*nqn;
588 	char				*tgt_name;
589 	struct spdk_nvmf_tgt		*tgt;
590 	struct spdk_nvmf_subsystem	*subsystem;
591 	struct rpc_listen_address	address;
592 
593 	struct spdk_jsonrpc_request	*request;
594 	struct spdk_nvme_transport_id	trid;
595 	enum nvmf_rpc_listen_op		op;
596 	bool				response_sent;
597 };
598 
599 static const struct spdk_json_object_decoder nvmf_rpc_listener_decoder[] = {
600 	{"nqn", offsetof(struct nvmf_rpc_listener_ctx, nqn), spdk_json_decode_string},
601 	{"listen_address", offsetof(struct nvmf_rpc_listener_ctx, address), decode_rpc_listen_address},
602 	{"tgt_name", offsetof(struct nvmf_rpc_listener_ctx, tgt_name), spdk_json_decode_string, true},
603 };
604 
605 static void
606 nvmf_rpc_listener_ctx_free(struct nvmf_rpc_listener_ctx *ctx)
607 {
608 	free(ctx->nqn);
609 	free(ctx->tgt_name);
610 	free_rpc_listen_address(&ctx->address);
611 	free(ctx);
612 }
613 
614 static void
615 nvmf_rpc_listen_resumed(struct spdk_nvmf_subsystem *subsystem,
616 			void *cb_arg, int status)
617 {
618 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
619 	struct spdk_jsonrpc_request *request;
620 	struct spdk_json_write_ctx *w;
621 
622 	request = ctx->request;
623 	if (ctx->response_sent) {
624 		/* If an error occurred, the response has already been sent. */
625 		nvmf_rpc_listener_ctx_free(ctx);
626 		return;
627 	}
628 
629 	nvmf_rpc_listener_ctx_free(ctx);
630 
631 	w = spdk_jsonrpc_begin_result(request);
632 	spdk_json_write_bool(w, true);
633 	spdk_jsonrpc_end_result(request, w);
634 }
635 
636 static void
637 nvmf_rpc_tgt_listen(void *cb_arg, int status)
638 {
639 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
640 
641 	if (status) {
642 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
643 						 "Invalid parameters");
644 		ctx->response_sent = true;
645 	} else {
646 		if (spdk_nvmf_subsystem_add_listener(ctx->subsystem, &ctx->trid)) {
647 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
648 							 "Invalid parameters");
649 			ctx->response_sent = true;
650 		}
651 	}
652 
653 	if (spdk_nvmf_subsystem_resume(ctx->subsystem, nvmf_rpc_listen_resumed, ctx)) {
654 		if (!ctx->response_sent) {
655 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
656 		}
657 		nvmf_rpc_listener_ctx_free(ctx);
658 		/* Can't really do anything to recover here - subsystem will remain paused. */
659 	}
660 }
661 
662 static void
663 nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem,
664 		       void *cb_arg, int status)
665 {
666 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
667 
668 	if (ctx->op == NVMF_RPC_LISTEN_ADD) {
669 		if (!spdk_nvmf_subsystem_find_listener(subsystem, &ctx->trid)) {
670 			spdk_nvmf_tgt_listen(ctx->tgt, &ctx->trid, nvmf_rpc_tgt_listen, ctx);
671 			return;
672 		}
673 	} else if (ctx->op == NVMF_RPC_LISTEN_REMOVE) {
674 		if (spdk_nvmf_subsystem_remove_listener(subsystem, &ctx->trid)) {
675 			SPDK_ERRLOG("Unable to remove listener.\n");
676 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
677 							 "Invalid parameters");
678 			ctx->response_sent = true;
679 		}
680 		spdk_nvmf_tgt_stop_listen(ctx->tgt, &ctx->trid);
681 	} else {
682 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
683 						 "Invalid parameters");
684 		ctx->response_sent = true;
685 	}
686 
687 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_listen_resumed, ctx)) {
688 		if (!ctx->response_sent) {
689 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
690 		}
691 		nvmf_rpc_listener_ctx_free(ctx);
692 		/* Can't really do anything to recover here - subsystem will remain paused. */
693 	}
694 }
695 
696 static int
697 rpc_listen_address_to_trid(const struct rpc_listen_address *address,
698 			   struct spdk_nvme_transport_id *trid)
699 {
700 	size_t len;
701 
702 	memset(trid, 0, sizeof(*trid));
703 
704 	if (spdk_nvme_transport_id_populate_trstring(trid, address->transport)) {
705 		SPDK_ERRLOG("Invalid transport string: %s\n", address->transport);
706 		return -EINVAL;
707 	}
708 
709 	if (spdk_nvme_transport_id_parse_trtype(&trid->trtype, address->transport)) {
710 		SPDK_ERRLOG("Invalid transport type: %s\n", address->transport);
711 		return -EINVAL;
712 	}
713 
714 	if (address->adrfam) {
715 		if (spdk_nvme_transport_id_parse_adrfam(&trid->adrfam, address->adrfam)) {
716 			SPDK_ERRLOG("Invalid adrfam: %s\n", address->adrfam);
717 			return -EINVAL;
718 		}
719 	} else {
720 		trid->adrfam = SPDK_NVMF_ADRFAM_IPV4;
721 	}
722 
723 	len = strlen(address->traddr);
724 	if (len > sizeof(trid->traddr) - 1) {
725 		SPDK_ERRLOG("Transport address longer than %zu characters: %s\n",
726 			    sizeof(trid->traddr) - 1, address->traddr);
727 		return -EINVAL;
728 	}
729 	memcpy(trid->traddr, address->traddr, len + 1);
730 
731 	len = strlen(address->trsvcid);
732 	if (len > sizeof(trid->trsvcid) - 1) {
733 		SPDK_ERRLOG("Transport service id longer than %zu characters: %s\n",
734 			    sizeof(trid->trsvcid) - 1, address->trsvcid);
735 		return -EINVAL;
736 	}
737 	memcpy(trid->trsvcid, address->trsvcid, len + 1);
738 
739 	return 0;
740 }
741 
742 static void
743 spdk_rpc_nvmf_subsystem_add_listener(struct spdk_jsonrpc_request *request,
744 				     const struct spdk_json_val *params)
745 {
746 	struct nvmf_rpc_listener_ctx *ctx;
747 	struct spdk_nvmf_subsystem *subsystem;
748 	struct spdk_nvmf_tgt *tgt;
749 
750 	ctx = calloc(1, sizeof(*ctx));
751 	if (!ctx) {
752 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
753 		return;
754 	}
755 
756 	ctx->request = request;
757 
758 	if (spdk_json_decode_object(params, nvmf_rpc_listener_decoder,
759 				    SPDK_COUNTOF(nvmf_rpc_listener_decoder),
760 				    ctx)) {
761 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
762 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
763 		nvmf_rpc_listener_ctx_free(ctx);
764 		return;
765 	}
766 
767 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
768 	if (!tgt) {
769 		SPDK_ERRLOG("Unable to find a target object.\n");
770 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
771 						 "Unable to find a target.");
772 		nvmf_rpc_listener_ctx_free(ctx);
773 		return;
774 	}
775 	ctx->tgt = tgt;
776 
777 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
778 	if (!subsystem) {
779 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
780 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
781 		nvmf_rpc_listener_ctx_free(ctx);
782 		return;
783 	}
784 
785 	ctx->subsystem = subsystem;
786 
787 	if (rpc_listen_address_to_trid(&ctx->address, &ctx->trid)) {
788 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
789 						 "Invalid parameters");
790 		nvmf_rpc_listener_ctx_free(ctx);
791 		return;
792 	}
793 
794 	ctx->op = NVMF_RPC_LISTEN_ADD;
795 
796 	if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_listen_paused, ctx)) {
797 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
798 		nvmf_rpc_listener_ctx_free(ctx);
799 		return;
800 	}
801 }
802 SPDK_RPC_REGISTER("nvmf_subsystem_add_listener", spdk_rpc_nvmf_subsystem_add_listener,
803 		  SPDK_RPC_RUNTIME);
804 
805 static void
806 spdk_rpc_nvmf_subsystem_remove_listener(struct spdk_jsonrpc_request *request,
807 					const struct spdk_json_val *params)
808 {
809 	struct nvmf_rpc_listener_ctx *ctx;
810 	struct spdk_nvmf_subsystem *subsystem;
811 	struct spdk_nvmf_tgt *tgt;
812 
813 	ctx = calloc(1, sizeof(*ctx));
814 	if (!ctx) {
815 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
816 		return;
817 	}
818 
819 	ctx->request = request;
820 
821 	if (spdk_json_decode_object(params, nvmf_rpc_listener_decoder,
822 				    SPDK_COUNTOF(nvmf_rpc_listener_decoder),
823 				    ctx)) {
824 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
825 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
826 		nvmf_rpc_listener_ctx_free(ctx);
827 		return;
828 	}
829 
830 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
831 	if (!tgt) {
832 		SPDK_ERRLOG("Unable to find a target object.\n");
833 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
834 						 "Unable to find a target.");
835 		nvmf_rpc_listener_ctx_free(ctx);
836 		return;
837 	}
838 	ctx->tgt = tgt;
839 
840 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
841 	if (!subsystem) {
842 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
843 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
844 		nvmf_rpc_listener_ctx_free(ctx);
845 		return;
846 	}
847 
848 	ctx->subsystem = subsystem;
849 
850 	if (rpc_listen_address_to_trid(&ctx->address, &ctx->trid)) {
851 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
852 						 "Invalid parameters");
853 		nvmf_rpc_listener_ctx_free(ctx);
854 		return;
855 	}
856 
857 	ctx->op = NVMF_RPC_LISTEN_REMOVE;
858 
859 	if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_listen_paused, ctx)) {
860 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
861 		nvmf_rpc_listener_ctx_free(ctx);
862 		return;
863 	}
864 
865 }
866 SPDK_RPC_REGISTER("nvmf_subsystem_remove_listener", spdk_rpc_nvmf_subsystem_remove_listener,
867 		  SPDK_RPC_RUNTIME);
868 
869 struct spdk_nvmf_ns_params {
870 	char *bdev_name;
871 	char *ptpl_file;
872 	uint32_t nsid;
873 	char nguid[16];
874 	char eui64[8];
875 	struct spdk_uuid uuid;
876 };
877 
878 struct rpc_namespaces {
879 	size_t num_ns;
880 	struct spdk_nvmf_ns_params ns_params[RPC_MAX_NAMESPACES];
881 };
882 
883 
884 static const struct spdk_json_object_decoder rpc_ns_params_decoders[] = {
885 	{"nsid", offsetof(struct spdk_nvmf_ns_params, nsid), spdk_json_decode_uint32, true},
886 	{"bdev_name", offsetof(struct spdk_nvmf_ns_params, bdev_name), spdk_json_decode_string},
887 	{"ptpl_file", offsetof(struct spdk_nvmf_ns_params, ptpl_file), spdk_json_decode_string, true},
888 	{"nguid", offsetof(struct spdk_nvmf_ns_params, nguid), decode_ns_nguid, true},
889 	{"eui64", offsetof(struct spdk_nvmf_ns_params, eui64), decode_ns_eui64, true},
890 	{"uuid", offsetof(struct spdk_nvmf_ns_params, uuid), decode_ns_uuid, true},
891 };
892 
893 static int
894 decode_rpc_ns_params(const struct spdk_json_val *val, void *out)
895 {
896 	struct spdk_nvmf_ns_params *ns_params = out;
897 
898 	return spdk_json_decode_object(val, rpc_ns_params_decoders,
899 				       SPDK_COUNTOF(rpc_ns_params_decoders),
900 				       ns_params);
901 }
902 
903 struct nvmf_rpc_ns_ctx {
904 	char *nqn;
905 	char *tgt_name;
906 	struct spdk_nvmf_ns_params ns_params;
907 
908 	struct spdk_jsonrpc_request *request;
909 	bool response_sent;
910 };
911 
912 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_ns_decoder[] = {
913 	{"nqn", offsetof(struct nvmf_rpc_ns_ctx, nqn), spdk_json_decode_string},
914 	{"namespace", offsetof(struct nvmf_rpc_ns_ctx, ns_params), decode_rpc_ns_params},
915 	{"tgt_name", offsetof(struct nvmf_rpc_ns_ctx, tgt_name), spdk_json_decode_string, true},
916 };
917 
918 static void
919 nvmf_rpc_ns_ctx_free(struct nvmf_rpc_ns_ctx *ctx)
920 {
921 	free(ctx->nqn);
922 	free(ctx->tgt_name);
923 	free(ctx->ns_params.bdev_name);
924 	free(ctx->ns_params.ptpl_file);
925 	free(ctx);
926 }
927 
928 static void
929 nvmf_rpc_ns_resumed(struct spdk_nvmf_subsystem *subsystem,
930 		    void *cb_arg, int status)
931 {
932 	struct nvmf_rpc_ns_ctx *ctx = cb_arg;
933 	struct spdk_jsonrpc_request *request = ctx->request;
934 	uint32_t nsid = ctx->ns_params.nsid;
935 	bool response_sent = ctx->response_sent;
936 	struct spdk_json_write_ctx *w;
937 
938 	nvmf_rpc_ns_ctx_free(ctx);
939 
940 	if (response_sent) {
941 		return;
942 	}
943 
944 	w = spdk_jsonrpc_begin_result(request);
945 	spdk_json_write_uint32(w, nsid);
946 	spdk_jsonrpc_end_result(request, w);
947 }
948 
949 static void
950 nvmf_rpc_ns_paused(struct spdk_nvmf_subsystem *subsystem,
951 		   void *cb_arg, int status)
952 {
953 	struct nvmf_rpc_ns_ctx *ctx = cb_arg;
954 	struct spdk_nvmf_ns_opts ns_opts;
955 	struct spdk_bdev *bdev;
956 
957 	bdev = spdk_bdev_get_by_name(ctx->ns_params.bdev_name);
958 	if (!bdev) {
959 		SPDK_ERRLOG("No bdev with name %s\n", ctx->ns_params.bdev_name);
960 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
961 						 "Invalid parameters");
962 		ctx->response_sent = true;
963 		goto resume;
964 	}
965 
966 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
967 	ns_opts.nsid = ctx->ns_params.nsid;
968 
969 	SPDK_STATIC_ASSERT(sizeof(ns_opts.nguid) == sizeof(ctx->ns_params.nguid), "size mismatch");
970 	memcpy(ns_opts.nguid, ctx->ns_params.nguid, sizeof(ns_opts.nguid));
971 
972 	SPDK_STATIC_ASSERT(sizeof(ns_opts.eui64) == sizeof(ctx->ns_params.eui64), "size mismatch");
973 	memcpy(ns_opts.eui64, ctx->ns_params.eui64, sizeof(ns_opts.eui64));
974 
975 	if (!spdk_mem_all_zero(&ctx->ns_params.uuid, sizeof(ctx->ns_params.uuid))) {
976 		ns_opts.uuid = ctx->ns_params.uuid;
977 	}
978 
979 	ctx->ns_params.nsid = spdk_nvmf_subsystem_add_ns(subsystem, bdev, &ns_opts, sizeof(ns_opts),
980 			      ctx->ns_params.ptpl_file);
981 	if (ctx->ns_params.nsid == 0) {
982 		SPDK_ERRLOG("Unable to add namespace\n");
983 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
984 						 "Invalid parameters");
985 		ctx->response_sent = true;
986 		goto resume;
987 	}
988 
989 resume:
990 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_ns_resumed, ctx)) {
991 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
992 		nvmf_rpc_ns_ctx_free(ctx);
993 		return;
994 	}
995 }
996 
997 static void
998 spdk_rpc_nvmf_subsystem_add_ns(struct spdk_jsonrpc_request *request,
999 			       const struct spdk_json_val *params)
1000 {
1001 	struct nvmf_rpc_ns_ctx *ctx;
1002 	struct spdk_nvmf_subsystem *subsystem;
1003 	struct spdk_nvmf_tgt *tgt;
1004 
1005 	ctx = calloc(1, sizeof(*ctx));
1006 	if (!ctx) {
1007 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1008 		return;
1009 	}
1010 
1011 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_ns_decoder,
1012 				    SPDK_COUNTOF(nvmf_rpc_subsystem_ns_decoder),
1013 				    ctx)) {
1014 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1015 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1016 		nvmf_rpc_ns_ctx_free(ctx);
1017 		return;
1018 	}
1019 
1020 	ctx->request = request;
1021 	ctx->response_sent = false;
1022 
1023 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1024 	if (!tgt) {
1025 		SPDK_ERRLOG("Unable to find a target object.\n");
1026 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1027 						 "Unable to find a target.");
1028 		nvmf_rpc_ns_ctx_free(ctx);
1029 		return;
1030 	}
1031 
1032 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1033 	if (!subsystem) {
1034 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1035 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1036 		nvmf_rpc_ns_ctx_free(ctx);
1037 		return;
1038 	}
1039 
1040 	if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_ns_paused, ctx)) {
1041 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1042 		nvmf_rpc_ns_ctx_free(ctx);
1043 		return;
1044 	}
1045 }
1046 SPDK_RPC_REGISTER("nvmf_subsystem_add_ns", spdk_rpc_nvmf_subsystem_add_ns, SPDK_RPC_RUNTIME)
1047 
1048 struct nvmf_rpc_remove_ns_ctx {
1049 	char *nqn;
1050 	char *tgt_name;
1051 	uint32_t nsid;
1052 
1053 	struct spdk_jsonrpc_request *request;
1054 	bool response_sent;
1055 };
1056 
1057 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_remove_ns_decoder[] = {
1058 	{"nqn", offsetof(struct nvmf_rpc_remove_ns_ctx, nqn), spdk_json_decode_string},
1059 	{"nsid", offsetof(struct nvmf_rpc_remove_ns_ctx, nsid), spdk_json_decode_uint32},
1060 	{"tgt_name", offsetof(struct nvmf_rpc_remove_ns_ctx, tgt_name), spdk_json_decode_string, true},
1061 };
1062 
1063 static void
1064 nvmf_rpc_remove_ns_ctx_free(struct nvmf_rpc_remove_ns_ctx *ctx)
1065 {
1066 	free(ctx->nqn);
1067 	free(ctx->tgt_name);
1068 	free(ctx);
1069 }
1070 
1071 static void
1072 nvmf_rpc_remove_ns_resumed(struct spdk_nvmf_subsystem *subsystem,
1073 			   void *cb_arg, int status)
1074 {
1075 	struct nvmf_rpc_remove_ns_ctx *ctx = cb_arg;
1076 	struct spdk_jsonrpc_request *request = ctx->request;
1077 	bool response_sent = ctx->response_sent;
1078 	struct spdk_json_write_ctx *w;
1079 
1080 	nvmf_rpc_remove_ns_ctx_free(ctx);
1081 
1082 	if (response_sent) {
1083 		return;
1084 	}
1085 
1086 	w = spdk_jsonrpc_begin_result(request);
1087 	spdk_json_write_bool(w, true);
1088 	spdk_jsonrpc_end_result(request, w);
1089 }
1090 
1091 static void
1092 nvmf_rpc_remove_ns_paused(struct spdk_nvmf_subsystem *subsystem,
1093 			  void *cb_arg, int status)
1094 {
1095 	struct nvmf_rpc_remove_ns_ctx *ctx = cb_arg;
1096 	int ret;
1097 
1098 	ret = spdk_nvmf_subsystem_remove_ns(subsystem, ctx->nsid);
1099 	if (ret < 0) {
1100 		SPDK_ERRLOG("Unable to remove namespace ID %u\n", ctx->nsid);
1101 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1102 						 "Invalid parameters");
1103 		ctx->response_sent = true;
1104 	}
1105 
1106 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_remove_ns_resumed, ctx)) {
1107 		if (!ctx->response_sent) {
1108 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1109 		}
1110 		nvmf_rpc_remove_ns_ctx_free(ctx);
1111 		return;
1112 	}
1113 }
1114 
1115 static void
1116 spdk_rpc_nvmf_subsystem_remove_ns(struct spdk_jsonrpc_request *request,
1117 				  const struct spdk_json_val *params)
1118 {
1119 	struct nvmf_rpc_remove_ns_ctx *ctx;
1120 	struct spdk_nvmf_subsystem *subsystem;
1121 	struct spdk_nvmf_tgt *tgt;
1122 
1123 	ctx = calloc(1, sizeof(*ctx));
1124 	if (!ctx) {
1125 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1126 		return;
1127 	}
1128 
1129 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_remove_ns_decoder,
1130 				    SPDK_COUNTOF(nvmf_rpc_subsystem_remove_ns_decoder),
1131 				    ctx)) {
1132 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1133 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1134 		nvmf_rpc_remove_ns_ctx_free(ctx);
1135 		return;
1136 	}
1137 
1138 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1139 	if (!tgt) {
1140 		SPDK_ERRLOG("Unable to find a target object.\n");
1141 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1142 						 "Unable to find a target.");
1143 		nvmf_rpc_remove_ns_ctx_free(ctx);
1144 		return;
1145 	}
1146 
1147 	ctx->request = request;
1148 	ctx->response_sent = false;
1149 
1150 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1151 	if (!subsystem) {
1152 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1153 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1154 		nvmf_rpc_remove_ns_ctx_free(ctx);
1155 		return;
1156 	}
1157 
1158 	if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_remove_ns_paused, ctx)) {
1159 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1160 		nvmf_rpc_remove_ns_ctx_free(ctx);
1161 		return;
1162 	}
1163 }
1164 SPDK_RPC_REGISTER("nvmf_subsystem_remove_ns", spdk_rpc_nvmf_subsystem_remove_ns, SPDK_RPC_RUNTIME)
1165 
1166 enum nvmf_rpc_host_op {
1167 	NVMF_RPC_HOST_ADD,
1168 	NVMF_RPC_HOST_REMOVE,
1169 	NVMF_RPC_HOST_ALLOW_ANY,
1170 };
1171 
1172 struct nvmf_rpc_host_ctx {
1173 	struct spdk_jsonrpc_request *request;
1174 
1175 	char *nqn;
1176 	char *host;
1177 	char *tgt_name;
1178 
1179 	enum nvmf_rpc_host_op op;
1180 
1181 	bool allow_any_host;
1182 
1183 	bool response_sent;
1184 };
1185 
1186 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_host_decoder[] = {
1187 	{"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string},
1188 	{"host", offsetof(struct nvmf_rpc_host_ctx, host), spdk_json_decode_string},
1189 	{"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true},
1190 };
1191 
1192 static void
1193 nvmf_rpc_host_ctx_free(struct nvmf_rpc_host_ctx *ctx)
1194 {
1195 	free(ctx->nqn);
1196 	free(ctx->host);
1197 	free(ctx->tgt_name);
1198 	free(ctx);
1199 }
1200 
1201 static void
1202 nvmf_rpc_host_resumed(struct spdk_nvmf_subsystem *subsystem,
1203 		      void *cb_arg, int status)
1204 {
1205 	struct nvmf_rpc_host_ctx *ctx = cb_arg;
1206 	struct spdk_jsonrpc_request *request;
1207 	struct spdk_json_write_ctx *w;
1208 	bool response_sent = ctx->response_sent;
1209 
1210 	request = ctx->request;
1211 	nvmf_rpc_host_ctx_free(ctx);
1212 
1213 	if (response_sent) {
1214 		return;
1215 	}
1216 
1217 	w = spdk_jsonrpc_begin_result(request);
1218 	spdk_json_write_bool(w, true);
1219 	spdk_jsonrpc_end_result(request, w);
1220 }
1221 
1222 static void
1223 nvmf_rpc_host_paused(struct spdk_nvmf_subsystem *subsystem,
1224 		     void *cb_arg, int status)
1225 {
1226 	struct nvmf_rpc_host_ctx *ctx = cb_arg;
1227 	int rc = -1;
1228 
1229 	switch (ctx->op) {
1230 	case NVMF_RPC_HOST_ADD:
1231 		rc = spdk_nvmf_subsystem_add_host(subsystem, ctx->host);
1232 		break;
1233 	case NVMF_RPC_HOST_REMOVE:
1234 		rc = spdk_nvmf_subsystem_remove_host(subsystem, ctx->host);
1235 		break;
1236 	case NVMF_RPC_HOST_ALLOW_ANY:
1237 		rc = spdk_nvmf_subsystem_set_allow_any_host(subsystem, ctx->allow_any_host);
1238 		break;
1239 	}
1240 
1241 	if (rc != 0) {
1242 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1243 		ctx->response_sent = true;
1244 	}
1245 
1246 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_host_resumed, ctx)) {
1247 		if (!ctx->response_sent) {
1248 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1249 		}
1250 		nvmf_rpc_host_ctx_free(ctx);
1251 		return;
1252 	}
1253 }
1254 
1255 static void
1256 spdk_rpc_nvmf_subsystem_add_host(struct spdk_jsonrpc_request *request,
1257 				 const struct spdk_json_val *params)
1258 {
1259 	struct nvmf_rpc_host_ctx *ctx;
1260 	struct spdk_nvmf_subsystem *subsystem;
1261 	struct spdk_nvmf_tgt *tgt;
1262 
1263 	ctx = calloc(1, sizeof(*ctx));
1264 	if (!ctx) {
1265 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1266 		return;
1267 	}
1268 
1269 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_host_decoder,
1270 				    SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder),
1271 				    ctx)) {
1272 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1273 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1274 		nvmf_rpc_host_ctx_free(ctx);
1275 		return;
1276 	}
1277 
1278 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1279 	if (!tgt) {
1280 		SPDK_ERRLOG("Unable to find a target object.\n");
1281 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1282 						 "Unable to find a target.");
1283 		nvmf_rpc_host_ctx_free(ctx);
1284 		return;
1285 	}
1286 
1287 	ctx->request = request;
1288 	ctx->op = NVMF_RPC_HOST_ADD;
1289 	ctx->response_sent = false;
1290 
1291 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1292 	if (!subsystem) {
1293 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1294 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1295 		nvmf_rpc_host_ctx_free(ctx);
1296 		return;
1297 	}
1298 
1299 	if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_host_paused, ctx)) {
1300 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1301 		nvmf_rpc_host_ctx_free(ctx);
1302 		return;
1303 	}
1304 }
1305 SPDK_RPC_REGISTER("nvmf_subsystem_add_host", spdk_rpc_nvmf_subsystem_add_host, SPDK_RPC_RUNTIME)
1306 
1307 static void
1308 spdk_rpc_nvmf_subsystem_remove_host(struct spdk_jsonrpc_request *request,
1309 				    const struct spdk_json_val *params)
1310 {
1311 	struct nvmf_rpc_host_ctx *ctx;
1312 	struct spdk_nvmf_subsystem *subsystem;
1313 	struct spdk_nvmf_tgt *tgt;
1314 
1315 	ctx = calloc(1, sizeof(*ctx));
1316 	if (!ctx) {
1317 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1318 		return;
1319 	}
1320 
1321 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_host_decoder,
1322 				    SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder),
1323 				    ctx)) {
1324 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1325 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1326 		nvmf_rpc_host_ctx_free(ctx);
1327 		return;
1328 	}
1329 
1330 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1331 	if (!tgt) {
1332 		SPDK_ERRLOG("Unable to find a target object.\n");
1333 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1334 						 "Unable to find a target.");
1335 		nvmf_rpc_host_ctx_free(ctx);
1336 		return;
1337 	}
1338 
1339 	ctx->request = request;
1340 	ctx->op = NVMF_RPC_HOST_REMOVE;
1341 	ctx->response_sent = false;
1342 
1343 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1344 	if (!subsystem) {
1345 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1346 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1347 		nvmf_rpc_host_ctx_free(ctx);
1348 		return;
1349 	}
1350 
1351 	if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_host_paused, ctx)) {
1352 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1353 		nvmf_rpc_host_ctx_free(ctx);
1354 		return;
1355 	}
1356 }
1357 SPDK_RPC_REGISTER("nvmf_subsystem_remove_host", spdk_rpc_nvmf_subsystem_remove_host,
1358 		  SPDK_RPC_RUNTIME)
1359 
1360 
1361 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_any_host_decoder[] = {
1362 	{"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string},
1363 	{"allow_any_host", offsetof(struct nvmf_rpc_host_ctx, allow_any_host), spdk_json_decode_bool},
1364 	{"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true},
1365 };
1366 
1367 static void
1368 spdk_rpc_nvmf_subsystem_allow_any_host(struct spdk_jsonrpc_request *request,
1369 				       const struct spdk_json_val *params)
1370 {
1371 	struct nvmf_rpc_host_ctx *ctx;
1372 	struct spdk_nvmf_subsystem *subsystem;
1373 	struct spdk_nvmf_tgt *tgt;
1374 
1375 	ctx = calloc(1, sizeof(*ctx));
1376 	if (!ctx) {
1377 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1378 		return;
1379 	}
1380 
1381 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_any_host_decoder,
1382 				    SPDK_COUNTOF(nvmf_rpc_subsystem_any_host_decoder),
1383 				    ctx)) {
1384 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1385 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1386 		nvmf_rpc_host_ctx_free(ctx);
1387 		return;
1388 	}
1389 
1390 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1391 	if (!tgt) {
1392 		SPDK_ERRLOG("Unable to find a target object.\n");
1393 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1394 						 "Unable to find a target.");
1395 		nvmf_rpc_host_ctx_free(ctx);
1396 		return;
1397 	}
1398 
1399 	ctx->request = request;
1400 	ctx->op = NVMF_RPC_HOST_ALLOW_ANY;
1401 	ctx->response_sent = false;
1402 
1403 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1404 	if (!subsystem) {
1405 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1406 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1407 		nvmf_rpc_host_ctx_free(ctx);
1408 		return;
1409 	}
1410 
1411 	if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_host_paused, ctx)) {
1412 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1413 		nvmf_rpc_host_ctx_free(ctx);
1414 		return;
1415 	}
1416 }
1417 SPDK_RPC_REGISTER("nvmf_subsystem_allow_any_host", spdk_rpc_nvmf_subsystem_allow_any_host,
1418 		  SPDK_RPC_RUNTIME)
1419 
1420 struct nvmf_rpc_target_ctx {
1421 	char *name;
1422 	uint32_t max_subsystems;
1423 };
1424 
1425 static const struct spdk_json_object_decoder nvmf_rpc_create_target_decoder[] = {
1426 	{"name", offsetof(struct nvmf_rpc_target_ctx, name), spdk_json_decode_string},
1427 	{"max_subsystems", offsetof(struct nvmf_rpc_target_ctx, max_subsystems), spdk_json_decode_uint32, true},
1428 };
1429 
1430 static void
1431 spdk_rpc_nvmf_create_target(struct spdk_jsonrpc_request *request,
1432 			    const struct spdk_json_val *params)
1433 {
1434 	struct spdk_nvmf_target_opts	opts;
1435 	struct nvmf_rpc_target_ctx	ctx = {0};
1436 	struct spdk_nvmf_tgt		*tgt;
1437 	struct spdk_json_write_ctx	*w;
1438 
1439 	/* Decode parameters the first time to get the transport type */
1440 	if (spdk_json_decode_object(params, nvmf_rpc_create_target_decoder,
1441 				    SPDK_COUNTOF(nvmf_rpc_create_target_decoder),
1442 				    &ctx)) {
1443 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1444 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1445 		free(ctx.name);
1446 		return;
1447 	}
1448 
1449 	snprintf(opts.name, NVMF_TGT_NAME_MAX_LENGTH, "%s", ctx.name);
1450 	opts.max_subsystems = ctx.max_subsystems;
1451 
1452 	if (spdk_nvmf_get_tgt(opts.name) != NULL) {
1453 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1454 						 "Target already exists.");
1455 		free(ctx.name);
1456 		return;
1457 	}
1458 
1459 	tgt = spdk_nvmf_tgt_create(&opts);
1460 
1461 	if (tgt == NULL) {
1462 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1463 						 "Unable to create the requested target.");
1464 		free(ctx.name);
1465 		return;
1466 	}
1467 
1468 	w = spdk_jsonrpc_begin_result(request);
1469 	spdk_json_write_string(w, spdk_nvmf_tgt_get_name(tgt));
1470 	spdk_jsonrpc_end_result(request, w);
1471 	free(ctx.name);
1472 }
1473 SPDK_RPC_REGISTER("nvmf_create_target", spdk_rpc_nvmf_create_target, SPDK_RPC_RUNTIME);
1474 
1475 static const struct spdk_json_object_decoder nvmf_rpc_destroy_target_decoder[] = {
1476 	{"name", offsetof(struct nvmf_rpc_target_ctx, name), spdk_json_decode_string},
1477 };
1478 
1479 static void
1480 nvmf_rpc_destroy_target_done(void *ctx, int status)
1481 {
1482 	struct spdk_jsonrpc_request	*request = ctx;
1483 	struct spdk_json_write_ctx	*w;
1484 
1485 	w = spdk_jsonrpc_begin_result(request);
1486 	spdk_json_write_bool(w, true);
1487 	spdk_jsonrpc_end_result(request, w);
1488 }
1489 
1490 static void
1491 spdk_rpc_nvmf_delete_target(struct spdk_jsonrpc_request *request,
1492 			    const struct spdk_json_val *params)
1493 {
1494 	struct nvmf_rpc_target_ctx	ctx = {0};
1495 	struct spdk_nvmf_tgt		*tgt;
1496 
1497 	/* Decode parameters the first time to get the transport type */
1498 	if (spdk_json_decode_object(params, nvmf_rpc_destroy_target_decoder,
1499 				    SPDK_COUNTOF(nvmf_rpc_destroy_target_decoder),
1500 				    &ctx)) {
1501 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1502 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1503 		free(ctx.name);
1504 		return;
1505 	}
1506 
1507 	tgt = spdk_nvmf_get_tgt(ctx.name);
1508 
1509 	if (tgt == NULL) {
1510 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1511 						 "The specified target doesn't exist, cannot delete it.");
1512 		free(ctx.name);
1513 		return;
1514 	}
1515 
1516 	spdk_nvmf_tgt_destroy(tgt, nvmf_rpc_destroy_target_done, request);
1517 	free(ctx.name);
1518 }
1519 SPDK_RPC_REGISTER("nvmf_delete_target", spdk_rpc_nvmf_delete_target, SPDK_RPC_RUNTIME);
1520 
1521 static void
1522 spdk_rpc_nvmf_get_targets(struct spdk_jsonrpc_request *request,
1523 			  const struct spdk_json_val *params)
1524 {
1525 	struct spdk_json_write_ctx	*w;
1526 	struct spdk_nvmf_tgt		*tgt;
1527 	const char			*name;
1528 
1529 	if (params != NULL) {
1530 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1531 						 "nvmf_get_targets has no parameters.");
1532 		return;
1533 	}
1534 
1535 	w = spdk_jsonrpc_begin_result(request);
1536 	spdk_json_write_array_begin(w);
1537 
1538 	tgt = spdk_nvmf_get_first_tgt();
1539 
1540 	while (tgt != NULL) {
1541 		name = spdk_nvmf_tgt_get_name(tgt);
1542 		spdk_json_write_string(w, name);
1543 		tgt = spdk_nvmf_get_next_tgt(tgt);
1544 	}
1545 
1546 	spdk_json_write_array_end(w);
1547 	spdk_jsonrpc_end_result(request, w);
1548 }
1549 SPDK_RPC_REGISTER("nvmf_get_targets", spdk_rpc_nvmf_get_targets, SPDK_RPC_RUNTIME);
1550 
1551 struct nvmf_rpc_create_transport_ctx {
1552 	char				*trtype;
1553 	char				*tgt_name;
1554 	struct spdk_nvmf_transport_opts	opts;
1555 	struct spdk_jsonrpc_request	*request;
1556 };
1557 
1558 static const struct spdk_json_object_decoder nvmf_rpc_create_transport_decoder[] = {
1559 	{	"trtype", offsetof(struct nvmf_rpc_create_transport_ctx, trtype), spdk_json_decode_string},
1560 	{
1561 		"max_queue_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_queue_depth),
1562 		spdk_json_decode_uint16, true
1563 	},
1564 	{
1565 		"max_qpairs_per_ctrlr", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_qpairs_per_ctrlr),
1566 		spdk_json_decode_uint16, true
1567 	},
1568 	{
1569 		"in_capsule_data_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.in_capsule_data_size),
1570 		spdk_json_decode_uint32, true
1571 	},
1572 	{
1573 		"max_io_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_io_size),
1574 		spdk_json_decode_uint32, true
1575 	},
1576 	{
1577 		"io_unit_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.io_unit_size),
1578 		spdk_json_decode_uint32, true
1579 	},
1580 	{
1581 		"max_aq_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_aq_depth),
1582 		spdk_json_decode_uint32, true
1583 	},
1584 	{
1585 		"num_shared_buffers", offsetof(struct nvmf_rpc_create_transport_ctx, opts.num_shared_buffers),
1586 		spdk_json_decode_uint32, true
1587 	},
1588 	{
1589 		"buf_cache_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.buf_cache_size),
1590 		spdk_json_decode_uint32, true
1591 	},
1592 	{
1593 		"max_srq_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_srq_depth),
1594 		spdk_json_decode_uint32, true
1595 	},
1596 	{
1597 		"no_srq", offsetof(struct nvmf_rpc_create_transport_ctx, opts.no_srq),
1598 		spdk_json_decode_bool, true
1599 	},
1600 	{
1601 		"c2h_success", offsetof(struct nvmf_rpc_create_transport_ctx, opts.c2h_success),
1602 		spdk_json_decode_bool, true
1603 	},
1604 	{
1605 		"dif_insert_or_strip", offsetof(struct nvmf_rpc_create_transport_ctx, opts.dif_insert_or_strip),
1606 		spdk_json_decode_bool, true
1607 	},
1608 	{
1609 		"sock_priority", offsetof(struct nvmf_rpc_create_transport_ctx, opts.sock_priority),
1610 		spdk_json_decode_uint32, true
1611 	},
1612 	{
1613 		"tgt_name", offsetof(struct nvmf_rpc_create_transport_ctx, tgt_name),
1614 		spdk_json_decode_string, true
1615 	},
1616 };
1617 
1618 static void
1619 nvmf_rpc_create_transport_ctx_free(struct nvmf_rpc_create_transport_ctx *ctx)
1620 {
1621 	free(ctx->trtype);
1622 	free(ctx->tgt_name);
1623 	free(ctx);
1624 }
1625 
1626 static void
1627 nvmf_rpc_tgt_add_transport_done(void *cb_arg, int status)
1628 {
1629 	struct nvmf_rpc_create_transport_ctx *ctx = cb_arg;
1630 	struct spdk_jsonrpc_request *request;
1631 	struct spdk_json_write_ctx *w;
1632 
1633 	request = ctx->request;
1634 	nvmf_rpc_create_transport_ctx_free(ctx);
1635 
1636 	if (status) {
1637 		SPDK_ERRLOG("Failed to add transport to tgt.(%d)\n", status);
1638 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1639 						     "Failed to add transport to tgt.(%d)\n",
1640 						     status);
1641 		return;
1642 	}
1643 
1644 	w = spdk_jsonrpc_begin_result(request);
1645 	spdk_json_write_bool(w, true);
1646 	spdk_jsonrpc_end_result(request, w);
1647 }
1648 
1649 static void
1650 spdk_rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request,
1651 			       const struct spdk_json_val *params)
1652 {
1653 	struct nvmf_rpc_create_transport_ctx *ctx;
1654 	enum spdk_nvme_transport_type trtype;
1655 	struct spdk_nvmf_transport *transport;
1656 	struct spdk_nvmf_tgt *tgt;
1657 
1658 	ctx = calloc(1, sizeof(*ctx));
1659 	if (!ctx) {
1660 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1661 		return;
1662 	}
1663 
1664 	/* Decode parameters the first time to get the transport type */
1665 	if (spdk_json_decode_object(params, nvmf_rpc_create_transport_decoder,
1666 				    SPDK_COUNTOF(nvmf_rpc_create_transport_decoder),
1667 				    ctx)) {
1668 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1669 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1670 		nvmf_rpc_create_transport_ctx_free(ctx);
1671 		return;
1672 	}
1673 
1674 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1675 	if (!tgt) {
1676 		SPDK_ERRLOG("Unable to find a target object.\n");
1677 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1678 						 "Unable to find a target.");
1679 		nvmf_rpc_create_transport_ctx_free(ctx);
1680 		return;
1681 	}
1682 
1683 	if (spdk_nvme_transport_id_parse_trtype(&trtype, ctx->trtype)) {
1684 		SPDK_ERRLOG("Invalid transport type '%s'\n", ctx->trtype);
1685 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1686 						     "Invalid transport type '%s'\n", ctx->trtype);
1687 		nvmf_rpc_create_transport_ctx_free(ctx);
1688 		return;
1689 	}
1690 
1691 	/* Initialize all the transport options (based on transport type) and decode the
1692 	 * parameters again to update any options passed in rpc create transport call.
1693 	 */
1694 	if (!spdk_nvmf_transport_opts_init(ctx->trtype, &ctx->opts)) {
1695 		/* This can happen if user specifies PCIE transport type which isn't valid for
1696 		 * NVMe-oF.
1697 		 */
1698 		SPDK_ERRLOG("Invalid transport type '%s'\n", ctx->trtype);
1699 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1700 						     "Invalid transport type '%s'\n", ctx->trtype);
1701 		nvmf_rpc_create_transport_ctx_free(ctx);
1702 		return;
1703 	}
1704 
1705 	if (spdk_json_decode_object(params, nvmf_rpc_create_transport_decoder,
1706 				    SPDK_COUNTOF(nvmf_rpc_create_transport_decoder),
1707 				    ctx)) {
1708 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1709 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1710 		nvmf_rpc_create_transport_ctx_free(ctx);
1711 		return;
1712 	}
1713 
1714 	if (spdk_nvmf_tgt_get_transport(tgt, ctx->trtype)) {
1715 		SPDK_ERRLOG("Transport type '%s' already exists\n", ctx->trtype);
1716 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1717 						     "Transport type '%s' already exists\n", ctx->trtype);
1718 		nvmf_rpc_create_transport_ctx_free(ctx);
1719 		return;
1720 	}
1721 
1722 	transport = spdk_nvmf_transport_create(ctx->trtype, &ctx->opts);
1723 
1724 	if (!transport) {
1725 		SPDK_ERRLOG("Transport type '%s' create failed\n", ctx->trtype);
1726 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1727 						     "Transport type '%s' create failed\n", ctx->trtype);
1728 		nvmf_rpc_create_transport_ctx_free(ctx);
1729 		return;
1730 	}
1731 
1732 	/* add transport to target */
1733 	ctx->request = request;
1734 	spdk_nvmf_tgt_add_transport(tgt, transport, nvmf_rpc_tgt_add_transport_done, ctx);
1735 }
1736 SPDK_RPC_REGISTER("nvmf_create_transport", spdk_rpc_nvmf_create_transport, SPDK_RPC_RUNTIME)
1737 
1738 static void
1739 dump_nvmf_transport(struct spdk_json_write_ctx *w, struct spdk_nvmf_transport *transport)
1740 {
1741 	const struct spdk_nvmf_transport_opts *opts = spdk_nvmf_get_transport_opts(transport);
1742 	spdk_nvme_transport_type_t type = spdk_nvmf_get_transport_type(transport);
1743 
1744 	spdk_json_write_object_begin(w);
1745 
1746 	spdk_json_write_named_string(w, "trtype", spdk_nvmf_get_transport_name(transport));
1747 	spdk_json_write_named_uint32(w, "max_queue_depth", opts->max_queue_depth);
1748 	spdk_json_write_named_uint32(w, "max_qpairs_per_ctrlr", opts->max_qpairs_per_ctrlr);
1749 	spdk_json_write_named_uint32(w, "in_capsule_data_size", opts->in_capsule_data_size);
1750 	spdk_json_write_named_uint32(w, "max_io_size", opts->max_io_size);
1751 	spdk_json_write_named_uint32(w, "io_unit_size", opts->io_unit_size);
1752 	spdk_json_write_named_uint32(w, "max_aq_depth", opts->max_aq_depth);
1753 	spdk_json_write_named_uint32(w, "num_shared_buffers", opts->num_shared_buffers);
1754 	spdk_json_write_named_uint32(w, "buf_cache_size", opts->buf_cache_size);
1755 	spdk_json_write_named_bool(w, "dif_insert_or_strip", opts->dif_insert_or_strip);
1756 	if (type == SPDK_NVME_TRANSPORT_RDMA) {
1757 		spdk_json_write_named_uint32(w, "max_srq_depth", opts->max_srq_depth);
1758 		spdk_json_write_named_bool(w, "no_srq", opts->no_srq);
1759 	} else if (type == SPDK_NVME_TRANSPORT_TCP) {
1760 		spdk_json_write_named_bool(w, "c2h_success", opts->c2h_success);
1761 		spdk_json_write_named_uint32(w, "sock_priority", opts->sock_priority);
1762 	}
1763 
1764 	spdk_json_write_object_end(w);
1765 }
1766 
1767 struct rpc_get_transport {
1768 	char *tgt_name;
1769 };
1770 
1771 static const struct spdk_json_object_decoder rpc_get_transport_decoders[] = {
1772 	{"tgt_name", offsetof(struct rpc_get_transport, tgt_name), spdk_json_decode_string, true},
1773 };
1774 
1775 static void
1776 spdk_rpc_nvmf_get_transports(struct spdk_jsonrpc_request *request,
1777 			     const struct spdk_json_val *params)
1778 {
1779 	struct rpc_get_transport req = { 0 };
1780 	struct spdk_json_write_ctx *w;
1781 	struct spdk_nvmf_transport *transport;
1782 	struct spdk_nvmf_tgt *tgt;
1783 
1784 	if (params) {
1785 		if (spdk_json_decode_object(params, rpc_get_transport_decoders,
1786 					    SPDK_COUNTOF(rpc_get_transport_decoders),
1787 					    &req)) {
1788 			SPDK_ERRLOG("spdk_json_decode_object failed\n");
1789 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1790 			return;
1791 		}
1792 	}
1793 
1794 	tgt = spdk_nvmf_get_tgt(req.tgt_name);
1795 	if (!tgt) {
1796 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1797 						 "Unable to find a target.");
1798 		free(req.tgt_name);
1799 		return;
1800 	}
1801 
1802 	w = spdk_jsonrpc_begin_result(request);
1803 	spdk_json_write_array_begin(w);
1804 	transport = spdk_nvmf_transport_get_first(tgt);
1805 	while (transport) {
1806 		dump_nvmf_transport(w, transport);
1807 		transport = spdk_nvmf_transport_get_next(transport);
1808 	}
1809 	spdk_json_write_array_end(w);
1810 	spdk_jsonrpc_end_result(request, w);
1811 	free(req.tgt_name);
1812 }
1813 SPDK_RPC_REGISTER("nvmf_get_transports", spdk_rpc_nvmf_get_transports, SPDK_RPC_RUNTIME)
1814 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_get_transports, get_nvmf_transports)
1815 
1816 struct rpc_nvmf_get_stats_ctx {
1817 	char *tgt_name;
1818 	struct spdk_nvmf_tgt *tgt;
1819 	struct spdk_jsonrpc_request *request;
1820 	struct spdk_json_write_ctx *w;
1821 };
1822 
1823 static const struct spdk_json_object_decoder rpc_get_stats_decoders[] = {
1824 	{"tgt_name", offsetof(struct rpc_nvmf_get_stats_ctx, tgt_name), spdk_json_decode_string, true},
1825 };
1826 
1827 static void
1828 free_get_stats_ctx(struct rpc_nvmf_get_stats_ctx *ctx)
1829 {
1830 	free(ctx->tgt_name);
1831 	free(ctx);
1832 }
1833 
1834 static void
1835 rpc_nvmf_get_stats_done(struct spdk_io_channel_iter *i, int status)
1836 {
1837 	struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
1838 
1839 	spdk_json_write_array_end(ctx->w);
1840 	spdk_json_write_object_end(ctx->w);
1841 	spdk_jsonrpc_end_result(ctx->request, ctx->w);
1842 	free_get_stats_ctx(ctx);
1843 }
1844 
1845 static void
1846 write_nvmf_transport_stats(struct spdk_json_write_ctx *w,
1847 			   struct spdk_nvmf_transport_poll_group_stat *stat)
1848 {
1849 	uint64_t i;
1850 
1851 	spdk_json_write_object_begin(w);
1852 	spdk_json_write_named_string(w, "trtype",
1853 				     spdk_nvme_transport_id_trtype_str(stat->trtype));
1854 	switch (stat->trtype) {
1855 	case SPDK_NVME_TRANSPORT_RDMA:
1856 		spdk_json_write_named_uint64(w, "pending_data_buffer", stat->rdma.pending_data_buffer);
1857 		spdk_json_write_named_array_begin(w, "devices");
1858 		for (i = 0; i < stat->rdma.num_devices; ++i) {
1859 			spdk_json_write_object_begin(w);
1860 			spdk_json_write_named_string(w, "name", stat->rdma.devices[i].name);
1861 			spdk_json_write_named_uint64(w, "polls", stat->rdma.devices[i].polls);
1862 			spdk_json_write_named_uint64(w, "completions", stat->rdma.devices[i].completions);
1863 			spdk_json_write_named_uint64(w, "requests",
1864 						     stat->rdma.devices[i].requests);
1865 			spdk_json_write_named_uint64(w, "request_latency",
1866 						     stat->rdma.devices[i].request_latency);
1867 			spdk_json_write_named_uint64(w, "pending_free_request",
1868 						     stat->rdma.devices[i].pending_free_request);
1869 			spdk_json_write_named_uint64(w, "pending_rdma_read",
1870 						     stat->rdma.devices[i].pending_rdma_read);
1871 			spdk_json_write_named_uint64(w, "pending_rdma_write",
1872 						     stat->rdma.devices[i].pending_rdma_write);
1873 			spdk_json_write_object_end(w);
1874 		}
1875 		spdk_json_write_array_end(w);
1876 		break;
1877 	default:
1878 		break;
1879 	}
1880 	spdk_json_write_object_end(w);
1881 }
1882 
1883 static void
1884 rpc_nvmf_get_stats(struct spdk_io_channel_iter *i)
1885 {
1886 	struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
1887 	struct spdk_nvmf_transport *transport;
1888 	struct spdk_nvmf_poll_group_stat stat;
1889 	struct spdk_nvmf_transport_poll_group_stat *trstat;
1890 	int rc;
1891 
1892 	if (0 == spdk_nvmf_poll_group_get_stat(ctx->tgt, &stat)) {
1893 		spdk_json_write_object_begin(ctx->w);
1894 		spdk_json_write_named_string(ctx->w, "name", spdk_thread_get_name(spdk_get_thread()));
1895 		spdk_json_write_named_uint32(ctx->w, "admin_qpairs", stat.admin_qpairs);
1896 		spdk_json_write_named_uint32(ctx->w, "io_qpairs", stat.io_qpairs);
1897 		spdk_json_write_named_uint64(ctx->w, "pending_bdev_io", stat.pending_bdev_io);
1898 
1899 		spdk_json_write_named_array_begin(ctx->w, "transports");
1900 		transport = spdk_nvmf_transport_get_first(ctx->tgt);
1901 		while (transport) {
1902 			rc = spdk_nvmf_transport_poll_group_get_stat(ctx->tgt, transport, &trstat);
1903 			if (0 == rc) {
1904 				write_nvmf_transport_stats(ctx->w, trstat);
1905 				spdk_nvmf_transport_poll_group_free_stat(transport, trstat);
1906 			} else if (-ENOTSUP != rc) {
1907 				SPDK_ERRLOG("Failed to get poll group statistics for transport %s, errno %d\n",
1908 					    spdk_nvme_transport_id_trtype_str(spdk_nvmf_get_transport_type(transport)),
1909 					    rc);
1910 			}
1911 			transport = spdk_nvmf_transport_get_next(transport);
1912 		}
1913 		spdk_json_write_array_end(ctx->w);
1914 		spdk_json_write_object_end(ctx->w);
1915 	}
1916 
1917 	spdk_for_each_channel_continue(i, 0);
1918 }
1919 
1920 
1921 static void
1922 spdk_rpc_nvmf_get_stats(struct spdk_jsonrpc_request *request,
1923 			const struct spdk_json_val *params)
1924 {
1925 	struct rpc_nvmf_get_stats_ctx *ctx;
1926 
1927 	ctx = calloc(1, sizeof(*ctx));
1928 	if (!ctx) {
1929 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1930 						 "Memory allocation error");
1931 		return;
1932 	}
1933 	ctx->request = request;
1934 
1935 	if (params) {
1936 		if (spdk_json_decode_object(params, rpc_get_stats_decoders,
1937 					    SPDK_COUNTOF(rpc_get_stats_decoders),
1938 					    ctx)) {
1939 			SPDK_ERRLOG("spdk_json_decode_object failed\n");
1940 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1941 			free_get_stats_ctx(ctx);
1942 			return;
1943 		}
1944 	}
1945 
1946 	ctx->tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1947 	if (!ctx->tgt) {
1948 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1949 						 "Unable to find a target.");
1950 		free_get_stats_ctx(ctx);
1951 		return;
1952 	}
1953 
1954 	ctx->w = spdk_jsonrpc_begin_result(ctx->request);
1955 	if (NULL == ctx->w) {
1956 		free_get_stats_ctx(ctx);
1957 		return;
1958 	}
1959 
1960 	spdk_json_write_object_begin(ctx->w);
1961 	spdk_json_write_named_uint64(ctx->w, "tick_rate", spdk_get_ticks_hz());
1962 	spdk_json_write_named_array_begin(ctx->w, "poll_groups");
1963 
1964 	spdk_for_each_channel(ctx->tgt,
1965 			      rpc_nvmf_get_stats,
1966 			      ctx,
1967 			      rpc_nvmf_get_stats_done);
1968 }
1969 
1970 SPDK_RPC_REGISTER("nvmf_get_stats", spdk_rpc_nvmf_get_stats, SPDK_RPC_RUNTIME)
1971