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