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