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