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