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