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