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