xref: /spdk/lib/nvmf/nvmf_rpc.c (revision 0fd542bcf43352bf25e48e6f131fe30f26f7c1b8)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2016 Intel Corporation. All rights reserved.
3  *   Copyright (c) 2018-2021 Mellanox Technologies LTD. All rights reserved.
4  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5  */
6 
7 #include "spdk/bdev.h"
8 #include "spdk/log.h"
9 #include "spdk/rpc.h"
10 #include "spdk/env.h"
11 #include "spdk/nvme.h"
12 #include "spdk/nvmf.h"
13 #include "spdk/string.h"
14 #include "spdk/util.h"
15 #include "spdk/bit_array.h"
16 
17 #include "spdk_internal/assert.h"
18 
19 #include "nvmf_internal.h"
20 
21 static bool g_logged_deprecated_decode_rpc_listen_address = false;
22 
23 static int rpc_ana_state_parse(const char *str, enum spdk_nvme_ana_state *ana_state);
24 
25 static int
26 json_write_hex_str(struct spdk_json_write_ctx *w, const void *data, size_t size)
27 {
28 	static const char hex_char[16] = "0123456789ABCDEF";
29 	const uint8_t *buf = data;
30 	char *str, *out;
31 	int rc;
32 
33 	str = malloc(size * 2 + 1);
34 	if (str == NULL) {
35 		return -1;
36 	}
37 
38 	out = str;
39 	while (size--) {
40 		unsigned byte = *buf++;
41 
42 		out[0] = hex_char[(byte >> 4) & 0xF];
43 		out[1] = hex_char[byte & 0xF];
44 
45 		out += 2;
46 	}
47 	*out = '\0';
48 
49 	rc = spdk_json_write_string(w, str);
50 	free(str);
51 
52 	return rc;
53 }
54 
55 static int
56 hex_nybble_to_num(char c)
57 {
58 	if (c >= '0' && c <= '9') {
59 		return c - '0';
60 	}
61 
62 	if (c >= 'a' && c <= 'f') {
63 		return c - 'a' + 0xA;
64 	}
65 
66 	if (c >= 'A' && c <= 'F') {
67 		return c - 'A' + 0xA;
68 	}
69 
70 	return -1;
71 }
72 
73 static int
74 hex_byte_to_num(const char *str)
75 {
76 	int hi, lo;
77 
78 	hi = hex_nybble_to_num(str[0]);
79 	if (hi < 0) {
80 		return hi;
81 	}
82 
83 	lo = hex_nybble_to_num(str[1]);
84 	if (lo < 0) {
85 		return lo;
86 	}
87 
88 	return hi * 16 + lo;
89 }
90 
91 static int
92 decode_hex_string_be(const char *str, uint8_t *out, size_t size)
93 {
94 	size_t i;
95 
96 	/* Decode a string in "ABCDEF012345" format to its binary representation */
97 	for (i = 0; i < size; i++) {
98 		int num = hex_byte_to_num(str);
99 
100 		if (num < 0) {
101 			/* Invalid hex byte or end of string */
102 			return -1;
103 		}
104 
105 		out[i] = (uint8_t)num;
106 		str += 2;
107 	}
108 
109 	if (i != size || *str != '\0') {
110 		/* Length mismatch */
111 		return -1;
112 	}
113 
114 	return 0;
115 }
116 
117 static int
118 decode_ns_nguid(const struct spdk_json_val *val, void *out)
119 {
120 	char *str = NULL;
121 	int rc;
122 
123 	rc = spdk_json_decode_string(val, &str);
124 	if (rc == 0) {
125 		/* 16-byte NGUID */
126 		rc = decode_hex_string_be(str, out, 16);
127 	}
128 
129 	free(str);
130 	return rc;
131 }
132 
133 static int
134 decode_ns_eui64(const struct spdk_json_val *val, void *out)
135 {
136 	char *str = NULL;
137 	int rc;
138 
139 	rc = spdk_json_decode_string(val, &str);
140 	if (rc == 0) {
141 		/* 8-byte EUI-64 */
142 		rc = decode_hex_string_be(str, out, 8);
143 	}
144 
145 	free(str);
146 	return rc;
147 }
148 
149 struct rpc_get_subsystem {
150 	char *nqn;
151 	char *tgt_name;
152 };
153 
154 static const struct spdk_json_object_decoder rpc_get_subsystem_decoders[] = {
155 	{"nqn", offsetof(struct rpc_get_subsystem, nqn), spdk_json_decode_string, true},
156 	{"tgt_name", offsetof(struct rpc_get_subsystem, tgt_name), spdk_json_decode_string, true},
157 };
158 
159 static void
160 dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct spdk_nvmf_subsystem *subsystem)
161 {
162 	struct spdk_nvmf_host			*host;
163 	struct spdk_nvmf_subsystem_listener	*listener;
164 
165 	spdk_json_write_object_begin(w);
166 
167 	spdk_json_write_named_string(w, "nqn", spdk_nvmf_subsystem_get_nqn(subsystem));
168 	spdk_json_write_name(w, "subtype");
169 	if (spdk_nvmf_subsystem_get_type(subsystem) == SPDK_NVMF_SUBTYPE_NVME) {
170 		spdk_json_write_string(w, "NVMe");
171 	} else {
172 		spdk_json_write_string(w, "Discovery");
173 	}
174 
175 	spdk_json_write_named_array_begin(w, "listen_addresses");
176 
177 	for (listener = spdk_nvmf_subsystem_get_first_listener(subsystem); listener != NULL;
178 	     listener = spdk_nvmf_subsystem_get_next_listener(subsystem, listener)) {
179 		const struct spdk_nvme_transport_id *trid;
180 
181 		trid = spdk_nvmf_subsystem_listener_get_trid(listener);
182 
183 		spdk_json_write_object_begin(w);
184 		nvmf_transport_listen_dump_trid(trid, w);
185 		spdk_json_write_object_end(w);
186 	}
187 	spdk_json_write_array_end(w);
188 
189 	spdk_json_write_named_bool(w, "allow_any_host",
190 				   spdk_nvmf_subsystem_get_allow_any_host(subsystem));
191 
192 	spdk_json_write_named_array_begin(w, "hosts");
193 
194 	for (host = spdk_nvmf_subsystem_get_first_host(subsystem); host != NULL;
195 	     host = spdk_nvmf_subsystem_get_next_host(subsystem, host)) {
196 		spdk_json_write_object_begin(w);
197 		spdk_json_write_named_string(w, "nqn", spdk_nvmf_host_get_nqn(host));
198 		if (host->dhchap_key != NULL) {
199 			spdk_json_write_named_string(w, "dhchap_key",
200 						     spdk_key_get_name(host->dhchap_key));
201 		}
202 		spdk_json_write_object_end(w);
203 	}
204 	spdk_json_write_array_end(w);
205 
206 	if (spdk_nvmf_subsystem_get_type(subsystem) == SPDK_NVMF_SUBTYPE_NVME) {
207 		struct spdk_nvmf_ns *ns;
208 		struct spdk_nvmf_ns_opts ns_opts;
209 		uint32_t max_namespaces;
210 
211 		spdk_json_write_named_string(w, "serial_number", spdk_nvmf_subsystem_get_sn(subsystem));
212 
213 		spdk_json_write_named_string(w, "model_number", spdk_nvmf_subsystem_get_mn(subsystem));
214 
215 		max_namespaces = spdk_nvmf_subsystem_get_max_namespaces(subsystem);
216 		if (max_namespaces != 0) {
217 			spdk_json_write_named_uint32(w, "max_namespaces", max_namespaces);
218 		}
219 
220 		spdk_json_write_named_uint32(w, "min_cntlid", spdk_nvmf_subsystem_get_min_cntlid(subsystem));
221 		spdk_json_write_named_uint32(w, "max_cntlid", spdk_nvmf_subsystem_get_max_cntlid(subsystem));
222 
223 		spdk_json_write_named_array_begin(w, "namespaces");
224 		for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL;
225 		     ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) {
226 			spdk_nvmf_ns_get_opts(ns, &ns_opts, sizeof(ns_opts));
227 			spdk_json_write_object_begin(w);
228 			spdk_json_write_named_int32(w, "nsid", spdk_nvmf_ns_get_id(ns));
229 			spdk_json_write_named_string(w, "bdev_name",
230 						     spdk_bdev_get_name(spdk_nvmf_ns_get_bdev(ns)));
231 			/* NOTE: "name" is kept for compatibility only - new code should use bdev_name. */
232 			spdk_json_write_named_string(w, "name",
233 						     spdk_bdev_get_name(spdk_nvmf_ns_get_bdev(ns)));
234 
235 			if (!spdk_mem_all_zero(ns_opts.nguid, sizeof(ns_opts.nguid))) {
236 				spdk_json_write_name(w, "nguid");
237 				json_write_hex_str(w, ns_opts.nguid, sizeof(ns_opts.nguid));
238 			}
239 
240 			if (!spdk_mem_all_zero(ns_opts.eui64, sizeof(ns_opts.eui64))) {
241 				spdk_json_write_name(w, "eui64");
242 				json_write_hex_str(w, ns_opts.eui64, sizeof(ns_opts.eui64));
243 			}
244 
245 			if (!spdk_uuid_is_null(&ns_opts.uuid)) {
246 				spdk_json_write_named_uuid(w, "uuid", &ns_opts.uuid);
247 			}
248 
249 			if (spdk_nvmf_subsystem_get_ana_reporting(subsystem)) {
250 				spdk_json_write_named_uint32(w, "anagrpid", ns_opts.anagrpid);
251 			}
252 
253 			spdk_json_write_object_end(w);
254 		}
255 		spdk_json_write_array_end(w);
256 	}
257 	spdk_json_write_object_end(w);
258 }
259 
260 static void
261 rpc_nvmf_get_subsystems(struct spdk_jsonrpc_request *request,
262 			const struct spdk_json_val *params)
263 {
264 	struct rpc_get_subsystem req = { 0 };
265 	struct spdk_json_write_ctx *w;
266 	struct spdk_nvmf_subsystem *subsystem = NULL;
267 	struct spdk_nvmf_tgt *tgt;
268 
269 	if (params) {
270 		if (spdk_json_decode_object(params, rpc_get_subsystem_decoders,
271 					    SPDK_COUNTOF(rpc_get_subsystem_decoders),
272 					    &req)) {
273 			SPDK_ERRLOG("spdk_json_decode_object failed\n");
274 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
275 			return;
276 		}
277 	}
278 
279 	tgt = spdk_nvmf_get_tgt(req.tgt_name);
280 	if (!tgt) {
281 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
282 						 "Unable to find a target.");
283 		free(req.tgt_name);
284 		free(req.nqn);
285 		return;
286 	}
287 
288 	if (req.nqn) {
289 		subsystem = spdk_nvmf_tgt_find_subsystem(tgt, req.nqn);
290 		if (!subsystem) {
291 			SPDK_ERRLOG("subsystem '%s' does not exist\n", req.nqn);
292 			spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
293 			free(req.tgt_name);
294 			free(req.nqn);
295 			return;
296 		}
297 	}
298 
299 	w = spdk_jsonrpc_begin_result(request);
300 	spdk_json_write_array_begin(w);
301 
302 	if (subsystem) {
303 		dump_nvmf_subsystem(w, subsystem);
304 	} else {
305 		for (subsystem = spdk_nvmf_subsystem_get_first(tgt); subsystem != NULL;
306 		     subsystem = spdk_nvmf_subsystem_get_next(subsystem)) {
307 			dump_nvmf_subsystem(w, subsystem);
308 		}
309 	}
310 
311 	spdk_json_write_array_end(w);
312 	spdk_jsonrpc_end_result(request, w);
313 	free(req.tgt_name);
314 	free(req.nqn);
315 }
316 SPDK_RPC_REGISTER("nvmf_get_subsystems", rpc_nvmf_get_subsystems, SPDK_RPC_RUNTIME)
317 
318 struct rpc_subsystem_create {
319 	char *nqn;
320 	char *serial_number;
321 	char *model_number;
322 	char *tgt_name;
323 	uint32_t max_namespaces;
324 	bool allow_any_host;
325 	bool ana_reporting;
326 	uint16_t min_cntlid;
327 	uint16_t max_cntlid;
328 	uint64_t max_discard_size_kib;
329 	uint64_t max_write_zeroes_size_kib;
330 };
331 
332 static const struct spdk_json_object_decoder rpc_subsystem_create_decoders[] = {
333 	{"nqn", offsetof(struct rpc_subsystem_create, nqn), spdk_json_decode_string},
334 	{"serial_number", offsetof(struct rpc_subsystem_create, serial_number), spdk_json_decode_string, true},
335 	{"model_number", offsetof(struct rpc_subsystem_create, model_number), spdk_json_decode_string, true},
336 	{"tgt_name", offsetof(struct rpc_subsystem_create, tgt_name), spdk_json_decode_string, true},
337 	{"max_namespaces", offsetof(struct rpc_subsystem_create, max_namespaces), spdk_json_decode_uint32, true},
338 	{"allow_any_host", offsetof(struct rpc_subsystem_create, allow_any_host), spdk_json_decode_bool, true},
339 	{"ana_reporting", offsetof(struct rpc_subsystem_create, ana_reporting), spdk_json_decode_bool, true},
340 	{"min_cntlid", offsetof(struct rpc_subsystem_create, min_cntlid), spdk_json_decode_uint16, true},
341 	{"max_cntlid", offsetof(struct rpc_subsystem_create, max_cntlid), spdk_json_decode_uint16, true},
342 	{"max_discard_size_kib", offsetof(struct rpc_subsystem_create, max_discard_size_kib), spdk_json_decode_uint64, true},
343 	{"max_write_zeroes_size_kib", offsetof(struct rpc_subsystem_create, max_write_zeroes_size_kib), spdk_json_decode_uint64, true},
344 };
345 
346 static void
347 rpc_nvmf_subsystem_started(struct spdk_nvmf_subsystem *subsystem,
348 			   void *cb_arg, int status)
349 {
350 	struct spdk_jsonrpc_request *request = cb_arg;
351 
352 	if (!status) {
353 		spdk_jsonrpc_send_bool_response(request, true);
354 	} else {
355 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
356 						     "Subsystem %s start failed",
357 						     subsystem->subnqn);
358 		spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
359 	}
360 }
361 
362 static void
363 rpc_nvmf_create_subsystem(struct spdk_jsonrpc_request *request,
364 			  const struct spdk_json_val *params)
365 {
366 	struct rpc_subsystem_create *req;
367 	struct spdk_nvmf_subsystem *subsystem = NULL;
368 	struct spdk_nvmf_tgt *tgt;
369 	int rc = -1;
370 
371 	req = calloc(1, sizeof(*req));
372 	if (!req) {
373 		SPDK_ERRLOG("Memory allocation failed\n");
374 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
375 						 "Memory allocation failed");
376 		return;
377 	}
378 	req->min_cntlid = NVMF_MIN_CNTLID;
379 	req->max_cntlid = NVMF_MAX_CNTLID;
380 
381 	if (spdk_json_decode_object(params, rpc_subsystem_create_decoders,
382 				    SPDK_COUNTOF(rpc_subsystem_create_decoders),
383 				    req)) {
384 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
385 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
386 		goto cleanup;
387 	}
388 
389 	tgt = spdk_nvmf_get_tgt(req->tgt_name);
390 	if (!tgt) {
391 		SPDK_ERRLOG("Unable to find target %s\n", req->tgt_name);
392 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
393 						     "Unable to find target %s", req->tgt_name);
394 		goto cleanup;
395 	}
396 
397 	subsystem = spdk_nvmf_subsystem_create(tgt, req->nqn, SPDK_NVMF_SUBTYPE_NVME,
398 					       req->max_namespaces);
399 	if (!subsystem) {
400 		SPDK_ERRLOG("Unable to create subsystem %s\n", req->nqn);
401 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
402 						     "Unable to create subsystem %s", req->nqn);
403 		goto cleanup;
404 	}
405 
406 	if (req->serial_number) {
407 		if (spdk_nvmf_subsystem_set_sn(subsystem, req->serial_number)) {
408 			SPDK_ERRLOG("Subsystem %s: invalid serial number '%s'\n", req->nqn, req->serial_number);
409 			spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
410 							     "Invalid SN %s", req->serial_number);
411 			goto cleanup;
412 		}
413 	}
414 
415 	if (req->model_number) {
416 		if (spdk_nvmf_subsystem_set_mn(subsystem, req->model_number)) {
417 			SPDK_ERRLOG("Subsystem %s: invalid model number '%s'\n", req->nqn, req->model_number);
418 			spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
419 							     "Invalid MN %s", req->model_number);
420 			goto cleanup;
421 		}
422 	}
423 
424 	spdk_nvmf_subsystem_set_allow_any_host(subsystem, req->allow_any_host);
425 
426 	spdk_nvmf_subsystem_set_ana_reporting(subsystem, req->ana_reporting);
427 
428 	if (nvmf_subsystem_set_cntlid_range(subsystem, req->min_cntlid, req->max_cntlid)) {
429 		SPDK_ERRLOG("Subsystem %s: invalid cntlid range [%u-%u]\n", req->nqn, req->min_cntlid,
430 			    req->max_cntlid);
431 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
432 						     "Invalid cntlid range [%u-%u]", req->min_cntlid, req->max_cntlid);
433 		goto cleanup;
434 	}
435 
436 	subsystem->max_discard_size_kib = req->max_discard_size_kib;
437 
438 	/* max_write_zeroes_size_kib must be aligned to 4 and power of 2 */
439 	if (req->max_write_zeroes_size_kib == 0 || (req->max_write_zeroes_size_kib > 2 &&
440 			spdk_u64_is_pow2(req->max_write_zeroes_size_kib))) {
441 		subsystem->max_write_zeroes_size_kib = req->max_write_zeroes_size_kib;
442 	} else {
443 		SPDK_ERRLOG("Subsystem %s: invalid max_write_zeroes_size_kib %"PRIu64"\n", req->nqn,
444 			    req->max_write_zeroes_size_kib);
445 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
446 						     "Invalid max_write_zeroes_size_kib %"PRIu64"\n", req->max_write_zeroes_size_kib);
447 		goto cleanup;
448 	}
449 
450 	rc = spdk_nvmf_subsystem_start(subsystem,
451 				       rpc_nvmf_subsystem_started,
452 				       request);
453 	if (rc) {
454 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
455 						 "Failed to start subsystem");
456 	}
457 
458 cleanup:
459 	free(req->nqn);
460 	free(req->tgt_name);
461 	free(req->serial_number);
462 	free(req->model_number);
463 	free(req);
464 
465 	if (rc && subsystem) {
466 		spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
467 	}
468 }
469 SPDK_RPC_REGISTER("nvmf_create_subsystem", rpc_nvmf_create_subsystem, SPDK_RPC_RUNTIME)
470 
471 struct rpc_delete_subsystem {
472 	char *nqn;
473 	char *tgt_name;
474 };
475 
476 static void
477 free_rpc_delete_subsystem(struct rpc_delete_subsystem *r)
478 {
479 	free(r->nqn);
480 	free(r->tgt_name);
481 }
482 
483 static void
484 rpc_nvmf_subsystem_destroy_complete_cb(void *cb_arg)
485 {
486 	struct spdk_jsonrpc_request *request = cb_arg;
487 
488 	spdk_jsonrpc_send_bool_response(request, true);
489 }
490 
491 static void
492 rpc_nvmf_subsystem_stopped(struct spdk_nvmf_subsystem *subsystem,
493 			   void *cb_arg, int status)
494 {
495 	struct spdk_jsonrpc_request *request = cb_arg;
496 	int rc;
497 
498 	nvmf_subsystem_remove_all_listeners(subsystem, true);
499 	rc = spdk_nvmf_subsystem_destroy(subsystem, rpc_nvmf_subsystem_destroy_complete_cb, request);
500 	if (rc) {
501 		if (rc == -EINPROGRESS) {
502 			/* response will be sent in completion callback */
503 			return;
504 		} else {
505 			SPDK_ERRLOG("Subsystem destruction failed, rc %d\n", rc);
506 			spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
507 							     "Subsystem destruction failed, rc %d", rc);
508 			return;
509 		}
510 	}
511 	spdk_jsonrpc_send_bool_response(request, true);
512 }
513 
514 static const struct spdk_json_object_decoder rpc_delete_subsystem_decoders[] = {
515 	{"nqn", offsetof(struct rpc_delete_subsystem, nqn), spdk_json_decode_string},
516 	{"tgt_name", offsetof(struct rpc_delete_subsystem, tgt_name), spdk_json_decode_string, true},
517 };
518 
519 static void
520 rpc_nvmf_delete_subsystem(struct spdk_jsonrpc_request *request,
521 			  const struct spdk_json_val *params)
522 {
523 	struct rpc_delete_subsystem req = { 0 };
524 	struct spdk_nvmf_subsystem *subsystem;
525 	struct spdk_nvmf_tgt *tgt;
526 	int rc;
527 
528 	if (spdk_json_decode_object(params, rpc_delete_subsystem_decoders,
529 				    SPDK_COUNTOF(rpc_delete_subsystem_decoders),
530 				    &req)) {
531 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
532 		goto invalid;
533 	}
534 
535 	if (req.nqn == NULL) {
536 		SPDK_ERRLOG("missing name param\n");
537 		goto invalid;
538 	}
539 
540 	tgt = spdk_nvmf_get_tgt(req.tgt_name);
541 	if (!tgt) {
542 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
543 						 "Unable to find a target.");
544 		goto invalid_custom_response;
545 	}
546 
547 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, req.nqn);
548 	if (!subsystem) {
549 		goto invalid;
550 	}
551 
552 	free_rpc_delete_subsystem(&req);
553 
554 	rc = spdk_nvmf_subsystem_stop(subsystem,
555 				      rpc_nvmf_subsystem_stopped,
556 				      request);
557 	if (rc == -EBUSY) {
558 		SPDK_ERRLOG("Subsystem currently in another state change try again later.\n");
559 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
560 						 "Subsystem currently in another state change try again later.");
561 	} else if (rc != 0) {
562 		SPDK_ERRLOG("Unable to change state on subsystem. rc=%d\n", rc);
563 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
564 						     "Unable to change state on subsystem. rc=%d", rc);
565 	}
566 
567 	return;
568 
569 invalid:
570 	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
571 invalid_custom_response:
572 	free_rpc_delete_subsystem(&req);
573 }
574 SPDK_RPC_REGISTER("nvmf_delete_subsystem", rpc_nvmf_delete_subsystem, SPDK_RPC_RUNTIME)
575 
576 struct rpc_listen_address {
577 	char *transport;
578 	char *adrfam;
579 	char *traddr;
580 	char *trsvcid;
581 };
582 
583 static const struct spdk_json_object_decoder rpc_listen_address_decoders[] = {
584 	/* NOTE: "transport" is kept for compatibility; new code should use "trtype" */
585 	{"transport", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true},
586 	{"trtype", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true},
587 	{"adrfam", offsetof(struct rpc_listen_address, adrfam), spdk_json_decode_string, true},
588 	{"traddr", offsetof(struct rpc_listen_address, traddr), spdk_json_decode_string},
589 	{"trsvcid", offsetof(struct rpc_listen_address, trsvcid), spdk_json_decode_string, true},
590 };
591 
592 SPDK_LOG_DEPRECATION_REGISTER(decode_rpc_listen_address,
593 			      "[listen_]address.transport is deprecated in favor of trtype",
594 			      "v24.09", 0);
595 
596 static int
597 decode_rpc_listen_address(const struct spdk_json_val *val, void *out)
598 {
599 	struct rpc_listen_address *req = (struct rpc_listen_address *)out;
600 
601 	if (spdk_json_decode_object(val, rpc_listen_address_decoders,
602 				    SPDK_COUNTOF(rpc_listen_address_decoders),
603 				    req)) {
604 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
605 		return -1;
606 	}
607 
608 	/* Log only once */
609 	if (req->transport && !g_logged_deprecated_decode_rpc_listen_address) {
610 		SPDK_LOG_DEPRECATED(decode_rpc_listen_address);
611 		g_logged_deprecated_decode_rpc_listen_address = true;
612 	}
613 
614 	return 0;
615 }
616 
617 static void
618 free_rpc_listen_address(struct rpc_listen_address *r)
619 {
620 	free(r->transport);
621 	free(r->adrfam);
622 	free(r->traddr);
623 	free(r->trsvcid);
624 }
625 
626 enum nvmf_rpc_listen_op {
627 	NVMF_RPC_LISTEN_ADD,
628 	NVMF_RPC_LISTEN_REMOVE,
629 	NVMF_RPC_LISTEN_SET_ANA_STATE,
630 };
631 
632 struct nvmf_rpc_listener_ctx {
633 	char				*nqn;
634 	char				*tgt_name;
635 	struct spdk_nvmf_tgt		*tgt;
636 	struct spdk_nvmf_transport	*transport;
637 	struct spdk_nvmf_subsystem	*subsystem;
638 	struct rpc_listen_address	address;
639 	char				*ana_state_str;
640 	enum spdk_nvme_ana_state	ana_state;
641 	uint32_t			anagrpid;
642 
643 	struct spdk_jsonrpc_request	*request;
644 	struct spdk_nvme_transport_id	trid;
645 	enum nvmf_rpc_listen_op		op;
646 	bool				response_sent;
647 	struct spdk_nvmf_listen_opts	opts;
648 
649 	/* Additional options for listener creation. */
650 	struct spdk_nvmf_listener_opts	listener_opts;
651 };
652 
653 static const struct spdk_json_object_decoder nvmf_rpc_listener_decoder[] = {
654 	{"nqn", offsetof(struct nvmf_rpc_listener_ctx, nqn), spdk_json_decode_string},
655 	{"listen_address", offsetof(struct nvmf_rpc_listener_ctx, address), decode_rpc_listen_address},
656 	{"tgt_name", offsetof(struct nvmf_rpc_listener_ctx, tgt_name), spdk_json_decode_string, true},
657 	{"secure_channel", offsetof(struct nvmf_rpc_listener_ctx, listener_opts.secure_channel), spdk_json_decode_bool, true},
658 	{"ana_state", offsetof(struct nvmf_rpc_listener_ctx, ana_state_str), spdk_json_decode_string, true},
659 };
660 
661 static void
662 nvmf_rpc_listener_ctx_free(struct nvmf_rpc_listener_ctx *ctx)
663 {
664 	free(ctx->nqn);
665 	free(ctx->tgt_name);
666 	free_rpc_listen_address(&ctx->address);
667 	free(ctx->ana_state_str);
668 	free(ctx);
669 }
670 
671 static void
672 nvmf_rpc_listen_resumed(struct spdk_nvmf_subsystem *subsystem,
673 			void *cb_arg, int status)
674 {
675 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
676 	struct spdk_jsonrpc_request *request;
677 
678 	request = ctx->request;
679 	if (ctx->response_sent) {
680 		/* If an error occurred, the response has already been sent. */
681 		nvmf_rpc_listener_ctx_free(ctx);
682 		return;
683 	}
684 
685 	nvmf_rpc_listener_ctx_free(ctx);
686 
687 	spdk_jsonrpc_send_bool_response(request, true);
688 }
689 
690 static void
691 nvmf_rpc_subsystem_listen(void *cb_arg, int status)
692 {
693 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
694 
695 	if (status) {
696 		/* Destroy the listener that we just created. Ignore the error code because
697 		 * the RPC is failing already anyway. */
698 		spdk_nvmf_tgt_stop_listen(ctx->tgt, &ctx->trid);
699 
700 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
701 						 "Invalid parameters");
702 		ctx->response_sent = true;
703 	}
704 
705 	if (spdk_nvmf_subsystem_resume(ctx->subsystem, nvmf_rpc_listen_resumed, ctx)) {
706 		if (!ctx->response_sent) {
707 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
708 							 "Internal error");
709 		}
710 		nvmf_rpc_listener_ctx_free(ctx);
711 		/* Can't really do anything to recover here - subsystem will remain paused. */
712 	}
713 }
714 static void
715 nvmf_rpc_stop_listen_async_done(void *cb_arg, int status)
716 {
717 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
718 
719 	if (status) {
720 		SPDK_ERRLOG("Unable to stop listener.\n");
721 		spdk_jsonrpc_send_error_response_fmt(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
722 						     "error stopping listener: %d", status);
723 		ctx->response_sent = true;
724 	}
725 
726 	if (spdk_nvmf_subsystem_resume(ctx->subsystem, nvmf_rpc_listen_resumed, ctx)) {
727 		if (!ctx->response_sent) {
728 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
729 							 "Internal error");
730 		}
731 		nvmf_rpc_listener_ctx_free(ctx);
732 		/* Can't really do anything to recover here - subsystem will remain paused. */
733 	}
734 }
735 
736 static void
737 nvmf_rpc_set_ana_state_done(void *cb_arg, int status)
738 {
739 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
740 
741 	if (status) {
742 		SPDK_ERRLOG("Unable to set ANA state.\n");
743 		spdk_jsonrpc_send_error_response_fmt(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
744 						     "error setting ANA state: %d", status);
745 		ctx->response_sent = true;
746 	}
747 
748 	if (spdk_nvmf_subsystem_resume(ctx->subsystem, nvmf_rpc_listen_resumed, ctx)) {
749 		if (!ctx->response_sent) {
750 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
751 							 "Internal error");
752 		}
753 		nvmf_rpc_listener_ctx_free(ctx);
754 		/* Can't really do anything to recover here - subsystem will remain paused. */
755 	}
756 }
757 
758 static void
759 nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem,
760 		       void *cb_arg, int status)
761 {
762 	struct nvmf_rpc_listener_ctx *ctx = cb_arg;
763 	int rc;
764 
765 	switch (ctx->op) {
766 	case NVMF_RPC_LISTEN_ADD:
767 		if (nvmf_subsystem_find_listener(subsystem, &ctx->trid)) {
768 			SPDK_ERRLOG("Listener already exists\n");
769 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
770 							 "Invalid parameters");
771 			ctx->response_sent = true;
772 			break;
773 		}
774 
775 		rc = spdk_nvmf_tgt_listen_ext(ctx->tgt, &ctx->trid, &ctx->opts);
776 		if (rc) {
777 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
778 							 "Invalid parameters");
779 			ctx->response_sent = true;
780 			break;
781 		}
782 
783 		spdk_nvmf_subsystem_add_listener_ext(ctx->subsystem, &ctx->trid, nvmf_rpc_subsystem_listen, ctx,
784 						     &ctx->listener_opts);
785 		return;
786 	case NVMF_RPC_LISTEN_REMOVE:
787 		rc = spdk_nvmf_subsystem_remove_listener(subsystem, &ctx->trid);
788 		if (rc) {
789 			SPDK_ERRLOG("Unable to remove listener, rc %d\n", rc);
790 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
791 							 "Invalid parameters");
792 			ctx->response_sent = true;
793 			break;
794 		}
795 
796 		spdk_nvmf_transport_stop_listen_async(ctx->transport, &ctx->trid, subsystem,
797 						      nvmf_rpc_stop_listen_async_done, ctx);
798 		return;
799 	case NVMF_RPC_LISTEN_SET_ANA_STATE:
800 		spdk_nvmf_subsystem_set_ana_state(subsystem, &ctx->trid, ctx->ana_state, ctx->anagrpid,
801 						  nvmf_rpc_set_ana_state_done, ctx);
802 		return;
803 	default:
804 		SPDK_UNREACHABLE();
805 	}
806 
807 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_listen_resumed, ctx)) {
808 		if (!ctx->response_sent) {
809 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
810 							 "Internal error");
811 		}
812 
813 		nvmf_rpc_listener_ctx_free(ctx);
814 		/* Can't really do anything to recover here - subsystem will remain paused. */
815 	}
816 }
817 
818 static int
819 rpc_listen_address_to_trid(const struct rpc_listen_address *address,
820 			   struct spdk_nvme_transport_id *trid)
821 {
822 	size_t len;
823 
824 	memset(trid, 0, sizeof(*trid));
825 
826 	if (spdk_nvme_transport_id_populate_trstring(trid, address->transport)) {
827 		SPDK_ERRLOG("Invalid transport string: %s\n", address->transport);
828 		return -EINVAL;
829 	}
830 
831 	if (spdk_nvme_transport_id_parse_trtype(&trid->trtype, address->transport)) {
832 		SPDK_ERRLOG("Invalid transport type: %s\n", address->transport);
833 		return -EINVAL;
834 	}
835 
836 	if (address->adrfam) {
837 		if (spdk_nvme_transport_id_parse_adrfam(&trid->adrfam, address->adrfam)) {
838 			SPDK_ERRLOG("Invalid adrfam: %s\n", address->adrfam);
839 			return -EINVAL;
840 		}
841 	} else {
842 		trid->adrfam = SPDK_NVMF_ADRFAM_IPV4;
843 	}
844 
845 	len = strlen(address->traddr);
846 	if (len > sizeof(trid->traddr) - 1) {
847 		SPDK_ERRLOG("Transport address longer than %zu characters: %s\n",
848 			    sizeof(trid->traddr) - 1, address->traddr);
849 		return -EINVAL;
850 	}
851 	memcpy(trid->traddr, address->traddr, len + 1);
852 
853 	trid->trsvcid[0] = '\0';
854 	if (address->trsvcid) {
855 		len = strlen(address->trsvcid);
856 		if (len > sizeof(trid->trsvcid) - 1) {
857 			SPDK_ERRLOG("Transport service id longer than %zu characters: %s\n",
858 				    sizeof(trid->trsvcid) - 1, address->trsvcid);
859 			return -EINVAL;
860 		}
861 		memcpy(trid->trsvcid, address->trsvcid, len + 1);
862 	}
863 
864 	return 0;
865 }
866 
867 static void
868 rpc_nvmf_subsystem_add_listener(struct spdk_jsonrpc_request *request,
869 				const struct spdk_json_val *params)
870 {
871 	struct nvmf_rpc_listener_ctx *ctx;
872 	struct spdk_nvmf_subsystem *subsystem;
873 	struct spdk_nvmf_tgt *tgt;
874 	int rc;
875 
876 	ctx = calloc(1, sizeof(*ctx));
877 	if (!ctx) {
878 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
879 		return;
880 	}
881 
882 	ctx->request = request;
883 
884 	spdk_nvmf_subsystem_listener_opts_init(&ctx->listener_opts, sizeof(ctx->listener_opts));
885 
886 	if (spdk_json_decode_object_relaxed(params, nvmf_rpc_listener_decoder,
887 					    SPDK_COUNTOF(nvmf_rpc_listener_decoder),
888 					    ctx)) {
889 		SPDK_ERRLOG("spdk_json_decode_object_relaxed failed\n");
890 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
891 		nvmf_rpc_listener_ctx_free(ctx);
892 		return;
893 	}
894 
895 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
896 	if (!tgt) {
897 		SPDK_ERRLOG("Unable to find a target object.\n");
898 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
899 						 "Unable to find a target.");
900 		nvmf_rpc_listener_ctx_free(ctx);
901 		return;
902 	}
903 	ctx->tgt = tgt;
904 
905 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
906 	if (!subsystem) {
907 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
908 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
909 		nvmf_rpc_listener_ctx_free(ctx);
910 		return;
911 	}
912 
913 	ctx->subsystem = subsystem;
914 
915 	if (rpc_listen_address_to_trid(&ctx->address, &ctx->trid)) {
916 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
917 						 "Invalid parameters");
918 		nvmf_rpc_listener_ctx_free(ctx);
919 		return;
920 	}
921 
922 	ctx->op = NVMF_RPC_LISTEN_ADD;
923 	spdk_nvmf_listen_opts_init(&ctx->opts, sizeof(ctx->opts));
924 	ctx->opts.transport_specific = params;
925 	if (subsystem->flags.allow_any_host == 1 && ctx->listener_opts.secure_channel == true) {
926 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
927 						 "Cannot establish secure channel, when 'allow_any_host' is set");
928 		nvmf_rpc_listener_ctx_free(ctx);
929 		return;
930 	}
931 	ctx->opts.secure_channel = ctx->listener_opts.secure_channel;
932 
933 	if (ctx->ana_state_str) {
934 		if (rpc_ana_state_parse(ctx->ana_state_str, &ctx->ana_state)) {
935 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
936 							 "Invalid parameters");
937 			nvmf_rpc_listener_ctx_free(ctx);
938 			return;
939 		}
940 		ctx->listener_opts.ana_state = ctx->ana_state;
941 	}
942 
943 	rc = spdk_nvmf_subsystem_pause(subsystem, 0, nvmf_rpc_listen_paused, ctx);
944 	if (rc != 0) {
945 		if (rc == -EBUSY) {
946 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
947 							 "subsystem busy, retry later.\n");
948 		} else {
949 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
950 		}
951 		nvmf_rpc_listener_ctx_free(ctx);
952 	}
953 }
954 SPDK_RPC_REGISTER("nvmf_subsystem_add_listener", rpc_nvmf_subsystem_add_listener,
955 		  SPDK_RPC_RUNTIME);
956 
957 static void
958 rpc_nvmf_subsystem_remove_listener(struct spdk_jsonrpc_request *request,
959 				   const struct spdk_json_val *params)
960 {
961 	struct nvmf_rpc_listener_ctx *ctx;
962 	struct spdk_nvmf_subsystem *subsystem;
963 	struct spdk_nvmf_tgt *tgt;
964 	int rc;
965 
966 	ctx = calloc(1, sizeof(*ctx));
967 	if (!ctx) {
968 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
969 		return;
970 	}
971 
972 	ctx->request = request;
973 
974 	if (spdk_json_decode_object(params, nvmf_rpc_listener_decoder,
975 				    SPDK_COUNTOF(nvmf_rpc_listener_decoder),
976 				    ctx)) {
977 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
978 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
979 		nvmf_rpc_listener_ctx_free(ctx);
980 		return;
981 	}
982 
983 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
984 	if (!tgt) {
985 		SPDK_ERRLOG("Unable to find a target object.\n");
986 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
987 						 "Unable to find a target.");
988 		nvmf_rpc_listener_ctx_free(ctx);
989 		return;
990 	}
991 	ctx->tgt = tgt;
992 
993 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
994 	if (!subsystem) {
995 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
996 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
997 		nvmf_rpc_listener_ctx_free(ctx);
998 		return;
999 	}
1000 
1001 	ctx->subsystem = subsystem;
1002 
1003 	if (rpc_listen_address_to_trid(&ctx->address, &ctx->trid)) {
1004 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1005 						 "Invalid parameters");
1006 		nvmf_rpc_listener_ctx_free(ctx);
1007 		return;
1008 	}
1009 
1010 	ctx->transport = spdk_nvmf_tgt_get_transport(tgt, ctx->trid.trstring);
1011 	if (!ctx->transport) {
1012 		SPDK_ERRLOG("Unable to find %s transport. The transport must be created first also make sure it is properly registered.\n",
1013 			    ctx->trid.trstring);
1014 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1015 						 "Invalid parameters");
1016 		nvmf_rpc_listener_ctx_free(ctx);
1017 		return;
1018 	}
1019 
1020 	ctx->op = NVMF_RPC_LISTEN_REMOVE;
1021 
1022 	rc = spdk_nvmf_subsystem_pause(subsystem, 0, nvmf_rpc_listen_paused, ctx);
1023 	if (rc != 0) {
1024 		if (rc == -EBUSY) {
1025 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1026 							 "subsystem busy, retry later.\n");
1027 		} else {
1028 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1029 		}
1030 		nvmf_rpc_listener_ctx_free(ctx);
1031 	}
1032 }
1033 SPDK_RPC_REGISTER("nvmf_subsystem_remove_listener", rpc_nvmf_subsystem_remove_listener,
1034 		  SPDK_RPC_RUNTIME);
1035 
1036 struct nvmf_rpc_referral_ctx {
1037 	char				*tgt_name;
1038 	struct rpc_listen_address	address;
1039 	bool				secure_channel;
1040 	char				*subnqn;
1041 };
1042 
1043 static const struct spdk_json_object_decoder nvmf_rpc_referral_decoder[] = {
1044 	{"address", offsetof(struct nvmf_rpc_referral_ctx, address), decode_rpc_listen_address},
1045 	{"tgt_name", offsetof(struct nvmf_rpc_referral_ctx, tgt_name), spdk_json_decode_string, true},
1046 	{"secure_channel", offsetof(struct nvmf_rpc_referral_ctx, secure_channel), spdk_json_decode_bool, true},
1047 	{"subnqn", offsetof(struct nvmf_rpc_referral_ctx, subnqn), spdk_json_decode_string, true},
1048 };
1049 
1050 static void
1051 nvmf_rpc_referral_ctx_free(struct nvmf_rpc_referral_ctx *ctx)
1052 {
1053 	free(ctx->tgt_name);
1054 	free(ctx->subnqn);
1055 	free_rpc_listen_address(&ctx->address);
1056 }
1057 
1058 static void
1059 rpc_nvmf_add_referral(struct spdk_jsonrpc_request *request,
1060 		      const struct spdk_json_val *params)
1061 {
1062 	struct nvmf_rpc_referral_ctx ctx = {};
1063 	struct spdk_nvme_transport_id trid = {};
1064 	struct spdk_nvmf_tgt *tgt;
1065 	struct spdk_nvmf_referral_opts opts = {};
1066 	int rc;
1067 
1068 	if (spdk_json_decode_object_relaxed(params, nvmf_rpc_referral_decoder,
1069 					    SPDK_COUNTOF(nvmf_rpc_referral_decoder),
1070 					    &ctx)) {
1071 		SPDK_ERRLOG("spdk_json_decode_object_relaxed failed\n");
1072 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1073 		nvmf_rpc_referral_ctx_free(&ctx);
1074 		return;
1075 	}
1076 
1077 	tgt = spdk_nvmf_get_tgt(ctx.tgt_name);
1078 	if (!tgt) {
1079 		SPDK_ERRLOG("Unable to find a target object.\n");
1080 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1081 						 "Unable to find a target.");
1082 		nvmf_rpc_referral_ctx_free(&ctx);
1083 		return;
1084 	}
1085 
1086 	if (rpc_listen_address_to_trid(&ctx.address, &trid)) {
1087 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1088 						 "Invalid parameters");
1089 		nvmf_rpc_referral_ctx_free(&ctx);
1090 		return;
1091 	}
1092 
1093 	if (ctx.subnqn != NULL) {
1094 		rc = snprintf(trid.subnqn, sizeof(trid.subnqn), "%s", ctx.subnqn);
1095 		if (rc < 0 || (size_t)rc >= sizeof(trid.subnqn)) {
1096 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1097 							 "Invalid subsystem NQN");
1098 			nvmf_rpc_referral_ctx_free(&ctx);
1099 			return;
1100 		}
1101 	}
1102 
1103 	if ((trid.trtype == SPDK_NVME_TRANSPORT_TCP ||
1104 	     trid.trtype == SPDK_NVME_TRANSPORT_RDMA) &&
1105 	    !strlen(trid.trsvcid)) {
1106 		SPDK_ERRLOG("Service ID is required.\n");
1107 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1108 						 "Service ID is required.");
1109 		nvmf_rpc_referral_ctx_free(&ctx);
1110 		return;
1111 	}
1112 
1113 	opts.size = SPDK_SIZEOF(&opts, secure_channel);
1114 	opts.trid = trid;
1115 	opts.secure_channel = ctx.secure_channel;
1116 
1117 	rc = spdk_nvmf_tgt_add_referral(tgt, &opts);
1118 	if (rc != 0) {
1119 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1120 						 "Internal error");
1121 		nvmf_rpc_referral_ctx_free(&ctx);
1122 		return;
1123 	}
1124 
1125 	nvmf_rpc_referral_ctx_free(&ctx);
1126 
1127 	spdk_jsonrpc_send_bool_response(request, true);
1128 }
1129 
1130 SPDK_RPC_REGISTER("nvmf_discovery_add_referral", rpc_nvmf_add_referral,
1131 		  SPDK_RPC_RUNTIME);
1132 
1133 static void
1134 rpc_nvmf_remove_referral(struct spdk_jsonrpc_request *request,
1135 			 const struct spdk_json_val *params)
1136 {
1137 	struct nvmf_rpc_referral_ctx ctx = {};
1138 	struct spdk_nvme_transport_id trid = {};
1139 	struct spdk_nvmf_referral_opts opts = {};
1140 	struct spdk_nvmf_tgt *tgt;
1141 	int rc;
1142 
1143 	if (spdk_json_decode_object(params, nvmf_rpc_referral_decoder,
1144 				    SPDK_COUNTOF(nvmf_rpc_referral_decoder),
1145 				    &ctx)) {
1146 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1147 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1148 		nvmf_rpc_referral_ctx_free(&ctx);
1149 		return;
1150 	}
1151 
1152 	tgt = spdk_nvmf_get_tgt(ctx.tgt_name);
1153 	if (!tgt) {
1154 		SPDK_ERRLOG("Unable to find a target object.\n");
1155 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1156 						 "Unable to find a target.");
1157 		nvmf_rpc_referral_ctx_free(&ctx);
1158 		return;
1159 	}
1160 
1161 	if (rpc_listen_address_to_trid(&ctx.address, &trid)) {
1162 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1163 						 "Invalid parameters");
1164 		nvmf_rpc_referral_ctx_free(&ctx);
1165 		return;
1166 	}
1167 
1168 	if (ctx.subnqn != NULL) {
1169 		rc = snprintf(trid.subnqn, sizeof(trid.subnqn), "%s", ctx.subnqn);
1170 		if (rc < 0 || (size_t)rc >= sizeof(trid.subnqn)) {
1171 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1172 							 "Invalid subsystem NQN");
1173 			nvmf_rpc_referral_ctx_free(&ctx);
1174 			return;
1175 		}
1176 	}
1177 
1178 	opts.size = SPDK_SIZEOF(&opts, secure_channel);
1179 	opts.trid = trid;
1180 
1181 	if (spdk_nvmf_tgt_remove_referral(tgt, &opts)) {
1182 		SPDK_ERRLOG("Failed to remove referral.\n");
1183 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1184 						 "Unable to remove a referral.");
1185 		nvmf_rpc_referral_ctx_free(&ctx);
1186 		return;
1187 	}
1188 
1189 	nvmf_rpc_referral_ctx_free(&ctx);
1190 
1191 	spdk_jsonrpc_send_bool_response(request, true);
1192 }
1193 
1194 SPDK_RPC_REGISTER("nvmf_discovery_remove_referral", rpc_nvmf_remove_referral,
1195 		  SPDK_RPC_RUNTIME);
1196 
1197 static void
1198 dump_nvmf_referral(struct spdk_json_write_ctx *w,
1199 		   struct spdk_nvmf_referral *referral)
1200 {
1201 	spdk_json_write_object_begin(w);
1202 
1203 	spdk_json_write_named_object_begin(w, "address");
1204 	nvmf_transport_listen_dump_trid(&referral->trid, w);
1205 	spdk_json_write_object_end(w);
1206 	spdk_json_write_named_bool(w, "secure_channel",
1207 				   referral->entry.treq.secure_channel == SPDK_NVMF_TREQ_SECURE_CHANNEL_REQUIRED);
1208 	spdk_json_write_named_string(w, "subnqn", referral->trid.subnqn);
1209 
1210 	spdk_json_write_object_end(w);
1211 }
1212 
1213 struct rpc_get_referrals_ctx {
1214 	char *tgt_name;
1215 };
1216 
1217 static const struct spdk_json_object_decoder rpc_get_referrals_decoders[] = {
1218 	{"tgt_name", offsetof(struct rpc_get_referrals_ctx, tgt_name), spdk_json_decode_string, true},
1219 };
1220 
1221 static void
1222 free_rpc_get_referrals_ctx(struct rpc_get_referrals_ctx *ctx)
1223 {
1224 	free(ctx->tgt_name);
1225 	free(ctx);
1226 }
1227 
1228 static void
1229 rpc_nvmf_get_referrals(struct spdk_jsonrpc_request *request,
1230 		       const struct spdk_json_val *params)
1231 {
1232 	struct rpc_get_referrals_ctx *ctx;
1233 	struct spdk_nvmf_tgt *tgt;
1234 	struct spdk_json_write_ctx *w;
1235 	struct spdk_nvmf_referral *referral;
1236 
1237 	ctx = calloc(1, sizeof(*ctx));
1238 	if (!ctx) {
1239 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1240 						 "Out of memory");
1241 		return;
1242 	}
1243 
1244 	if (params) {
1245 		if (spdk_json_decode_object(params, rpc_get_referrals_decoders,
1246 					    SPDK_COUNTOF(rpc_get_referrals_decoders),
1247 					    ctx)) {
1248 			SPDK_ERRLOG("spdk_json_decode_object failed\n");
1249 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1250 							 "Invalid parameters");
1251 			free_rpc_get_referrals_ctx(ctx);
1252 			return;
1253 		}
1254 	}
1255 
1256 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1257 	if (!tgt) {
1258 		SPDK_ERRLOG("Unable to find a target object.\n");
1259 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1260 						 "Unable to find a target");
1261 		free_rpc_get_referrals_ctx(ctx);
1262 		return;
1263 	}
1264 
1265 	w = spdk_jsonrpc_begin_result(request);
1266 
1267 	spdk_json_write_array_begin(w);
1268 
1269 	TAILQ_FOREACH(referral, &tgt->referrals, link) {
1270 		dump_nvmf_referral(w, referral);
1271 	}
1272 
1273 	spdk_json_write_array_end(w);
1274 
1275 	spdk_jsonrpc_end_result(request, w);
1276 
1277 	free_rpc_get_referrals_ctx(ctx);
1278 }
1279 SPDK_RPC_REGISTER("nvmf_discovery_get_referrals", rpc_nvmf_get_referrals,
1280 		  SPDK_RPC_RUNTIME);
1281 
1282 static const struct spdk_json_object_decoder nvmf_rpc_set_ana_state_decoder[] = {
1283 	{"nqn", offsetof(struct nvmf_rpc_listener_ctx, nqn), spdk_json_decode_string},
1284 	{"listen_address", offsetof(struct nvmf_rpc_listener_ctx, address), decode_rpc_listen_address},
1285 	{"ana_state", offsetof(struct nvmf_rpc_listener_ctx, ana_state_str), spdk_json_decode_string},
1286 	{"tgt_name", offsetof(struct nvmf_rpc_listener_ctx, tgt_name), spdk_json_decode_string, true},
1287 	{"anagrpid", offsetof(struct nvmf_rpc_listener_ctx, anagrpid), spdk_json_decode_uint32, true},
1288 };
1289 
1290 static int
1291 rpc_ana_state_parse(const char *str, enum spdk_nvme_ana_state *ana_state)
1292 {
1293 	if (ana_state == NULL || str == NULL) {
1294 		return -EINVAL;
1295 	}
1296 
1297 	if (strcasecmp(str, "optimized") == 0) {
1298 		*ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE;
1299 	} else if (strcasecmp(str, "non_optimized") == 0) {
1300 		*ana_state = SPDK_NVME_ANA_NON_OPTIMIZED_STATE;
1301 	} else if (strcasecmp(str, "inaccessible") == 0) {
1302 		*ana_state = SPDK_NVME_ANA_INACCESSIBLE_STATE;
1303 	} else {
1304 		return -ENOENT;
1305 	}
1306 
1307 	return 0;
1308 }
1309 
1310 static void
1311 rpc_nvmf_subsystem_listener_set_ana_state(struct spdk_jsonrpc_request *request,
1312 		const struct spdk_json_val *params)
1313 {
1314 	struct nvmf_rpc_listener_ctx *ctx;
1315 	struct spdk_nvmf_subsystem *subsystem;
1316 	struct spdk_nvmf_tgt *tgt;
1317 
1318 	ctx = calloc(1, sizeof(*ctx));
1319 	if (!ctx) {
1320 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1321 						 "Out of memory");
1322 		return;
1323 	}
1324 
1325 	ctx->request = request;
1326 
1327 	if (spdk_json_decode_object(params, nvmf_rpc_set_ana_state_decoder,
1328 				    SPDK_COUNTOF(nvmf_rpc_set_ana_state_decoder),
1329 				    ctx)) {
1330 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1331 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1332 						 "Invalid parameters");
1333 		nvmf_rpc_listener_ctx_free(ctx);
1334 		return;
1335 	}
1336 
1337 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1338 	if (!tgt) {
1339 		SPDK_ERRLOG("Unable to find a target object.\n");
1340 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1341 						 "Unable to find a target.\n");
1342 		nvmf_rpc_listener_ctx_free(ctx);
1343 		return;
1344 	}
1345 
1346 	ctx->tgt = tgt;
1347 
1348 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1349 	if (!subsystem) {
1350 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1351 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1352 						     "Unable to find subsystem with NQN %s",
1353 						     ctx->nqn);
1354 		nvmf_rpc_listener_ctx_free(ctx);
1355 		return;
1356 	}
1357 
1358 	ctx->subsystem = subsystem;
1359 
1360 	if (rpc_listen_address_to_trid(&ctx->address, &ctx->trid)) {
1361 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1362 						 "Invalid parameters");
1363 		nvmf_rpc_listener_ctx_free(ctx);
1364 		return;
1365 	}
1366 
1367 	if (rpc_ana_state_parse(ctx->ana_state_str, &ctx->ana_state)) {
1368 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1369 						 "Invalid parameters");
1370 		nvmf_rpc_listener_ctx_free(ctx);
1371 		return;
1372 	}
1373 
1374 	ctx->op = NVMF_RPC_LISTEN_SET_ANA_STATE;
1375 
1376 	if (spdk_nvmf_subsystem_pause(subsystem, 0, nvmf_rpc_listen_paused, ctx)) {
1377 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1378 						 "Internal error");
1379 		nvmf_rpc_listener_ctx_free(ctx);
1380 	}
1381 }
1382 SPDK_RPC_REGISTER("nvmf_subsystem_listener_set_ana_state",
1383 		  rpc_nvmf_subsystem_listener_set_ana_state, SPDK_RPC_RUNTIME);
1384 
1385 struct nvmf_rpc_ns_params {
1386 	char *bdev_name;
1387 	char *ptpl_file;
1388 	uint32_t nsid;
1389 	char nguid[16];
1390 	char eui64[8];
1391 	struct spdk_uuid uuid;
1392 	uint32_t anagrpid;
1393 	bool no_auto_visible;
1394 };
1395 
1396 static const struct spdk_json_object_decoder rpc_ns_params_decoders[] = {
1397 	{"nsid", offsetof(struct nvmf_rpc_ns_params, nsid), spdk_json_decode_uint32, true},
1398 	{"bdev_name", offsetof(struct nvmf_rpc_ns_params, bdev_name), spdk_json_decode_string},
1399 	{"ptpl_file", offsetof(struct nvmf_rpc_ns_params, ptpl_file), spdk_json_decode_string, true},
1400 	{"nguid", offsetof(struct nvmf_rpc_ns_params, nguid), decode_ns_nguid, true},
1401 	{"eui64", offsetof(struct nvmf_rpc_ns_params, eui64), decode_ns_eui64, true},
1402 	{"uuid", offsetof(struct nvmf_rpc_ns_params, uuid), spdk_json_decode_uuid, true},
1403 	{"anagrpid", offsetof(struct nvmf_rpc_ns_params, anagrpid), spdk_json_decode_uint32, true},
1404 	{"no_auto_visible", offsetof(struct nvmf_rpc_ns_params, no_auto_visible), spdk_json_decode_bool, true},
1405 };
1406 
1407 static int
1408 decode_rpc_ns_params(const struct spdk_json_val *val, void *out)
1409 {
1410 	struct nvmf_rpc_ns_params *ns_params = out;
1411 
1412 	return spdk_json_decode_object(val, rpc_ns_params_decoders,
1413 				       SPDK_COUNTOF(rpc_ns_params_decoders),
1414 				       ns_params);
1415 }
1416 
1417 struct nvmf_rpc_ns_ctx {
1418 	char *nqn;
1419 	char *tgt_name;
1420 	struct nvmf_rpc_ns_params ns_params;
1421 
1422 	struct spdk_jsonrpc_request *request;
1423 	const struct spdk_json_val *params;
1424 	bool response_sent;
1425 };
1426 
1427 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_ns_decoder[] = {
1428 	{"nqn", offsetof(struct nvmf_rpc_ns_ctx, nqn), spdk_json_decode_string},
1429 	{"namespace", offsetof(struct nvmf_rpc_ns_ctx, ns_params), decode_rpc_ns_params},
1430 	{"tgt_name", offsetof(struct nvmf_rpc_ns_ctx, tgt_name), spdk_json_decode_string, true},
1431 };
1432 
1433 static void
1434 nvmf_rpc_ns_ctx_free(struct nvmf_rpc_ns_ctx *ctx)
1435 {
1436 	free(ctx->nqn);
1437 	free(ctx->tgt_name);
1438 	free(ctx->ns_params.bdev_name);
1439 	free(ctx->ns_params.ptpl_file);
1440 	free(ctx);
1441 }
1442 
1443 static void
1444 nvmf_rpc_ns_failback_resumed(struct spdk_nvmf_subsystem *subsystem,
1445 			     void *cb_arg, int status)
1446 {
1447 	struct nvmf_rpc_ns_ctx *ctx = cb_arg;
1448 	struct spdk_jsonrpc_request *request = ctx->request;
1449 
1450 	if (status) {
1451 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1452 						 "Unable to add ns, subsystem in invalid state");
1453 	} else {
1454 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1455 						 "Unable to add ns, subsystem in active state");
1456 	}
1457 
1458 	nvmf_rpc_ns_ctx_free(ctx);
1459 }
1460 
1461 static void
1462 nvmf_rpc_ns_resumed(struct spdk_nvmf_subsystem *subsystem,
1463 		    void *cb_arg, int status)
1464 {
1465 	struct nvmf_rpc_ns_ctx *ctx = cb_arg;
1466 	struct spdk_jsonrpc_request *request = ctx->request;
1467 	uint32_t nsid = ctx->ns_params.nsid;
1468 	bool response_sent = ctx->response_sent;
1469 	struct spdk_json_write_ctx *w;
1470 	int rc;
1471 
1472 	/* The case where the call to add the namespace was successful, but the subsystem couldn't be resumed. */
1473 	if (status && !ctx->response_sent) {
1474 		rc = spdk_nvmf_subsystem_remove_ns(subsystem, nsid);
1475 		if (rc != 0) {
1476 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1477 							 "Unable to add ns, subsystem in invalid state");
1478 			nvmf_rpc_ns_ctx_free(ctx);
1479 			return;
1480 		}
1481 
1482 		rc = spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_ns_failback_resumed, ctx);
1483 		if (rc != 0) {
1484 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1485 			nvmf_rpc_ns_ctx_free(ctx);
1486 			return;
1487 		}
1488 
1489 		return;
1490 	}
1491 
1492 	nvmf_rpc_ns_ctx_free(ctx);
1493 
1494 	if (response_sent) {
1495 		return;
1496 	}
1497 
1498 	w = spdk_jsonrpc_begin_result(request);
1499 	spdk_json_write_uint32(w, nsid);
1500 	spdk_jsonrpc_end_result(request, w);
1501 }
1502 
1503 static void
1504 nvmf_rpc_ns_paused(struct spdk_nvmf_subsystem *subsystem,
1505 		   void *cb_arg, int status)
1506 {
1507 	struct nvmf_rpc_ns_ctx *ctx = cb_arg;
1508 	struct spdk_nvmf_ns_opts ns_opts;
1509 
1510 	spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts));
1511 	ns_opts.nsid = ctx->ns_params.nsid;
1512 	ns_opts.transport_specific = ctx->params;
1513 
1514 	SPDK_STATIC_ASSERT(sizeof(ns_opts.nguid) == sizeof(ctx->ns_params.nguid), "size mismatch");
1515 	memcpy(ns_opts.nguid, ctx->ns_params.nguid, sizeof(ns_opts.nguid));
1516 
1517 	SPDK_STATIC_ASSERT(sizeof(ns_opts.eui64) == sizeof(ctx->ns_params.eui64), "size mismatch");
1518 	memcpy(ns_opts.eui64, ctx->ns_params.eui64, sizeof(ns_opts.eui64));
1519 
1520 	if (!spdk_uuid_is_null(&ctx->ns_params.uuid)) {
1521 		ns_opts.uuid = ctx->ns_params.uuid;
1522 	}
1523 
1524 	ns_opts.anagrpid = ctx->ns_params.anagrpid;
1525 	ns_opts.no_auto_visible = ctx->ns_params.no_auto_visible;
1526 
1527 	ctx->ns_params.nsid = spdk_nvmf_subsystem_add_ns_ext(subsystem, ctx->ns_params.bdev_name,
1528 			      &ns_opts, sizeof(ns_opts),
1529 			      ctx->ns_params.ptpl_file);
1530 	if (ctx->ns_params.nsid == 0) {
1531 		SPDK_ERRLOG("Unable to add namespace\n");
1532 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1533 						 "Invalid parameters");
1534 		ctx->response_sent = true;
1535 		goto resume;
1536 	}
1537 
1538 resume:
1539 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_ns_resumed, ctx)) {
1540 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1541 		nvmf_rpc_ns_ctx_free(ctx);
1542 	}
1543 }
1544 
1545 static void
1546 rpc_nvmf_subsystem_add_ns(struct spdk_jsonrpc_request *request,
1547 			  const struct spdk_json_val *params)
1548 {
1549 	struct nvmf_rpc_ns_ctx *ctx;
1550 	struct spdk_nvmf_subsystem *subsystem;
1551 	struct spdk_nvmf_tgt *tgt;
1552 	int rc;
1553 
1554 	ctx = calloc(1, sizeof(*ctx));
1555 	if (!ctx) {
1556 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1557 		return;
1558 	}
1559 
1560 	if (spdk_json_decode_object_relaxed(params, nvmf_rpc_subsystem_ns_decoder,
1561 					    SPDK_COUNTOF(nvmf_rpc_subsystem_ns_decoder), ctx)) {
1562 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1563 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1564 		nvmf_rpc_ns_ctx_free(ctx);
1565 		return;
1566 	}
1567 
1568 	ctx->request = request;
1569 	ctx->params = params;
1570 	ctx->response_sent = false;
1571 
1572 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1573 	if (!tgt) {
1574 		SPDK_ERRLOG("Unable to find a target object.\n");
1575 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1576 						 "Unable to find a target.");
1577 		nvmf_rpc_ns_ctx_free(ctx);
1578 		return;
1579 	}
1580 
1581 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1582 	if (!subsystem) {
1583 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1584 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1585 		nvmf_rpc_ns_ctx_free(ctx);
1586 		return;
1587 	}
1588 
1589 	rc = spdk_nvmf_subsystem_pause(subsystem, ctx->ns_params.nsid, nvmf_rpc_ns_paused, ctx);
1590 	if (rc != 0) {
1591 		if (rc == -EBUSY) {
1592 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1593 							 "subsystem busy, retry later.\n");
1594 		} else {
1595 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1596 		}
1597 		nvmf_rpc_ns_ctx_free(ctx);
1598 	}
1599 }
1600 SPDK_RPC_REGISTER("nvmf_subsystem_add_ns", rpc_nvmf_subsystem_add_ns, SPDK_RPC_RUNTIME)
1601 
1602 struct nvmf_rpc_remove_ns_ctx {
1603 	char *nqn;
1604 	char *tgt_name;
1605 	uint32_t nsid;
1606 
1607 	struct spdk_jsonrpc_request *request;
1608 	bool response_sent;
1609 };
1610 
1611 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_remove_ns_decoder[] = {
1612 	{"nqn", offsetof(struct nvmf_rpc_remove_ns_ctx, nqn), spdk_json_decode_string},
1613 	{"nsid", offsetof(struct nvmf_rpc_remove_ns_ctx, nsid), spdk_json_decode_uint32},
1614 	{"tgt_name", offsetof(struct nvmf_rpc_remove_ns_ctx, tgt_name), spdk_json_decode_string, true},
1615 };
1616 
1617 static void
1618 nvmf_rpc_remove_ns_ctx_free(struct nvmf_rpc_remove_ns_ctx *ctx)
1619 {
1620 	free(ctx->nqn);
1621 	free(ctx->tgt_name);
1622 	free(ctx);
1623 }
1624 
1625 static void
1626 nvmf_rpc_remove_ns_resumed(struct spdk_nvmf_subsystem *subsystem,
1627 			   void *cb_arg, int status)
1628 {
1629 	struct nvmf_rpc_remove_ns_ctx *ctx = cb_arg;
1630 	struct spdk_jsonrpc_request *request = ctx->request;
1631 	bool response_sent = ctx->response_sent;
1632 
1633 	nvmf_rpc_remove_ns_ctx_free(ctx);
1634 
1635 	if (response_sent) {
1636 		return;
1637 	}
1638 
1639 	spdk_jsonrpc_send_bool_response(request, true);
1640 }
1641 
1642 static void
1643 nvmf_rpc_remove_ns_paused(struct spdk_nvmf_subsystem *subsystem,
1644 			  void *cb_arg, int status)
1645 {
1646 	struct nvmf_rpc_remove_ns_ctx *ctx = cb_arg;
1647 	int ret;
1648 
1649 	ret = spdk_nvmf_subsystem_remove_ns(subsystem, ctx->nsid);
1650 	if (ret < 0) {
1651 		SPDK_ERRLOG("Unable to remove namespace ID %u\n", ctx->nsid);
1652 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1653 						 "Invalid parameters");
1654 		ctx->response_sent = true;
1655 	}
1656 
1657 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_remove_ns_resumed, ctx)) {
1658 		if (!ctx->response_sent) {
1659 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1660 		}
1661 		nvmf_rpc_remove_ns_ctx_free(ctx);
1662 	}
1663 }
1664 
1665 static void
1666 rpc_nvmf_subsystem_remove_ns(struct spdk_jsonrpc_request *request,
1667 			     const struct spdk_json_val *params)
1668 {
1669 	struct nvmf_rpc_remove_ns_ctx *ctx;
1670 	struct spdk_nvmf_subsystem *subsystem;
1671 	struct spdk_nvmf_tgt *tgt;
1672 	int rc;
1673 
1674 	ctx = calloc(1, sizeof(*ctx));
1675 	if (!ctx) {
1676 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1677 		return;
1678 	}
1679 
1680 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_remove_ns_decoder,
1681 				    SPDK_COUNTOF(nvmf_rpc_subsystem_remove_ns_decoder),
1682 				    ctx)) {
1683 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1684 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1685 		nvmf_rpc_remove_ns_ctx_free(ctx);
1686 		return;
1687 	}
1688 
1689 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1690 	if (!tgt) {
1691 		SPDK_ERRLOG("Unable to find a target object.\n");
1692 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1693 						 "Unable to find a target.");
1694 		nvmf_rpc_remove_ns_ctx_free(ctx);
1695 		return;
1696 	}
1697 
1698 	ctx->request = request;
1699 	ctx->response_sent = false;
1700 
1701 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1702 	if (!subsystem) {
1703 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1704 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1705 		nvmf_rpc_remove_ns_ctx_free(ctx);
1706 		return;
1707 	}
1708 
1709 	rc = spdk_nvmf_subsystem_pause(subsystem, ctx->nsid, nvmf_rpc_remove_ns_paused, ctx);
1710 	if (rc != 0) {
1711 		if (rc == -EBUSY) {
1712 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1713 							 "subsystem busy, retry later.\n");
1714 		} else {
1715 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1716 		}
1717 		nvmf_rpc_remove_ns_ctx_free(ctx);
1718 	}
1719 }
1720 SPDK_RPC_REGISTER("nvmf_subsystem_remove_ns", rpc_nvmf_subsystem_remove_ns, SPDK_RPC_RUNTIME)
1721 
1722 struct nvmf_rpc_ns_visible_ctx {
1723 	struct spdk_jsonrpc_request *request;
1724 	char *nqn;
1725 	uint32_t nsid;
1726 	char *host;
1727 	char *tgt_name;
1728 	bool visible;
1729 	bool response_sent;
1730 };
1731 
1732 static const struct spdk_json_object_decoder nvmf_rpc_ns_visible_decoder[] = {
1733 	{"nqn", offsetof(struct nvmf_rpc_ns_visible_ctx, nqn), spdk_json_decode_string},
1734 	{"nsid", offsetof(struct nvmf_rpc_ns_visible_ctx, nsid), spdk_json_decode_uint32},
1735 	{"host", offsetof(struct nvmf_rpc_ns_visible_ctx, host), spdk_json_decode_string},
1736 	{"tgt_name", offsetof(struct nvmf_rpc_ns_visible_ctx, tgt_name), spdk_json_decode_string, true},
1737 };
1738 
1739 static void
1740 nvmf_rpc_ns_visible_ctx_free(struct nvmf_rpc_ns_visible_ctx *ctx)
1741 {
1742 	free(ctx->nqn);
1743 	free(ctx->host);
1744 	free(ctx->tgt_name);
1745 	free(ctx);
1746 }
1747 
1748 static void
1749 nvmf_rpc_ns_visible_resumed(struct spdk_nvmf_subsystem *subsystem,
1750 			    void *cb_arg, int status)
1751 {
1752 	struct nvmf_rpc_ns_visible_ctx *ctx = cb_arg;
1753 	struct spdk_jsonrpc_request *request = ctx->request;
1754 	bool response_sent = ctx->response_sent;
1755 
1756 	nvmf_rpc_ns_visible_ctx_free(ctx);
1757 
1758 	if (!response_sent) {
1759 		spdk_jsonrpc_send_bool_response(request, true);
1760 	}
1761 }
1762 
1763 static void
1764 nvmf_rpc_ns_visible_paused(struct spdk_nvmf_subsystem *subsystem,
1765 			   void *cb_arg, int status)
1766 {
1767 	struct nvmf_rpc_ns_visible_ctx *ctx = cb_arg;
1768 	int ret;
1769 
1770 	if (ctx->visible) {
1771 		ret = spdk_nvmf_ns_add_host(subsystem, ctx->nsid, ctx->host, 0);
1772 	} else {
1773 		ret = spdk_nvmf_ns_remove_host(subsystem, ctx->nsid, ctx->host, 0);
1774 	}
1775 	if (ret < 0) {
1776 		SPDK_ERRLOG("Unable to add/remove %s to namespace ID %u\n", ctx->host, ctx->nsid);
1777 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1778 						 "Invalid parameters");
1779 		ctx->response_sent = true;
1780 	}
1781 
1782 	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_ns_visible_resumed, ctx)) {
1783 		if (!ctx->response_sent) {
1784 			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1785 		}
1786 		nvmf_rpc_ns_visible_ctx_free(ctx);
1787 	}
1788 }
1789 
1790 static void
1791 nvmf_rpc_ns_visible(struct spdk_jsonrpc_request *request,
1792 		    const struct spdk_json_val *params,
1793 		    bool visible)
1794 {
1795 	struct nvmf_rpc_ns_visible_ctx *ctx;
1796 	struct spdk_nvmf_subsystem *subsystem;
1797 	struct spdk_nvmf_tgt *tgt;
1798 	int rc;
1799 
1800 	ctx = calloc(1, sizeof(*ctx));
1801 	if (!ctx) {
1802 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1803 		return;
1804 	}
1805 	ctx->visible = visible;
1806 
1807 	if (spdk_json_decode_object(params, nvmf_rpc_ns_visible_decoder,
1808 				    SPDK_COUNTOF(nvmf_rpc_ns_visible_decoder),
1809 				    ctx)) {
1810 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1811 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1812 		nvmf_rpc_ns_visible_ctx_free(ctx);
1813 		return;
1814 	}
1815 	ctx->request = request;
1816 
1817 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1818 	if (!tgt) {
1819 		SPDK_ERRLOG("Unable to find a target object.\n");
1820 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1821 						 "Unable to find a target.");
1822 		nvmf_rpc_ns_visible_ctx_free(ctx);
1823 		return;
1824 	}
1825 
1826 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
1827 	if (!subsystem) {
1828 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
1829 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1830 		nvmf_rpc_ns_visible_ctx_free(ctx);
1831 		return;
1832 	}
1833 
1834 	rc = spdk_nvmf_subsystem_pause(subsystem, ctx->nsid, nvmf_rpc_ns_visible_paused, ctx);
1835 	if (rc != 0) {
1836 		if (rc == -EBUSY) {
1837 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1838 							 "subsystem busy, retry later.\n");
1839 		} else {
1840 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1841 		}
1842 		nvmf_rpc_ns_visible_ctx_free(ctx);
1843 	}
1844 }
1845 
1846 static void
1847 rpc_nvmf_ns_add_host(struct spdk_jsonrpc_request *request,
1848 		     const struct spdk_json_val *params)
1849 {
1850 	nvmf_rpc_ns_visible(request, params, true);
1851 }
1852 SPDK_RPC_REGISTER("nvmf_ns_add_host", rpc_nvmf_ns_add_host, SPDK_RPC_RUNTIME)
1853 
1854 static void
1855 rpc_nvmf_ns_remove_host(struct spdk_jsonrpc_request *request,
1856 			const struct spdk_json_val *params)
1857 {
1858 	nvmf_rpc_ns_visible(request, params, false);
1859 }
1860 SPDK_RPC_REGISTER("nvmf_ns_remove_host", rpc_nvmf_ns_remove_host, SPDK_RPC_RUNTIME)
1861 
1862 struct nvmf_rpc_host_ctx {
1863 	struct spdk_jsonrpc_request *request;
1864 	char *nqn;
1865 	char *host;
1866 	char *tgt_name;
1867 	char *dhchap_key;
1868 	bool allow_any_host;
1869 };
1870 
1871 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_host_decoder[] = {
1872 	{"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string},
1873 	{"host", offsetof(struct nvmf_rpc_host_ctx, host), spdk_json_decode_string},
1874 	{"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true},
1875 	{"dhchap_key", offsetof(struct nvmf_rpc_host_ctx, dhchap_key), spdk_json_decode_string, true},
1876 };
1877 
1878 static void
1879 nvmf_rpc_host_ctx_free(struct nvmf_rpc_host_ctx *ctx)
1880 {
1881 	free(ctx->nqn);
1882 	free(ctx->host);
1883 	free(ctx->tgt_name);
1884 	free(ctx->dhchap_key);
1885 }
1886 
1887 static void
1888 rpc_nvmf_subsystem_add_host(struct spdk_jsonrpc_request *request,
1889 			    const struct spdk_json_val *params)
1890 {
1891 	struct nvmf_rpc_host_ctx ctx = {};
1892 	struct spdk_nvmf_subsystem *subsystem;
1893 	struct spdk_nvmf_host_opts opts = {};
1894 	struct spdk_nvmf_tgt *tgt;
1895 	struct spdk_key *key = NULL;
1896 	int rc;
1897 
1898 	if (spdk_json_decode_object_relaxed(params, nvmf_rpc_subsystem_host_decoder,
1899 					    SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder),
1900 					    &ctx)) {
1901 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1902 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1903 		nvmf_rpc_host_ctx_free(&ctx);
1904 		return;
1905 	}
1906 
1907 	tgt = spdk_nvmf_get_tgt(ctx.tgt_name);
1908 	if (!tgt) {
1909 		SPDK_ERRLOG("Unable to find a target object.\n");
1910 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1911 						 "Unable to find a target.");
1912 		nvmf_rpc_host_ctx_free(&ctx);
1913 		return;
1914 	}
1915 
1916 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx.nqn);
1917 	if (!subsystem) {
1918 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx.nqn);
1919 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1920 		nvmf_rpc_host_ctx_free(&ctx);
1921 		return;
1922 	}
1923 
1924 	if (ctx.dhchap_key != NULL) {
1925 		key = spdk_keyring_get_key(ctx.dhchap_key);
1926 		if (key == NULL) {
1927 			SPDK_ERRLOG("Unable to find DH-HMAC-CHAP key: %s\n", ctx.dhchap_key);
1928 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1929 							 "Invalid parameters");
1930 			nvmf_rpc_host_ctx_free(&ctx);
1931 			return;
1932 		}
1933 	}
1934 
1935 	opts.size = SPDK_SIZEOF(&opts, dhchap_key);
1936 	opts.params = params;
1937 	opts.dhchap_key = key;
1938 	rc = spdk_nvmf_subsystem_add_host_ext(subsystem, ctx.host, &opts);
1939 	if (rc != 0) {
1940 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
1941 		nvmf_rpc_host_ctx_free(&ctx);
1942 		spdk_keyring_put_key(key);
1943 		return;
1944 	}
1945 
1946 	spdk_keyring_put_key(key);
1947 	spdk_jsonrpc_send_bool_response(request, true);
1948 	nvmf_rpc_host_ctx_free(&ctx);
1949 }
1950 SPDK_RPC_REGISTER("nvmf_subsystem_add_host", rpc_nvmf_subsystem_add_host, SPDK_RPC_RUNTIME)
1951 
1952 static void
1953 rpc_nvmf_subsystem_remove_host_done(void *_ctx, int status)
1954 {
1955 	struct nvmf_rpc_host_ctx *ctx = _ctx;
1956 
1957 	spdk_jsonrpc_send_bool_response(ctx->request, true);
1958 	nvmf_rpc_host_ctx_free(ctx);
1959 	free(ctx);
1960 }
1961 
1962 static void
1963 rpc_nvmf_subsystem_remove_host(struct spdk_jsonrpc_request *request,
1964 			       const struct spdk_json_val *params)
1965 {
1966 	struct nvmf_rpc_host_ctx *ctx;
1967 	struct spdk_nvmf_subsystem *subsystem;
1968 	struct spdk_nvmf_tgt *tgt;
1969 	int rc;
1970 
1971 	ctx = calloc(1, sizeof(*ctx));
1972 	if (ctx == NULL) {
1973 		SPDK_ERRLOG("Unable to allocate context to perform RPC\n");
1974 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
1975 		return;
1976 	}
1977 
1978 	ctx->request = request;
1979 
1980 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_host_decoder,
1981 				    SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder),
1982 				    ctx)) {
1983 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
1984 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
1985 		nvmf_rpc_host_ctx_free(ctx);
1986 		free(ctx);
1987 		return;
1988 	}
1989 
1990 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
1991 	if (!tgt) {
1992 		SPDK_ERRLOG("Unable to find a target object.\n");
1993 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1994 						 "Unable to find a target.");
1995 		nvmf_rpc_host_ctx_free(ctx);
1996 		free(ctx);
1997 		return;
1998 	}
1999 
2000 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
2001 	if (!subsystem) {
2002 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
2003 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2004 		nvmf_rpc_host_ctx_free(ctx);
2005 		free(ctx);
2006 		return;
2007 	}
2008 
2009 	rc = spdk_nvmf_subsystem_remove_host(subsystem, ctx->host);
2010 	if (rc != 0) {
2011 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
2012 		nvmf_rpc_host_ctx_free(ctx);
2013 		free(ctx);
2014 		return;
2015 	}
2016 
2017 	rc = spdk_nvmf_subsystem_disconnect_host(subsystem, ctx->host,
2018 			rpc_nvmf_subsystem_remove_host_done,
2019 			ctx);
2020 	if (rc != 0) {
2021 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
2022 		nvmf_rpc_host_ctx_free(ctx);
2023 		free(ctx);
2024 		return;
2025 	}
2026 }
2027 SPDK_RPC_REGISTER("nvmf_subsystem_remove_host", rpc_nvmf_subsystem_remove_host,
2028 		  SPDK_RPC_RUNTIME)
2029 
2030 
2031 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_any_host_decoder[] = {
2032 	{"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string},
2033 	{"allow_any_host", offsetof(struct nvmf_rpc_host_ctx, allow_any_host), spdk_json_decode_bool},
2034 	{"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true},
2035 };
2036 
2037 static void
2038 rpc_nvmf_subsystem_allow_any_host(struct spdk_jsonrpc_request *request,
2039 				  const struct spdk_json_val *params)
2040 {
2041 	struct nvmf_rpc_host_ctx ctx = {};
2042 	struct spdk_nvmf_subsystem *subsystem;
2043 	struct spdk_nvmf_tgt *tgt;
2044 	int rc;
2045 
2046 	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_any_host_decoder,
2047 				    SPDK_COUNTOF(nvmf_rpc_subsystem_any_host_decoder),
2048 				    &ctx)) {
2049 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
2050 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2051 		nvmf_rpc_host_ctx_free(&ctx);
2052 		return;
2053 	}
2054 
2055 	tgt = spdk_nvmf_get_tgt(ctx.tgt_name);
2056 	if (!tgt) {
2057 		SPDK_ERRLOG("Unable to find a target object.\n");
2058 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2059 						 "Unable to find a target.");
2060 		nvmf_rpc_host_ctx_free(&ctx);
2061 		return;
2062 	}
2063 
2064 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx.nqn);
2065 	if (!subsystem) {
2066 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx.nqn);
2067 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2068 		nvmf_rpc_host_ctx_free(&ctx);
2069 		return;
2070 	}
2071 
2072 	rc = spdk_nvmf_subsystem_set_allow_any_host(subsystem, ctx.allow_any_host);
2073 	if (rc != 0) {
2074 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
2075 		nvmf_rpc_host_ctx_free(&ctx);
2076 		return;
2077 	}
2078 
2079 	spdk_jsonrpc_send_bool_response(request, true);
2080 	nvmf_rpc_host_ctx_free(&ctx);
2081 }
2082 SPDK_RPC_REGISTER("nvmf_subsystem_allow_any_host", rpc_nvmf_subsystem_allow_any_host,
2083 		  SPDK_RPC_RUNTIME)
2084 
2085 struct nvmf_rpc_target_ctx {
2086 	char *name;
2087 	uint32_t max_subsystems;
2088 	char *discovery_filter;
2089 };
2090 
2091 static int
2092 decode_discovery_filter(const struct spdk_json_val *val, void *out)
2093 {
2094 	enum spdk_nvmf_tgt_discovery_filter *_filter = (enum spdk_nvmf_tgt_discovery_filter *)out;
2095 	enum spdk_nvmf_tgt_discovery_filter filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_ANY;
2096 	char *tokens = spdk_json_strdup(val);
2097 	char *tok;
2098 	int rc = -EINVAL;
2099 	bool all_specified = false;
2100 
2101 	if (!tokens) {
2102 		return -ENOMEM;
2103 	}
2104 
2105 	tok = strtok(tokens, ",");
2106 	while (tok) {
2107 		if (strncmp(tok, "match_any", 9) == 0) {
2108 			if (filter != SPDK_NVMF_TGT_DISCOVERY_MATCH_ANY) {
2109 				goto out;
2110 			}
2111 			filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_ANY;
2112 			all_specified = true;
2113 		} else {
2114 			if (all_specified) {
2115 				goto out;
2116 			}
2117 			if (strncmp(tok, "transport", 9) == 0) {
2118 				filter |= SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE;
2119 			} else if (strncmp(tok, "address", 7) == 0) {
2120 				filter |= SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS;
2121 			} else if (strncmp(tok, "svcid", 5) == 0) {
2122 				filter |= SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID;
2123 			} else {
2124 				SPDK_ERRLOG("Invalid value %s\n", tok);
2125 				goto out;
2126 			}
2127 		}
2128 
2129 		tok = strtok(NULL, ",");
2130 	}
2131 
2132 	rc = 0;
2133 	*_filter = filter;
2134 
2135 out:
2136 	free(tokens);
2137 
2138 	return rc;
2139 }
2140 
2141 static const struct spdk_json_object_decoder nvmf_rpc_create_target_decoder[] = {
2142 	{"name", offsetof(struct nvmf_rpc_target_ctx, name), spdk_json_decode_string},
2143 	{"max_subsystems", offsetof(struct nvmf_rpc_target_ctx, max_subsystems), spdk_json_decode_uint32, true},
2144 	{"discovery_filter", offsetof(struct nvmf_rpc_target_ctx, discovery_filter), decode_discovery_filter, true}
2145 };
2146 
2147 static void
2148 rpc_nvmf_create_target(struct spdk_jsonrpc_request *request,
2149 		       const struct spdk_json_val *params)
2150 {
2151 	struct spdk_nvmf_target_opts	opts;
2152 	struct nvmf_rpc_target_ctx	ctx = {0};
2153 	struct spdk_nvmf_tgt		*tgt;
2154 	struct spdk_json_write_ctx	*w;
2155 
2156 	/* Decode parameters the first time to get the transport type */
2157 	if (spdk_json_decode_object(params, nvmf_rpc_create_target_decoder,
2158 				    SPDK_COUNTOF(nvmf_rpc_create_target_decoder),
2159 				    &ctx)) {
2160 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
2161 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2162 		goto out;
2163 	}
2164 
2165 	snprintf(opts.name, NVMF_TGT_NAME_MAX_LENGTH, "%s", ctx.name);
2166 	opts.max_subsystems = ctx.max_subsystems;
2167 
2168 	if (spdk_nvmf_get_tgt(opts.name) != NULL) {
2169 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
2170 						 "Target already exists.");
2171 		goto out;
2172 	}
2173 
2174 	tgt = spdk_nvmf_tgt_create(&opts);
2175 
2176 	if (tgt == NULL) {
2177 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2178 						 "Unable to create the requested target.");
2179 		goto out;
2180 	}
2181 
2182 	w = spdk_jsonrpc_begin_result(request);
2183 	spdk_json_write_string(w, spdk_nvmf_tgt_get_name(tgt));
2184 	spdk_jsonrpc_end_result(request, w);
2185 out:
2186 	free(ctx.name);
2187 	free(ctx.discovery_filter);
2188 }
2189 /* private */ SPDK_RPC_REGISTER("nvmf_create_target", rpc_nvmf_create_target, SPDK_RPC_RUNTIME);
2190 
2191 static const struct spdk_json_object_decoder nvmf_rpc_destroy_target_decoder[] = {
2192 	{"name", offsetof(struct nvmf_rpc_target_ctx, name), spdk_json_decode_string},
2193 };
2194 
2195 static void
2196 nvmf_rpc_destroy_target_done(void *ctx, int status)
2197 {
2198 	struct spdk_jsonrpc_request	*request = ctx;
2199 
2200 	spdk_jsonrpc_send_bool_response(request, true);
2201 }
2202 
2203 static void
2204 rpc_nvmf_delete_target(struct spdk_jsonrpc_request *request,
2205 		       const struct spdk_json_val *params)
2206 {
2207 	struct nvmf_rpc_target_ctx	ctx = {0};
2208 	struct spdk_nvmf_tgt		*tgt;
2209 
2210 	/* Decode parameters the first time to get the transport type */
2211 	if (spdk_json_decode_object(params, nvmf_rpc_destroy_target_decoder,
2212 				    SPDK_COUNTOF(nvmf_rpc_destroy_target_decoder),
2213 				    &ctx)) {
2214 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
2215 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2216 		free(ctx.name);
2217 		return;
2218 	}
2219 
2220 	tgt = spdk_nvmf_get_tgt(ctx.name);
2221 
2222 	if (tgt == NULL) {
2223 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
2224 						 "The specified target doesn't exist, cannot delete it.");
2225 		free(ctx.name);
2226 		return;
2227 	}
2228 
2229 	spdk_nvmf_tgt_destroy(tgt, nvmf_rpc_destroy_target_done, request);
2230 	free(ctx.name);
2231 }
2232 /* private */ SPDK_RPC_REGISTER("nvmf_delete_target", rpc_nvmf_delete_target, SPDK_RPC_RUNTIME);
2233 
2234 static void
2235 rpc_nvmf_get_targets(struct spdk_jsonrpc_request *request,
2236 		     const struct spdk_json_val *params)
2237 {
2238 	struct spdk_json_write_ctx	*w;
2239 	struct spdk_nvmf_tgt		*tgt;
2240 	const char			*name;
2241 
2242 	if (params != NULL) {
2243 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
2244 						 "nvmf_get_targets has no parameters.");
2245 		return;
2246 	}
2247 
2248 	w = spdk_jsonrpc_begin_result(request);
2249 	spdk_json_write_array_begin(w);
2250 
2251 	tgt = spdk_nvmf_get_first_tgt();
2252 
2253 	while (tgt != NULL) {
2254 		name = spdk_nvmf_tgt_get_name(tgt);
2255 		spdk_json_write_string(w, name);
2256 		tgt = spdk_nvmf_get_next_tgt(tgt);
2257 	}
2258 
2259 	spdk_json_write_array_end(w);
2260 	spdk_jsonrpc_end_result(request, w);
2261 }
2262 /* private */ SPDK_RPC_REGISTER("nvmf_get_targets", rpc_nvmf_get_targets, SPDK_RPC_RUNTIME);
2263 
2264 struct nvmf_rpc_create_transport_ctx {
2265 	char				*trtype;
2266 	char				*tgt_name;
2267 	struct spdk_nvmf_transport_opts	opts;
2268 	struct spdk_jsonrpc_request	*request;
2269 	struct spdk_nvmf_transport	*transport;
2270 	int				status;
2271 };
2272 
2273 /**
2274  * `max_qpairs_per_ctrlr` represents both admin and IO qpairs, that confuses
2275  * users when they configure a transport using RPC. So it was decided to
2276  * deprecate `max_qpairs_per_ctrlr` RPC parameter and use `max_io_qpairs_per_ctrlr`
2277  * But internal logic remains unchanged and SPDK expects that
2278  * spdk_nvmf_transport_opts::max_qpairs_per_ctrlr includes an admin qpair.
2279  * This function parses the number of IO qpairs and adds +1 for admin qpair.
2280  */
2281 static int
2282 nvmf_rpc_decode_max_io_qpairs(const struct spdk_json_val *val, void *out)
2283 {
2284 	uint16_t *i = out;
2285 	int rc;
2286 
2287 	rc = spdk_json_number_to_uint16(val, i);
2288 	if (rc == 0) {
2289 		(*i)++;
2290 	}
2291 
2292 	return rc;
2293 }
2294 
2295 static const struct spdk_json_object_decoder nvmf_rpc_create_transport_decoder[] = {
2296 	{	"trtype", offsetof(struct nvmf_rpc_create_transport_ctx, trtype), spdk_json_decode_string},
2297 	{
2298 		"max_queue_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_queue_depth),
2299 		spdk_json_decode_uint16, true
2300 	},
2301 	{
2302 		"max_io_qpairs_per_ctrlr", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_qpairs_per_ctrlr),
2303 		nvmf_rpc_decode_max_io_qpairs, true
2304 	},
2305 	{
2306 		"in_capsule_data_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.in_capsule_data_size),
2307 		spdk_json_decode_uint32, true
2308 	},
2309 	{
2310 		"max_io_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_io_size),
2311 		spdk_json_decode_uint32, true
2312 	},
2313 	{
2314 		"io_unit_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.io_unit_size),
2315 		spdk_json_decode_uint32, true
2316 	},
2317 	{
2318 		"max_aq_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_aq_depth),
2319 		spdk_json_decode_uint32, true
2320 	},
2321 	{
2322 		"num_shared_buffers", offsetof(struct nvmf_rpc_create_transport_ctx, opts.num_shared_buffers),
2323 		spdk_json_decode_uint32, true
2324 	},
2325 	{
2326 		"buf_cache_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.buf_cache_size),
2327 		spdk_json_decode_uint32, true
2328 	},
2329 	{
2330 		"dif_insert_or_strip", offsetof(struct nvmf_rpc_create_transport_ctx, opts.dif_insert_or_strip),
2331 		spdk_json_decode_bool, true
2332 	},
2333 	{
2334 		"abort_timeout_sec", offsetof(struct nvmf_rpc_create_transport_ctx, opts.abort_timeout_sec),
2335 		spdk_json_decode_uint32, true
2336 	},
2337 	{
2338 		"zcopy", offsetof(struct nvmf_rpc_create_transport_ctx, opts.zcopy),
2339 		spdk_json_decode_bool, true
2340 	},
2341 	{
2342 		"tgt_name", offsetof(struct nvmf_rpc_create_transport_ctx, tgt_name),
2343 		spdk_json_decode_string, true
2344 	},
2345 	{
2346 		"acceptor_poll_rate", offsetof(struct nvmf_rpc_create_transport_ctx, opts.acceptor_poll_rate),
2347 		spdk_json_decode_uint32, true
2348 	},
2349 	{
2350 		"ack_timeout", offsetof(struct nvmf_rpc_create_transport_ctx, opts.ack_timeout),
2351 		spdk_json_decode_uint32, true
2352 	},
2353 	{
2354 		"data_wr_pool_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.data_wr_pool_size),
2355 		spdk_json_decode_uint32, true
2356 	}
2357 };
2358 
2359 static void
2360 nvmf_rpc_create_transport_ctx_free(struct nvmf_rpc_create_transport_ctx *ctx)
2361 {
2362 	free(ctx->trtype);
2363 	free(ctx->tgt_name);
2364 	free(ctx);
2365 }
2366 
2367 static void
2368 nvmf_rpc_transport_destroy_done_cb(void *cb_arg)
2369 {
2370 	struct nvmf_rpc_create_transport_ctx *ctx = cb_arg;
2371 
2372 	spdk_jsonrpc_send_error_response_fmt(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2373 					     "Failed to add transport to tgt.(%d)", ctx->status);
2374 	nvmf_rpc_create_transport_ctx_free(ctx);
2375 }
2376 
2377 static void
2378 nvmf_rpc_tgt_add_transport_done(void *cb_arg, int status)
2379 {
2380 	struct nvmf_rpc_create_transport_ctx *ctx = cb_arg;
2381 
2382 	if (status) {
2383 		SPDK_ERRLOG("Failed to add transport to tgt.(%d)\n", status);
2384 		ctx->status = status;
2385 		spdk_nvmf_transport_destroy(ctx->transport, nvmf_rpc_transport_destroy_done_cb, ctx);
2386 		return;
2387 	}
2388 
2389 	spdk_jsonrpc_send_bool_response(ctx->request, true);
2390 	nvmf_rpc_create_transport_ctx_free(ctx);
2391 }
2392 
2393 static void
2394 nvmf_rpc_create_transport_done(void *cb_arg, struct spdk_nvmf_transport *transport)
2395 {
2396 	struct nvmf_rpc_create_transport_ctx *ctx = cb_arg;
2397 
2398 	if (!transport) {
2399 		SPDK_ERRLOG("Failed to create transport.\n");
2400 		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2401 						 "Failed to create transport.");
2402 		nvmf_rpc_create_transport_ctx_free(ctx);
2403 		return;
2404 	}
2405 
2406 	ctx->transport = transport;
2407 
2408 	spdk_nvmf_tgt_add_transport(spdk_nvmf_get_tgt(ctx->tgt_name), transport,
2409 				    nvmf_rpc_tgt_add_transport_done, ctx);
2410 }
2411 
2412 static void
2413 rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request,
2414 			  const struct spdk_json_val *params)
2415 {
2416 	struct nvmf_rpc_create_transport_ctx *ctx;
2417 	struct spdk_nvmf_tgt *tgt;
2418 	int rc;
2419 
2420 	ctx = calloc(1, sizeof(*ctx));
2421 	if (!ctx) {
2422 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
2423 		return;
2424 	}
2425 
2426 	/* Decode parameters the first time to get the transport type */
2427 	if (spdk_json_decode_object_relaxed(params, nvmf_rpc_create_transport_decoder,
2428 					    SPDK_COUNTOF(nvmf_rpc_create_transport_decoder),
2429 					    ctx)) {
2430 		SPDK_ERRLOG("spdk_json_decode_object_relaxed failed\n");
2431 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2432 		nvmf_rpc_create_transport_ctx_free(ctx);
2433 		return;
2434 	}
2435 
2436 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
2437 	if (!tgt) {
2438 		SPDK_ERRLOG("Unable to find a target object.\n");
2439 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2440 						 "Unable to find a target.");
2441 		nvmf_rpc_create_transport_ctx_free(ctx);
2442 		return;
2443 	}
2444 
2445 	/* Initialize all the transport options (based on transport type) and decode the
2446 	 * parameters again to update any options passed in rpc create transport call.
2447 	 */
2448 	if (!spdk_nvmf_transport_opts_init(ctx->trtype, &ctx->opts, sizeof(ctx->opts))) {
2449 		/* This can happen if user specifies PCIE transport type which isn't valid for
2450 		 * NVMe-oF.
2451 		 */
2452 		SPDK_ERRLOG("Invalid transport type '%s'\n", ctx->trtype);
2453 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
2454 						     "Invalid transport type '%s'", ctx->trtype);
2455 		nvmf_rpc_create_transport_ctx_free(ctx);
2456 		return;
2457 	}
2458 
2459 	if (spdk_json_decode_object_relaxed(params, nvmf_rpc_create_transport_decoder,
2460 					    SPDK_COUNTOF(nvmf_rpc_create_transport_decoder),
2461 					    ctx)) {
2462 		SPDK_ERRLOG("spdk_json_decode_object_relaxed failed\n");
2463 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2464 		nvmf_rpc_create_transport_ctx_free(ctx);
2465 		return;
2466 	}
2467 
2468 	if (spdk_nvmf_tgt_get_transport(tgt, ctx->trtype)) {
2469 		SPDK_ERRLOG("Transport type '%s' already exists\n", ctx->trtype);
2470 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2471 						     "Transport type '%s' already exists", ctx->trtype);
2472 		nvmf_rpc_create_transport_ctx_free(ctx);
2473 		return;
2474 	}
2475 
2476 	/* Transport can parse additional params themselves */
2477 	ctx->opts.transport_specific = params;
2478 	ctx->request = request;
2479 
2480 	rc = spdk_nvmf_transport_create_async(ctx->trtype, &ctx->opts, nvmf_rpc_create_transport_done, ctx);
2481 	if (rc) {
2482 		SPDK_ERRLOG("Transport type '%s' create failed\n", ctx->trtype);
2483 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2484 						     "Transport type '%s' create failed", ctx->trtype);
2485 		nvmf_rpc_create_transport_ctx_free(ctx);
2486 	}
2487 }
2488 SPDK_RPC_REGISTER("nvmf_create_transport", rpc_nvmf_create_transport, SPDK_RPC_RUNTIME)
2489 
2490 struct rpc_get_transport {
2491 	char *trtype;
2492 	char *tgt_name;
2493 };
2494 
2495 static const struct spdk_json_object_decoder rpc_get_transport_decoders[] = {
2496 	{"trtype", offsetof(struct rpc_get_transport, trtype), spdk_json_decode_string, true},
2497 	{"tgt_name", offsetof(struct rpc_get_transport, tgt_name), spdk_json_decode_string, true},
2498 };
2499 
2500 static void
2501 rpc_nvmf_get_transports(struct spdk_jsonrpc_request *request,
2502 			const struct spdk_json_val *params)
2503 {
2504 	struct rpc_get_transport req = { 0 };
2505 	struct spdk_json_write_ctx *w;
2506 	struct spdk_nvmf_transport *transport = NULL;
2507 	struct spdk_nvmf_tgt *tgt;
2508 
2509 	if (params) {
2510 		if (spdk_json_decode_object(params, rpc_get_transport_decoders,
2511 					    SPDK_COUNTOF(rpc_get_transport_decoders),
2512 					    &req)) {
2513 			SPDK_ERRLOG("spdk_json_decode_object failed\n");
2514 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2515 			return;
2516 		}
2517 	}
2518 
2519 	tgt = spdk_nvmf_get_tgt(req.tgt_name);
2520 	if (!tgt) {
2521 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2522 						 "Unable to find a target.");
2523 		free(req.trtype);
2524 		free(req.tgt_name);
2525 		return;
2526 	}
2527 
2528 	if (req.trtype) {
2529 		transport = spdk_nvmf_tgt_get_transport(tgt, req.trtype);
2530 		if (transport == NULL) {
2531 			SPDK_ERRLOG("transport '%s' does not exist\n", req.trtype);
2532 			spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
2533 			free(req.trtype);
2534 			free(req.tgt_name);
2535 			return;
2536 		}
2537 	}
2538 
2539 	w = spdk_jsonrpc_begin_result(request);
2540 	spdk_json_write_array_begin(w);
2541 
2542 	if (transport) {
2543 		nvmf_transport_dump_opts(transport, w, false);
2544 	} else {
2545 		for (transport = spdk_nvmf_transport_get_first(tgt); transport != NULL;
2546 		     transport = spdk_nvmf_transport_get_next(transport)) {
2547 			nvmf_transport_dump_opts(transport, w, false);
2548 		}
2549 	}
2550 
2551 	spdk_json_write_array_end(w);
2552 	spdk_jsonrpc_end_result(request, w);
2553 	free(req.trtype);
2554 	free(req.tgt_name);
2555 }
2556 SPDK_RPC_REGISTER("nvmf_get_transports", rpc_nvmf_get_transports, SPDK_RPC_RUNTIME)
2557 
2558 struct rpc_nvmf_get_stats_ctx {
2559 	char *tgt_name;
2560 	struct spdk_nvmf_tgt *tgt;
2561 	struct spdk_jsonrpc_request *request;
2562 	struct spdk_json_write_ctx *w;
2563 };
2564 
2565 static const struct spdk_json_object_decoder rpc_get_stats_decoders[] = {
2566 	{"tgt_name", offsetof(struct rpc_nvmf_get_stats_ctx, tgt_name), spdk_json_decode_string, true},
2567 };
2568 
2569 static void
2570 free_get_stats_ctx(struct rpc_nvmf_get_stats_ctx *ctx)
2571 {
2572 	free(ctx->tgt_name);
2573 	free(ctx);
2574 }
2575 
2576 static void
2577 rpc_nvmf_get_stats_done(struct spdk_io_channel_iter *i, int status)
2578 {
2579 	struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
2580 
2581 	spdk_json_write_array_end(ctx->w);
2582 	spdk_json_write_object_end(ctx->w);
2583 	spdk_jsonrpc_end_result(ctx->request, ctx->w);
2584 	free_get_stats_ctx(ctx);
2585 }
2586 
2587 static void
2588 _rpc_nvmf_get_stats(struct spdk_io_channel_iter *i)
2589 {
2590 	struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
2591 	struct spdk_io_channel *ch;
2592 	struct spdk_nvmf_poll_group *group;
2593 
2594 	ch = spdk_get_io_channel(ctx->tgt);
2595 	group = spdk_io_channel_get_ctx(ch);
2596 
2597 	spdk_nvmf_poll_group_dump_stat(group, ctx->w);
2598 
2599 	spdk_put_io_channel(ch);
2600 	spdk_for_each_channel_continue(i, 0);
2601 }
2602 
2603 
2604 static void
2605 rpc_nvmf_get_stats(struct spdk_jsonrpc_request *request,
2606 		   const struct spdk_json_val *params)
2607 {
2608 	struct rpc_nvmf_get_stats_ctx *ctx;
2609 
2610 	ctx = calloc(1, sizeof(*ctx));
2611 	if (!ctx) {
2612 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2613 						 "Memory allocation error");
2614 		return;
2615 	}
2616 	ctx->request = request;
2617 
2618 	if (params) {
2619 		if (spdk_json_decode_object(params, rpc_get_stats_decoders,
2620 					    SPDK_COUNTOF(rpc_get_stats_decoders),
2621 					    ctx)) {
2622 			SPDK_ERRLOG("spdk_json_decode_object failed\n");
2623 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
2624 			free_get_stats_ctx(ctx);
2625 			return;
2626 		}
2627 	}
2628 
2629 	ctx->tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
2630 	if (!ctx->tgt) {
2631 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2632 						 "Unable to find a target.");
2633 		free_get_stats_ctx(ctx);
2634 		return;
2635 	}
2636 
2637 	ctx->w = spdk_jsonrpc_begin_result(ctx->request);
2638 	spdk_json_write_object_begin(ctx->w);
2639 	spdk_json_write_named_uint64(ctx->w, "tick_rate", spdk_get_ticks_hz());
2640 	spdk_json_write_named_array_begin(ctx->w, "poll_groups");
2641 
2642 	spdk_for_each_channel(ctx->tgt,
2643 			      _rpc_nvmf_get_stats,
2644 			      ctx,
2645 			      rpc_nvmf_get_stats_done);
2646 }
2647 
2648 SPDK_RPC_REGISTER("nvmf_get_stats", rpc_nvmf_get_stats, SPDK_RPC_RUNTIME)
2649 
2650 static void
2651 dump_nvmf_ctrlr(struct spdk_json_write_ctx *w, struct spdk_nvmf_ctrlr *ctrlr)
2652 {
2653 	uint32_t count;
2654 
2655 	spdk_json_write_object_begin(w);
2656 
2657 	spdk_json_write_named_uint32(w, "cntlid", ctrlr->cntlid);
2658 	spdk_json_write_named_string(w, "hostnqn", ctrlr->hostnqn);
2659 	spdk_json_write_named_uuid(w, "hostid", &ctrlr->hostid);
2660 
2661 	count = spdk_bit_array_count_set(ctrlr->qpair_mask);
2662 	spdk_json_write_named_uint32(w, "num_io_qpairs", count);
2663 
2664 	spdk_json_write_object_end(w);
2665 }
2666 
2667 static const char *
2668 nvmf_qpair_state_str(enum spdk_nvmf_qpair_state state)
2669 {
2670 	switch (state) {
2671 	case SPDK_NVMF_QPAIR_UNINITIALIZED:
2672 		return "uninitialized";
2673 	case SPDK_NVMF_QPAIR_CONNECTING:
2674 		return "connecting";
2675 	case SPDK_NVMF_QPAIR_ENABLED:
2676 		return "enabled";
2677 	case SPDK_NVMF_QPAIR_DEACTIVATING:
2678 		return "deactivating";
2679 	case SPDK_NVMF_QPAIR_ERROR:
2680 		return "error";
2681 	default:
2682 		return NULL;
2683 	}
2684 }
2685 
2686 static void
2687 dump_nvmf_qpair(struct spdk_json_write_ctx *w, struct spdk_nvmf_qpair *qpair)
2688 {
2689 	struct spdk_nvme_transport_id trid = {};
2690 
2691 	spdk_json_write_object_begin(w);
2692 
2693 	spdk_json_write_named_uint32(w, "cntlid", qpair->ctrlr->cntlid);
2694 	spdk_json_write_named_uint32(w, "qid", qpair->qid);
2695 	spdk_json_write_named_string(w, "state", nvmf_qpair_state_str(qpair->state));
2696 
2697 	if (spdk_nvmf_qpair_get_listen_trid(qpair, &trid) == 0) {
2698 		spdk_json_write_named_object_begin(w, "listen_address");
2699 		nvmf_transport_listen_dump_trid(&trid, w);
2700 		spdk_json_write_object_end(w);
2701 		if (qpair->transport->ops->listen_dump_opts) {
2702 			qpair->transport->ops->listen_dump_opts(qpair->transport, &trid, w);
2703 		}
2704 	}
2705 
2706 	memset(&trid, 0, sizeof(trid));
2707 	if (spdk_nvmf_qpair_get_peer_trid(qpair, &trid) == 0) {
2708 		spdk_json_write_named_object_begin(w, "peer_address");
2709 		nvmf_transport_listen_dump_trid(&trid, w);
2710 		spdk_json_write_object_end(w);
2711 	}
2712 
2713 	spdk_json_write_object_end(w);
2714 }
2715 
2716 static const char *
2717 nvme_ana_state_str(enum spdk_nvme_ana_state ana_state)
2718 {
2719 	switch (ana_state) {
2720 	case SPDK_NVME_ANA_OPTIMIZED_STATE:
2721 		return "optimized";
2722 	case SPDK_NVME_ANA_NON_OPTIMIZED_STATE:
2723 		return "non_optimized";
2724 	case SPDK_NVME_ANA_INACCESSIBLE_STATE:
2725 		return "inaccessible";
2726 	case SPDK_NVME_ANA_PERSISTENT_LOSS_STATE:
2727 		return "persistent_loss";
2728 	case SPDK_NVME_ANA_CHANGE_STATE:
2729 		return "change";
2730 	default:
2731 		return NULL;
2732 	}
2733 }
2734 
2735 static void
2736 dump_nvmf_subsystem_listener(struct spdk_json_write_ctx *w,
2737 			     struct spdk_nvmf_subsystem_listener *listener)
2738 {
2739 	const struct spdk_nvme_transport_id *trid = listener->trid;
2740 	uint32_t i;
2741 
2742 	spdk_json_write_object_begin(w);
2743 
2744 	spdk_json_write_named_object_begin(w, "address");
2745 	nvmf_transport_listen_dump_trid(trid, w);
2746 	spdk_json_write_object_end(w);
2747 
2748 	if (spdk_nvmf_subsystem_get_ana_reporting(listener->subsystem)) {
2749 		spdk_json_write_named_array_begin(w, "ana_states");
2750 		for (i = 0; i < listener->subsystem->max_nsid; i++) {
2751 			spdk_json_write_object_begin(w);
2752 			spdk_json_write_named_uint32(w, "ana_group", i + 1);
2753 			spdk_json_write_named_string(w, "ana_state",
2754 						     nvme_ana_state_str(listener->ana_state[i]));
2755 			spdk_json_write_object_end(w);
2756 		}
2757 		spdk_json_write_array_end(w);
2758 	}
2759 
2760 	spdk_json_write_object_end(w);
2761 }
2762 
2763 struct rpc_subsystem_query_ctx {
2764 	char *nqn;
2765 	char *tgt_name;
2766 	struct spdk_nvmf_subsystem *subsystem;
2767 	struct spdk_jsonrpc_request *request;
2768 	struct spdk_json_write_ctx *w;
2769 };
2770 
2771 static const struct spdk_json_object_decoder rpc_subsystem_query_decoders[] = {
2772 	{"nqn", offsetof(struct rpc_subsystem_query_ctx, nqn), spdk_json_decode_string},
2773 	{"tgt_name", offsetof(struct rpc_subsystem_query_ctx, tgt_name), spdk_json_decode_string, true},
2774 };
2775 
2776 static void
2777 free_rpc_subsystem_query_ctx(struct rpc_subsystem_query_ctx *ctx)
2778 {
2779 	free(ctx->nqn);
2780 	free(ctx->tgt_name);
2781 	free(ctx);
2782 }
2783 
2784 static void
2785 rpc_nvmf_get_controllers_paused(struct spdk_nvmf_subsystem *subsystem,
2786 				void *cb_arg, int status)
2787 {
2788 	struct rpc_subsystem_query_ctx *ctx = cb_arg;
2789 	struct spdk_json_write_ctx *w;
2790 	struct spdk_nvmf_ctrlr *ctrlr;
2791 
2792 	w = spdk_jsonrpc_begin_result(ctx->request);
2793 
2794 	spdk_json_write_array_begin(w);
2795 	TAILQ_FOREACH(ctrlr, &ctx->subsystem->ctrlrs, link) {
2796 		dump_nvmf_ctrlr(w, ctrlr);
2797 	}
2798 	spdk_json_write_array_end(w);
2799 
2800 	spdk_jsonrpc_end_result(ctx->request, w);
2801 
2802 	if (spdk_nvmf_subsystem_resume(ctx->subsystem, NULL, NULL)) {
2803 		SPDK_ERRLOG("Resuming subsystem with NQN %s failed\n", ctx->nqn);
2804 		/* FIXME: RPC should fail if resuming the subsystem failed. */
2805 	}
2806 
2807 	free_rpc_subsystem_query_ctx(ctx);
2808 }
2809 
2810 static void
2811 rpc_nvmf_get_qpairs_done(struct spdk_io_channel_iter *i, int status)
2812 {
2813 	struct rpc_subsystem_query_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
2814 
2815 	spdk_json_write_array_end(ctx->w);
2816 	spdk_jsonrpc_end_result(ctx->request, ctx->w);
2817 
2818 	if (spdk_nvmf_subsystem_resume(ctx->subsystem, NULL, NULL)) {
2819 		SPDK_ERRLOG("Resuming subsystem with NQN %s failed\n", ctx->nqn);
2820 		/* FIXME: RPC should fail if resuming the subsystem failed. */
2821 	}
2822 
2823 	free_rpc_subsystem_query_ctx(ctx);
2824 }
2825 
2826 static void
2827 rpc_nvmf_get_qpairs(struct spdk_io_channel_iter *i)
2828 {
2829 	struct rpc_subsystem_query_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
2830 	struct spdk_io_channel *ch;
2831 	struct spdk_nvmf_poll_group *group;
2832 	struct spdk_nvmf_qpair *qpair;
2833 
2834 	ch = spdk_io_channel_iter_get_channel(i);
2835 	group = spdk_io_channel_get_ctx(ch);
2836 
2837 	TAILQ_FOREACH(qpair, &group->qpairs, link) {
2838 		if (qpair->ctrlr->subsys == ctx->subsystem) {
2839 			dump_nvmf_qpair(ctx->w, qpair);
2840 		}
2841 	}
2842 
2843 	spdk_for_each_channel_continue(i, 0);
2844 }
2845 
2846 static void
2847 rpc_nvmf_get_qpairs_paused(struct spdk_nvmf_subsystem *subsystem,
2848 			   void *cb_arg, int status)
2849 {
2850 	struct rpc_subsystem_query_ctx *ctx = cb_arg;
2851 
2852 	ctx->w = spdk_jsonrpc_begin_result(ctx->request);
2853 
2854 	spdk_json_write_array_begin(ctx->w);
2855 
2856 	spdk_for_each_channel(ctx->subsystem->tgt,
2857 			      rpc_nvmf_get_qpairs,
2858 			      ctx,
2859 			      rpc_nvmf_get_qpairs_done);
2860 }
2861 
2862 static void
2863 rpc_nvmf_get_listeners_paused(struct spdk_nvmf_subsystem *subsystem,
2864 			      void *cb_arg, int status)
2865 {
2866 	struct rpc_subsystem_query_ctx *ctx = cb_arg;
2867 	struct spdk_json_write_ctx *w;
2868 	struct spdk_nvmf_subsystem_listener *listener;
2869 
2870 	w = spdk_jsonrpc_begin_result(ctx->request);
2871 
2872 	spdk_json_write_array_begin(w);
2873 
2874 	for (listener = spdk_nvmf_subsystem_get_first_listener(ctx->subsystem);
2875 	     listener != NULL;
2876 	     listener = spdk_nvmf_subsystem_get_next_listener(ctx->subsystem, listener)) {
2877 		dump_nvmf_subsystem_listener(w, listener);
2878 	}
2879 	spdk_json_write_array_end(w);
2880 
2881 	spdk_jsonrpc_end_result(ctx->request, w);
2882 
2883 	if (spdk_nvmf_subsystem_resume(ctx->subsystem, NULL, NULL)) {
2884 		SPDK_ERRLOG("Resuming subsystem with NQN %s failed\n", ctx->nqn);
2885 		/* FIXME: RPC should fail if resuming the subsystem failed. */
2886 	}
2887 
2888 	free_rpc_subsystem_query_ctx(ctx);
2889 }
2890 
2891 static void
2892 _rpc_nvmf_subsystem_query(struct spdk_jsonrpc_request *request,
2893 			  const struct spdk_json_val *params,
2894 			  spdk_nvmf_subsystem_state_change_done cb_fn)
2895 {
2896 	struct rpc_subsystem_query_ctx *ctx;
2897 	struct spdk_nvmf_subsystem *subsystem;
2898 	struct spdk_nvmf_tgt *tgt;
2899 
2900 	ctx = calloc(1, sizeof(*ctx));
2901 	if (!ctx) {
2902 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2903 						 "Out of memory");
2904 		return;
2905 	}
2906 
2907 	ctx->request = request;
2908 
2909 	if (spdk_json_decode_object(params, rpc_subsystem_query_decoders,
2910 				    SPDK_COUNTOF(rpc_subsystem_query_decoders),
2911 				    ctx)) {
2912 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
2913 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
2914 						 "Invalid parameters");
2915 		free_rpc_subsystem_query_ctx(ctx);
2916 		return;
2917 	}
2918 
2919 	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
2920 	if (!tgt) {
2921 		SPDK_ERRLOG("Unable to find a target object.\n");
2922 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2923 						 "Unable to find a target");
2924 		free_rpc_subsystem_query_ctx(ctx);
2925 		return;
2926 	}
2927 
2928 	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn);
2929 	if (!subsystem) {
2930 		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn);
2931 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
2932 						 "Invalid parameters");
2933 		free_rpc_subsystem_query_ctx(ctx);
2934 		return;
2935 	}
2936 
2937 	ctx->subsystem = subsystem;
2938 
2939 	if (spdk_nvmf_subsystem_pause(subsystem, 0, cb_fn, ctx)) {
2940 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
2941 						 "Internal error");
2942 		free_rpc_subsystem_query_ctx(ctx);
2943 		return;
2944 	}
2945 }
2946 
2947 static void
2948 rpc_nvmf_subsystem_get_controllers(struct spdk_jsonrpc_request *request,
2949 				   const struct spdk_json_val *params)
2950 {
2951 	_rpc_nvmf_subsystem_query(request, params, rpc_nvmf_get_controllers_paused);
2952 }
2953 SPDK_RPC_REGISTER("nvmf_subsystem_get_controllers", rpc_nvmf_subsystem_get_controllers,
2954 		  SPDK_RPC_RUNTIME);
2955 
2956 static void
2957 rpc_nvmf_subsystem_get_qpairs(struct spdk_jsonrpc_request *request,
2958 			      const struct spdk_json_val *params)
2959 {
2960 	_rpc_nvmf_subsystem_query(request, params, rpc_nvmf_get_qpairs_paused);
2961 }
2962 SPDK_RPC_REGISTER("nvmf_subsystem_get_qpairs", rpc_nvmf_subsystem_get_qpairs, SPDK_RPC_RUNTIME);
2963 
2964 static void
2965 rpc_nvmf_subsystem_get_listeners(struct spdk_jsonrpc_request *request,
2966 				 const struct spdk_json_val *params)
2967 {
2968 	_rpc_nvmf_subsystem_query(request, params, rpc_nvmf_get_listeners_paused);
2969 }
2970 SPDK_RPC_REGISTER("nvmf_subsystem_get_listeners", rpc_nvmf_subsystem_get_listeners,
2971 		  SPDK_RPC_RUNTIME);
2972