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