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