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