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