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