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 43 #include "spdk_internal/event.h" 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 }; 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 }; 357 358 static void 359 rpc_nvmf_subsystem_started(struct spdk_nvmf_subsystem *subsystem, 360 void *cb_arg, int status) 361 { 362 struct spdk_jsonrpc_request *request = cb_arg; 363 364 if (!status) { 365 struct spdk_json_write_ctx *w = spdk_jsonrpc_begin_result(request); 366 spdk_json_write_bool(w, true); 367 spdk_jsonrpc_end_result(request, w); 368 } else { 369 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 370 "Subsystem %s start failed", 371 subsystem->subnqn); 372 spdk_nvmf_subsystem_destroy(subsystem); 373 } 374 } 375 376 static void 377 rpc_nvmf_create_subsystem(struct spdk_jsonrpc_request *request, 378 const struct spdk_json_val *params) 379 { 380 struct rpc_subsystem_create *req; 381 struct spdk_nvmf_subsystem *subsystem = NULL; 382 struct spdk_nvmf_tgt *tgt; 383 int rc = -1; 384 385 req = calloc(1, sizeof(*req)); 386 if (!req) { 387 SPDK_ERRLOG("Memory allocation failed\n"); 388 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 389 "Memory allocation failed"); 390 return; 391 } 392 393 if (spdk_json_decode_object(params, rpc_subsystem_create_decoders, 394 SPDK_COUNTOF(rpc_subsystem_create_decoders), 395 req)) { 396 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 397 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 398 goto cleanup; 399 } 400 401 tgt = spdk_nvmf_get_tgt(req->tgt_name); 402 if (!tgt) { 403 SPDK_ERRLOG("Unable to find target %s\n", req->tgt_name); 404 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 405 "Unable to find target %s", req->tgt_name); 406 goto cleanup; 407 } 408 409 subsystem = spdk_nvmf_subsystem_create(tgt, req->nqn, SPDK_NVMF_SUBTYPE_NVME, 410 req->max_namespaces); 411 if (!subsystem) { 412 SPDK_ERRLOG("Unable to create subsystem %s\n", req->nqn); 413 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 414 "Unable to create subsystem %s", req->nqn); 415 goto cleanup; 416 } 417 418 if (req->serial_number) { 419 if (spdk_nvmf_subsystem_set_sn(subsystem, req->serial_number)) { 420 SPDK_ERRLOG("Subsystem %s: invalid serial number '%s'\n", req->nqn, req->serial_number); 421 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 422 "Invalid SN %s", req->serial_number); 423 goto cleanup; 424 } 425 } 426 427 if (req->model_number) { 428 if (spdk_nvmf_subsystem_set_mn(subsystem, req->model_number)) { 429 SPDK_ERRLOG("Subsystem %s: invalid model number '%s'\n", req->nqn, req->model_number); 430 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 431 "Invalid MN %s", req->model_number); 432 goto cleanup; 433 } 434 } 435 436 spdk_nvmf_subsystem_set_allow_any_host(subsystem, req->allow_any_host); 437 438 rc = spdk_nvmf_subsystem_start(subsystem, 439 rpc_nvmf_subsystem_started, 440 request); 441 442 cleanup: 443 free(req->nqn); 444 free(req->tgt_name); 445 free(req->serial_number); 446 free(req->model_number); 447 free(req); 448 449 if (rc && subsystem) { 450 spdk_nvmf_subsystem_destroy(subsystem); 451 } 452 } 453 SPDK_RPC_REGISTER("nvmf_create_subsystem", rpc_nvmf_create_subsystem, SPDK_RPC_RUNTIME) 454 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_create_subsystem, nvmf_subsystem_create) 455 456 struct rpc_delete_subsystem { 457 char *nqn; 458 char *tgt_name; 459 }; 460 461 static void 462 free_rpc_delete_subsystem(struct rpc_delete_subsystem *r) 463 { 464 free(r->nqn); 465 free(r->tgt_name); 466 } 467 468 static void 469 rpc_nvmf_subsystem_stopped(struct spdk_nvmf_subsystem *subsystem, 470 void *cb_arg, int status) 471 { 472 struct spdk_jsonrpc_request *request = cb_arg; 473 struct spdk_json_write_ctx *w; 474 475 nvmf_subsystem_remove_all_listeners(subsystem, true); 476 spdk_nvmf_subsystem_destroy(subsystem); 477 478 w = spdk_jsonrpc_begin_result(request); 479 spdk_json_write_bool(w, true); 480 spdk_jsonrpc_end_result(request, w); 481 } 482 483 static const struct spdk_json_object_decoder rpc_delete_subsystem_decoders[] = { 484 {"nqn", offsetof(struct rpc_delete_subsystem, nqn), spdk_json_decode_string}, 485 {"tgt_name", offsetof(struct rpc_delete_subsystem, tgt_name), spdk_json_decode_string, true}, 486 }; 487 488 static void 489 rpc_nvmf_delete_subsystem(struct spdk_jsonrpc_request *request, 490 const struct spdk_json_val *params) 491 { 492 struct rpc_delete_subsystem req = { 0 }; 493 struct spdk_nvmf_subsystem *subsystem; 494 struct spdk_nvmf_tgt *tgt; 495 496 if (spdk_json_decode_object(params, rpc_delete_subsystem_decoders, 497 SPDK_COUNTOF(rpc_delete_subsystem_decoders), 498 &req)) { 499 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 500 goto invalid; 501 } 502 503 if (req.nqn == NULL) { 504 SPDK_ERRLOG("missing name param\n"); 505 goto invalid; 506 } 507 508 tgt = spdk_nvmf_get_tgt(req.tgt_name); 509 if (!tgt) { 510 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 511 "Unable to find a target."); 512 goto invalid_custom_response; 513 } 514 515 subsystem = spdk_nvmf_tgt_find_subsystem(tgt, req.nqn); 516 if (!subsystem) { 517 goto invalid; 518 } 519 520 free_rpc_delete_subsystem(&req); 521 522 spdk_nvmf_subsystem_stop(subsystem, 523 rpc_nvmf_subsystem_stopped, 524 request); 525 526 return; 527 528 invalid: 529 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 530 invalid_custom_response: 531 free_rpc_delete_subsystem(&req); 532 } 533 SPDK_RPC_REGISTER("nvmf_delete_subsystem", rpc_nvmf_delete_subsystem, SPDK_RPC_RUNTIME) 534 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_delete_subsystem, delete_nvmf_subsystem) 535 536 struct rpc_listen_address { 537 char *transport; 538 char *adrfam; 539 char *traddr; 540 char *trsvcid; 541 }; 542 543 #define RPC_MAX_LISTEN_ADDRESSES 255 544 #define RPC_MAX_NAMESPACES 255 545 546 struct rpc_listen_addresses { 547 size_t num_listen_address; 548 struct rpc_listen_address addresses[RPC_MAX_LISTEN_ADDRESSES]; 549 }; 550 551 static const struct spdk_json_object_decoder rpc_listen_address_decoders[] = { 552 /* NOTE: "transport" is kept for compatibility; new code should use "trtype" */ 553 {"transport", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true}, 554 {"trtype", offsetof(struct rpc_listen_address, transport), spdk_json_decode_string, true}, 555 {"adrfam", offsetof(struct rpc_listen_address, adrfam), spdk_json_decode_string, true}, 556 {"traddr", offsetof(struct rpc_listen_address, traddr), spdk_json_decode_string}, 557 {"trsvcid", offsetof(struct rpc_listen_address, trsvcid), spdk_json_decode_string}, 558 }; 559 560 static int 561 decode_rpc_listen_address(const struct spdk_json_val *val, void *out) 562 { 563 struct rpc_listen_address *req = (struct rpc_listen_address *)out; 564 if (spdk_json_decode_object(val, rpc_listen_address_decoders, 565 SPDK_COUNTOF(rpc_listen_address_decoders), 566 req)) { 567 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 568 return -1; 569 } 570 return 0; 571 } 572 573 static void 574 free_rpc_listen_address(struct rpc_listen_address *r) 575 { 576 free(r->transport); 577 free(r->adrfam); 578 free(r->traddr); 579 free(r->trsvcid); 580 } 581 582 enum nvmf_rpc_listen_op { 583 NVMF_RPC_LISTEN_ADD, 584 NVMF_RPC_LISTEN_REMOVE, 585 }; 586 587 struct nvmf_rpc_listener_ctx { 588 char *nqn; 589 char *tgt_name; 590 struct spdk_nvmf_tgt *tgt; 591 struct spdk_nvmf_subsystem *subsystem; 592 struct rpc_listen_address address; 593 594 struct spdk_jsonrpc_request *request; 595 struct spdk_nvme_transport_id trid; 596 enum nvmf_rpc_listen_op op; 597 bool response_sent; 598 }; 599 600 static const struct spdk_json_object_decoder nvmf_rpc_listener_decoder[] = { 601 {"nqn", offsetof(struct nvmf_rpc_listener_ctx, nqn), spdk_json_decode_string}, 602 {"listen_address", offsetof(struct nvmf_rpc_listener_ctx, address), decode_rpc_listen_address}, 603 {"tgt_name", offsetof(struct nvmf_rpc_listener_ctx, tgt_name), spdk_json_decode_string, true}, 604 }; 605 606 static void 607 nvmf_rpc_listener_ctx_free(struct nvmf_rpc_listener_ctx *ctx) 608 { 609 free(ctx->nqn); 610 free(ctx->tgt_name); 611 free_rpc_listen_address(&ctx->address); 612 free(ctx); 613 } 614 615 static void 616 nvmf_rpc_listen_resumed(struct spdk_nvmf_subsystem *subsystem, 617 void *cb_arg, int status) 618 { 619 struct nvmf_rpc_listener_ctx *ctx = cb_arg; 620 struct spdk_jsonrpc_request *request; 621 struct spdk_json_write_ctx *w; 622 623 request = ctx->request; 624 if (ctx->response_sent) { 625 /* If an error occurred, the response has already been sent. */ 626 nvmf_rpc_listener_ctx_free(ctx); 627 return; 628 } 629 630 nvmf_rpc_listener_ctx_free(ctx); 631 632 w = spdk_jsonrpc_begin_result(request); 633 spdk_json_write_bool(w, true); 634 spdk_jsonrpc_end_result(request, w); 635 } 636 637 static void 638 nvmf_rpc_subsystem_listen(void *cb_arg, int status) 639 { 640 struct nvmf_rpc_listener_ctx *ctx = cb_arg; 641 642 if (status) { 643 /* Destroy the listener that we just created. Ignore the error code because 644 * the RPC is failing already anyway. */ 645 spdk_nvmf_tgt_stop_listen(ctx->tgt, &ctx->trid); 646 647 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 648 "Invalid parameters"); 649 ctx->response_sent = true; 650 } 651 652 if (spdk_nvmf_subsystem_resume(ctx->subsystem, nvmf_rpc_listen_resumed, ctx)) { 653 if (!ctx->response_sent) { 654 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 655 } 656 nvmf_rpc_listener_ctx_free(ctx); 657 /* Can't really do anything to recover here - subsystem will remain paused. */ 658 } 659 } 660 661 static void 662 nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem, 663 void *cb_arg, int status) 664 { 665 struct nvmf_rpc_listener_ctx *ctx = cb_arg; 666 int rc; 667 668 if (ctx->op == NVMF_RPC_LISTEN_ADD) { 669 if (!nvmf_subsystem_find_listener(subsystem, &ctx->trid)) { 670 rc = spdk_nvmf_tgt_listen(ctx->tgt, &ctx->trid); 671 if (rc == 0) { 672 spdk_nvmf_subsystem_add_listener(ctx->subsystem, &ctx->trid, nvmf_rpc_subsystem_listen, ctx); 673 return; 674 } 675 676 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 677 "Invalid parameters"); 678 ctx->response_sent = true; 679 } 680 } else if (ctx->op == NVMF_RPC_LISTEN_REMOVE) { 681 if (spdk_nvmf_subsystem_remove_listener(subsystem, &ctx->trid)) { 682 SPDK_ERRLOG("Unable to remove listener.\n"); 683 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 684 "Invalid parameters"); 685 ctx->response_sent = true; 686 } 687 spdk_nvmf_tgt_stop_listen(ctx->tgt, &ctx->trid); 688 } else { 689 SPDK_UNREACHABLE(); 690 } 691 692 if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_listen_resumed, ctx)) { 693 if (!ctx->response_sent) { 694 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 695 } 696 nvmf_rpc_listener_ctx_free(ctx); 697 /* Can't really do anything to recover here - subsystem will remain paused. */ 698 } 699 } 700 701 static int 702 rpc_listen_address_to_trid(const struct rpc_listen_address *address, 703 struct spdk_nvme_transport_id *trid) 704 { 705 size_t len; 706 707 memset(trid, 0, sizeof(*trid)); 708 709 if (spdk_nvme_transport_id_populate_trstring(trid, address->transport)) { 710 SPDK_ERRLOG("Invalid transport string: %s\n", address->transport); 711 return -EINVAL; 712 } 713 714 if (spdk_nvme_transport_id_parse_trtype(&trid->trtype, address->transport)) { 715 SPDK_ERRLOG("Invalid transport type: %s\n", address->transport); 716 return -EINVAL; 717 } 718 719 if (address->adrfam) { 720 if (spdk_nvme_transport_id_parse_adrfam(&trid->adrfam, address->adrfam)) { 721 SPDK_ERRLOG("Invalid adrfam: %s\n", address->adrfam); 722 return -EINVAL; 723 } 724 } else { 725 trid->adrfam = SPDK_NVMF_ADRFAM_IPV4; 726 } 727 728 len = strlen(address->traddr); 729 if (len > sizeof(trid->traddr) - 1) { 730 SPDK_ERRLOG("Transport address longer than %zu characters: %s\n", 731 sizeof(trid->traddr) - 1, address->traddr); 732 return -EINVAL; 733 } 734 memcpy(trid->traddr, address->traddr, len + 1); 735 736 len = strlen(address->trsvcid); 737 if (len > sizeof(trid->trsvcid) - 1) { 738 SPDK_ERRLOG("Transport service id longer than %zu characters: %s\n", 739 sizeof(trid->trsvcid) - 1, address->trsvcid); 740 return -EINVAL; 741 } 742 memcpy(trid->trsvcid, address->trsvcid, len + 1); 743 744 return 0; 745 } 746 747 static void 748 rpc_nvmf_subsystem_add_listener(struct spdk_jsonrpc_request *request, 749 const struct spdk_json_val *params) 750 { 751 struct nvmf_rpc_listener_ctx *ctx; 752 struct spdk_nvmf_subsystem *subsystem; 753 struct spdk_nvmf_tgt *tgt; 754 755 ctx = calloc(1, sizeof(*ctx)); 756 if (!ctx) { 757 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); 758 return; 759 } 760 761 ctx->request = request; 762 763 if (spdk_json_decode_object(params, nvmf_rpc_listener_decoder, 764 SPDK_COUNTOF(nvmf_rpc_listener_decoder), 765 ctx)) { 766 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 767 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 768 nvmf_rpc_listener_ctx_free(ctx); 769 return; 770 } 771 772 tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 773 if (!tgt) { 774 SPDK_ERRLOG("Unable to find a target object.\n"); 775 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 776 "Unable to find a target."); 777 nvmf_rpc_listener_ctx_free(ctx); 778 return; 779 } 780 ctx->tgt = tgt; 781 782 subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn); 783 if (!subsystem) { 784 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn); 785 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 786 nvmf_rpc_listener_ctx_free(ctx); 787 return; 788 } 789 790 ctx->subsystem = subsystem; 791 792 if (rpc_listen_address_to_trid(&ctx->address, &ctx->trid)) { 793 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 794 "Invalid parameters"); 795 nvmf_rpc_listener_ctx_free(ctx); 796 return; 797 } 798 799 ctx->op = NVMF_RPC_LISTEN_ADD; 800 801 if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_listen_paused, ctx)) { 802 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 803 nvmf_rpc_listener_ctx_free(ctx); 804 return; 805 } 806 } 807 SPDK_RPC_REGISTER("nvmf_subsystem_add_listener", rpc_nvmf_subsystem_add_listener, 808 SPDK_RPC_RUNTIME); 809 810 static void 811 rpc_nvmf_subsystem_remove_listener(struct spdk_jsonrpc_request *request, 812 const struct spdk_json_val *params) 813 { 814 struct nvmf_rpc_listener_ctx *ctx; 815 struct spdk_nvmf_subsystem *subsystem; 816 struct spdk_nvmf_tgt *tgt; 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_REMOVE; 863 864 if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_listen_paused, ctx)) { 865 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 866 nvmf_rpc_listener_ctx_free(ctx); 867 return; 868 } 869 870 } 871 SPDK_RPC_REGISTER("nvmf_subsystem_remove_listener", rpc_nvmf_subsystem_remove_listener, 872 SPDK_RPC_RUNTIME); 873 874 struct spdk_nvmf_ns_params { 875 char *bdev_name; 876 char *ptpl_file; 877 uint32_t nsid; 878 char nguid[16]; 879 char eui64[8]; 880 struct spdk_uuid uuid; 881 }; 882 883 struct rpc_namespaces { 884 size_t num_ns; 885 struct spdk_nvmf_ns_params ns_params[RPC_MAX_NAMESPACES]; 886 }; 887 888 889 static const struct spdk_json_object_decoder rpc_ns_params_decoders[] = { 890 {"nsid", offsetof(struct spdk_nvmf_ns_params, nsid), spdk_json_decode_uint32, true}, 891 {"bdev_name", offsetof(struct spdk_nvmf_ns_params, bdev_name), spdk_json_decode_string}, 892 {"ptpl_file", offsetof(struct spdk_nvmf_ns_params, ptpl_file), spdk_json_decode_string, true}, 893 {"nguid", offsetof(struct spdk_nvmf_ns_params, nguid), decode_ns_nguid, true}, 894 {"eui64", offsetof(struct spdk_nvmf_ns_params, eui64), decode_ns_eui64, true}, 895 {"uuid", offsetof(struct spdk_nvmf_ns_params, uuid), decode_ns_uuid, true}, 896 }; 897 898 static int 899 decode_rpc_ns_params(const struct spdk_json_val *val, void *out) 900 { 901 struct spdk_nvmf_ns_params *ns_params = out; 902 903 return spdk_json_decode_object(val, rpc_ns_params_decoders, 904 SPDK_COUNTOF(rpc_ns_params_decoders), 905 ns_params); 906 } 907 908 struct nvmf_rpc_ns_ctx { 909 char *nqn; 910 char *tgt_name; 911 struct spdk_nvmf_ns_params ns_params; 912 913 struct spdk_jsonrpc_request *request; 914 bool response_sent; 915 }; 916 917 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_ns_decoder[] = { 918 {"nqn", offsetof(struct nvmf_rpc_ns_ctx, nqn), spdk_json_decode_string}, 919 {"namespace", offsetof(struct nvmf_rpc_ns_ctx, ns_params), decode_rpc_ns_params}, 920 {"tgt_name", offsetof(struct nvmf_rpc_ns_ctx, tgt_name), spdk_json_decode_string, true}, 921 }; 922 923 static void 924 nvmf_rpc_ns_ctx_free(struct nvmf_rpc_ns_ctx *ctx) 925 { 926 free(ctx->nqn); 927 free(ctx->tgt_name); 928 free(ctx->ns_params.bdev_name); 929 free(ctx->ns_params.ptpl_file); 930 free(ctx); 931 } 932 933 static void 934 nvmf_rpc_ns_resumed(struct spdk_nvmf_subsystem *subsystem, 935 void *cb_arg, int status) 936 { 937 struct nvmf_rpc_ns_ctx *ctx = cb_arg; 938 struct spdk_jsonrpc_request *request = ctx->request; 939 uint32_t nsid = ctx->ns_params.nsid; 940 bool response_sent = ctx->response_sent; 941 struct spdk_json_write_ctx *w; 942 943 nvmf_rpc_ns_ctx_free(ctx); 944 945 if (response_sent) { 946 return; 947 } 948 949 w = spdk_jsonrpc_begin_result(request); 950 spdk_json_write_uint32(w, nsid); 951 spdk_jsonrpc_end_result(request, w); 952 } 953 954 static void 955 nvmf_rpc_ns_paused(struct spdk_nvmf_subsystem *subsystem, 956 void *cb_arg, int status) 957 { 958 struct nvmf_rpc_ns_ctx *ctx = cb_arg; 959 struct spdk_nvmf_ns_opts ns_opts; 960 struct spdk_bdev *bdev; 961 962 bdev = spdk_bdev_get_by_name(ctx->ns_params.bdev_name); 963 if (!bdev) { 964 SPDK_ERRLOG("No bdev with name %s\n", ctx->ns_params.bdev_name); 965 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 966 "Invalid parameters"); 967 ctx->response_sent = true; 968 goto resume; 969 } 970 971 spdk_nvmf_ns_opts_get_defaults(&ns_opts, sizeof(ns_opts)); 972 ns_opts.nsid = ctx->ns_params.nsid; 973 974 SPDK_STATIC_ASSERT(sizeof(ns_opts.nguid) == sizeof(ctx->ns_params.nguid), "size mismatch"); 975 memcpy(ns_opts.nguid, ctx->ns_params.nguid, sizeof(ns_opts.nguid)); 976 977 SPDK_STATIC_ASSERT(sizeof(ns_opts.eui64) == sizeof(ctx->ns_params.eui64), "size mismatch"); 978 memcpy(ns_opts.eui64, ctx->ns_params.eui64, sizeof(ns_opts.eui64)); 979 980 if (!spdk_mem_all_zero(&ctx->ns_params.uuid, sizeof(ctx->ns_params.uuid))) { 981 ns_opts.uuid = ctx->ns_params.uuid; 982 } 983 984 ctx->ns_params.nsid = spdk_nvmf_subsystem_add_ns(subsystem, bdev, &ns_opts, sizeof(ns_opts), 985 ctx->ns_params.ptpl_file); 986 if (ctx->ns_params.nsid == 0) { 987 SPDK_ERRLOG("Unable to add namespace\n"); 988 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 989 "Invalid parameters"); 990 ctx->response_sent = true; 991 goto resume; 992 } 993 994 resume: 995 if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_ns_resumed, ctx)) { 996 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 997 nvmf_rpc_ns_ctx_free(ctx); 998 return; 999 } 1000 } 1001 1002 static void 1003 rpc_nvmf_subsystem_add_ns(struct spdk_jsonrpc_request *request, 1004 const struct spdk_json_val *params) 1005 { 1006 struct nvmf_rpc_ns_ctx *ctx; 1007 struct spdk_nvmf_subsystem *subsystem; 1008 struct spdk_nvmf_tgt *tgt; 1009 1010 ctx = calloc(1, sizeof(*ctx)); 1011 if (!ctx) { 1012 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); 1013 return; 1014 } 1015 1016 if (spdk_json_decode_object(params, nvmf_rpc_subsystem_ns_decoder, 1017 SPDK_COUNTOF(nvmf_rpc_subsystem_ns_decoder), 1018 ctx)) { 1019 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1020 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1021 nvmf_rpc_ns_ctx_free(ctx); 1022 return; 1023 } 1024 1025 ctx->request = request; 1026 ctx->response_sent = false; 1027 1028 tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 1029 if (!tgt) { 1030 SPDK_ERRLOG("Unable to find a target object.\n"); 1031 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1032 "Unable to find a target."); 1033 nvmf_rpc_ns_ctx_free(ctx); 1034 return; 1035 } 1036 1037 subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn); 1038 if (!subsystem) { 1039 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn); 1040 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1041 nvmf_rpc_ns_ctx_free(ctx); 1042 return; 1043 } 1044 1045 if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_ns_paused, ctx)) { 1046 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1047 nvmf_rpc_ns_ctx_free(ctx); 1048 return; 1049 } 1050 } 1051 SPDK_RPC_REGISTER("nvmf_subsystem_add_ns", rpc_nvmf_subsystem_add_ns, SPDK_RPC_RUNTIME) 1052 1053 struct nvmf_rpc_remove_ns_ctx { 1054 char *nqn; 1055 char *tgt_name; 1056 uint32_t nsid; 1057 1058 struct spdk_jsonrpc_request *request; 1059 bool response_sent; 1060 }; 1061 1062 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_remove_ns_decoder[] = { 1063 {"nqn", offsetof(struct nvmf_rpc_remove_ns_ctx, nqn), spdk_json_decode_string}, 1064 {"nsid", offsetof(struct nvmf_rpc_remove_ns_ctx, nsid), spdk_json_decode_uint32}, 1065 {"tgt_name", offsetof(struct nvmf_rpc_remove_ns_ctx, tgt_name), spdk_json_decode_string, true}, 1066 }; 1067 1068 static void 1069 nvmf_rpc_remove_ns_ctx_free(struct nvmf_rpc_remove_ns_ctx *ctx) 1070 { 1071 free(ctx->nqn); 1072 free(ctx->tgt_name); 1073 free(ctx); 1074 } 1075 1076 static void 1077 nvmf_rpc_remove_ns_resumed(struct spdk_nvmf_subsystem *subsystem, 1078 void *cb_arg, int status) 1079 { 1080 struct nvmf_rpc_remove_ns_ctx *ctx = cb_arg; 1081 struct spdk_jsonrpc_request *request = ctx->request; 1082 bool response_sent = ctx->response_sent; 1083 struct spdk_json_write_ctx *w; 1084 1085 nvmf_rpc_remove_ns_ctx_free(ctx); 1086 1087 if (response_sent) { 1088 return; 1089 } 1090 1091 w = spdk_jsonrpc_begin_result(request); 1092 spdk_json_write_bool(w, true); 1093 spdk_jsonrpc_end_result(request, w); 1094 } 1095 1096 static void 1097 nvmf_rpc_remove_ns_paused(struct spdk_nvmf_subsystem *subsystem, 1098 void *cb_arg, int status) 1099 { 1100 struct nvmf_rpc_remove_ns_ctx *ctx = cb_arg; 1101 int ret; 1102 1103 ret = spdk_nvmf_subsystem_remove_ns(subsystem, ctx->nsid); 1104 if (ret < 0) { 1105 SPDK_ERRLOG("Unable to remove namespace ID %u\n", ctx->nsid); 1106 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 1107 "Invalid parameters"); 1108 ctx->response_sent = true; 1109 } 1110 1111 if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_remove_ns_resumed, ctx)) { 1112 if (!ctx->response_sent) { 1113 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1114 } 1115 nvmf_rpc_remove_ns_ctx_free(ctx); 1116 return; 1117 } 1118 } 1119 1120 static void 1121 rpc_nvmf_subsystem_remove_ns(struct spdk_jsonrpc_request *request, 1122 const struct spdk_json_val *params) 1123 { 1124 struct nvmf_rpc_remove_ns_ctx *ctx; 1125 struct spdk_nvmf_subsystem *subsystem; 1126 struct spdk_nvmf_tgt *tgt; 1127 1128 ctx = calloc(1, sizeof(*ctx)); 1129 if (!ctx) { 1130 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); 1131 return; 1132 } 1133 1134 if (spdk_json_decode_object(params, nvmf_rpc_subsystem_remove_ns_decoder, 1135 SPDK_COUNTOF(nvmf_rpc_subsystem_remove_ns_decoder), 1136 ctx)) { 1137 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1138 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1139 nvmf_rpc_remove_ns_ctx_free(ctx); 1140 return; 1141 } 1142 1143 tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 1144 if (!tgt) { 1145 SPDK_ERRLOG("Unable to find a target object.\n"); 1146 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1147 "Unable to find a target."); 1148 nvmf_rpc_remove_ns_ctx_free(ctx); 1149 return; 1150 } 1151 1152 ctx->request = request; 1153 ctx->response_sent = false; 1154 1155 subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn); 1156 if (!subsystem) { 1157 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn); 1158 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1159 nvmf_rpc_remove_ns_ctx_free(ctx); 1160 return; 1161 } 1162 1163 if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_remove_ns_paused, ctx)) { 1164 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1165 nvmf_rpc_remove_ns_ctx_free(ctx); 1166 return; 1167 } 1168 } 1169 SPDK_RPC_REGISTER("nvmf_subsystem_remove_ns", rpc_nvmf_subsystem_remove_ns, SPDK_RPC_RUNTIME) 1170 1171 enum nvmf_rpc_host_op { 1172 NVMF_RPC_HOST_ADD, 1173 NVMF_RPC_HOST_REMOVE, 1174 NVMF_RPC_HOST_ALLOW_ANY, 1175 }; 1176 1177 struct nvmf_rpc_host_ctx { 1178 struct spdk_jsonrpc_request *request; 1179 1180 char *nqn; 1181 char *host; 1182 char *tgt_name; 1183 1184 enum nvmf_rpc_host_op op; 1185 1186 bool allow_any_host; 1187 1188 bool response_sent; 1189 }; 1190 1191 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_host_decoder[] = { 1192 {"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string}, 1193 {"host", offsetof(struct nvmf_rpc_host_ctx, host), spdk_json_decode_string}, 1194 {"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true}, 1195 }; 1196 1197 static void 1198 nvmf_rpc_host_ctx_free(struct nvmf_rpc_host_ctx *ctx) 1199 { 1200 free(ctx->nqn); 1201 free(ctx->host); 1202 free(ctx->tgt_name); 1203 free(ctx); 1204 } 1205 1206 static void 1207 nvmf_rpc_host_resumed(struct spdk_nvmf_subsystem *subsystem, 1208 void *cb_arg, int status) 1209 { 1210 struct nvmf_rpc_host_ctx *ctx = cb_arg; 1211 struct spdk_jsonrpc_request *request; 1212 struct spdk_json_write_ctx *w; 1213 bool response_sent = ctx->response_sent; 1214 1215 request = ctx->request; 1216 nvmf_rpc_host_ctx_free(ctx); 1217 1218 if (response_sent) { 1219 return; 1220 } 1221 1222 w = spdk_jsonrpc_begin_result(request); 1223 spdk_json_write_bool(w, true); 1224 spdk_jsonrpc_end_result(request, w); 1225 } 1226 1227 static void 1228 nvmf_rpc_host_paused(struct spdk_nvmf_subsystem *subsystem, 1229 void *cb_arg, int status) 1230 { 1231 struct nvmf_rpc_host_ctx *ctx = cb_arg; 1232 int rc = -1; 1233 1234 switch (ctx->op) { 1235 case NVMF_RPC_HOST_ADD: 1236 rc = spdk_nvmf_subsystem_add_host(subsystem, ctx->host); 1237 break; 1238 case NVMF_RPC_HOST_REMOVE: 1239 rc = spdk_nvmf_subsystem_remove_host(subsystem, ctx->host); 1240 break; 1241 case NVMF_RPC_HOST_ALLOW_ANY: 1242 rc = spdk_nvmf_subsystem_set_allow_any_host(subsystem, ctx->allow_any_host); 1243 break; 1244 } 1245 1246 if (rc != 0) { 1247 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1248 ctx->response_sent = true; 1249 } 1250 1251 if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_host_resumed, ctx)) { 1252 if (!ctx->response_sent) { 1253 spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1254 } 1255 nvmf_rpc_host_ctx_free(ctx); 1256 return; 1257 } 1258 } 1259 1260 static void 1261 rpc_nvmf_subsystem_add_host(struct spdk_jsonrpc_request *request, 1262 const struct spdk_json_val *params) 1263 { 1264 struct nvmf_rpc_host_ctx *ctx; 1265 struct spdk_nvmf_subsystem *subsystem; 1266 struct spdk_nvmf_tgt *tgt; 1267 1268 ctx = calloc(1, sizeof(*ctx)); 1269 if (!ctx) { 1270 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); 1271 return; 1272 } 1273 1274 if (spdk_json_decode_object(params, nvmf_rpc_subsystem_host_decoder, 1275 SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder), 1276 ctx)) { 1277 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1278 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1279 nvmf_rpc_host_ctx_free(ctx); 1280 return; 1281 } 1282 1283 tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 1284 if (!tgt) { 1285 SPDK_ERRLOG("Unable to find a target object.\n"); 1286 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1287 "Unable to find a target."); 1288 nvmf_rpc_host_ctx_free(ctx); 1289 return; 1290 } 1291 1292 ctx->request = request; 1293 ctx->op = NVMF_RPC_HOST_ADD; 1294 ctx->response_sent = false; 1295 1296 subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn); 1297 if (!subsystem) { 1298 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn); 1299 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1300 nvmf_rpc_host_ctx_free(ctx); 1301 return; 1302 } 1303 1304 if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_host_paused, ctx)) { 1305 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1306 nvmf_rpc_host_ctx_free(ctx); 1307 return; 1308 } 1309 } 1310 SPDK_RPC_REGISTER("nvmf_subsystem_add_host", rpc_nvmf_subsystem_add_host, SPDK_RPC_RUNTIME) 1311 1312 static void 1313 rpc_nvmf_subsystem_remove_host(struct spdk_jsonrpc_request *request, 1314 const struct spdk_json_val *params) 1315 { 1316 struct nvmf_rpc_host_ctx *ctx; 1317 struct spdk_nvmf_subsystem *subsystem; 1318 struct spdk_nvmf_tgt *tgt; 1319 1320 ctx = calloc(1, sizeof(*ctx)); 1321 if (!ctx) { 1322 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); 1323 return; 1324 } 1325 1326 if (spdk_json_decode_object(params, nvmf_rpc_subsystem_host_decoder, 1327 SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder), 1328 ctx)) { 1329 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1330 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1331 nvmf_rpc_host_ctx_free(ctx); 1332 return; 1333 } 1334 1335 tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 1336 if (!tgt) { 1337 SPDK_ERRLOG("Unable to find a target object.\n"); 1338 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1339 "Unable to find a target."); 1340 nvmf_rpc_host_ctx_free(ctx); 1341 return; 1342 } 1343 1344 ctx->request = request; 1345 ctx->op = NVMF_RPC_HOST_REMOVE; 1346 ctx->response_sent = false; 1347 1348 subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn); 1349 if (!subsystem) { 1350 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn); 1351 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1352 nvmf_rpc_host_ctx_free(ctx); 1353 return; 1354 } 1355 1356 if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_host_paused, ctx)) { 1357 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1358 nvmf_rpc_host_ctx_free(ctx); 1359 return; 1360 } 1361 } 1362 SPDK_RPC_REGISTER("nvmf_subsystem_remove_host", rpc_nvmf_subsystem_remove_host, 1363 SPDK_RPC_RUNTIME) 1364 1365 1366 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_any_host_decoder[] = { 1367 {"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string}, 1368 {"allow_any_host", offsetof(struct nvmf_rpc_host_ctx, allow_any_host), spdk_json_decode_bool}, 1369 {"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true}, 1370 }; 1371 1372 static void 1373 rpc_nvmf_subsystem_allow_any_host(struct spdk_jsonrpc_request *request, 1374 const struct spdk_json_val *params) 1375 { 1376 struct nvmf_rpc_host_ctx *ctx; 1377 struct spdk_nvmf_subsystem *subsystem; 1378 struct spdk_nvmf_tgt *tgt; 1379 1380 ctx = calloc(1, sizeof(*ctx)); 1381 if (!ctx) { 1382 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); 1383 return; 1384 } 1385 1386 if (spdk_json_decode_object(params, nvmf_rpc_subsystem_any_host_decoder, 1387 SPDK_COUNTOF(nvmf_rpc_subsystem_any_host_decoder), 1388 ctx)) { 1389 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1390 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1391 nvmf_rpc_host_ctx_free(ctx); 1392 return; 1393 } 1394 1395 tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 1396 if (!tgt) { 1397 SPDK_ERRLOG("Unable to find a target object.\n"); 1398 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1399 "Unable to find a target."); 1400 nvmf_rpc_host_ctx_free(ctx); 1401 return; 1402 } 1403 1404 ctx->request = request; 1405 ctx->op = NVMF_RPC_HOST_ALLOW_ANY; 1406 ctx->response_sent = false; 1407 1408 subsystem = spdk_nvmf_tgt_find_subsystem(tgt, ctx->nqn); 1409 if (!subsystem) { 1410 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn); 1411 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1412 nvmf_rpc_host_ctx_free(ctx); 1413 return; 1414 } 1415 1416 if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_host_paused, ctx)) { 1417 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); 1418 nvmf_rpc_host_ctx_free(ctx); 1419 return; 1420 } 1421 } 1422 SPDK_RPC_REGISTER("nvmf_subsystem_allow_any_host", rpc_nvmf_subsystem_allow_any_host, 1423 SPDK_RPC_RUNTIME) 1424 1425 struct nvmf_rpc_target_ctx { 1426 char *name; 1427 uint32_t max_subsystems; 1428 }; 1429 1430 static const struct spdk_json_object_decoder nvmf_rpc_create_target_decoder[] = { 1431 {"name", offsetof(struct nvmf_rpc_target_ctx, name), spdk_json_decode_string}, 1432 {"max_subsystems", offsetof(struct nvmf_rpc_target_ctx, max_subsystems), spdk_json_decode_uint32, true}, 1433 }; 1434 1435 static void 1436 rpc_nvmf_create_target(struct spdk_jsonrpc_request *request, 1437 const struct spdk_json_val *params) 1438 { 1439 struct spdk_nvmf_target_opts opts; 1440 struct nvmf_rpc_target_ctx ctx = {0}; 1441 struct spdk_nvmf_tgt *tgt; 1442 struct spdk_json_write_ctx *w; 1443 1444 /* Decode parameters the first time to get the transport type */ 1445 if (spdk_json_decode_object(params, nvmf_rpc_create_target_decoder, 1446 SPDK_COUNTOF(nvmf_rpc_create_target_decoder), 1447 &ctx)) { 1448 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1449 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1450 free(ctx.name); 1451 return; 1452 } 1453 1454 snprintf(opts.name, NVMF_TGT_NAME_MAX_LENGTH, "%s", ctx.name); 1455 opts.max_subsystems = ctx.max_subsystems; 1456 1457 if (spdk_nvmf_get_tgt(opts.name) != NULL) { 1458 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 1459 "Target already exists."); 1460 free(ctx.name); 1461 return; 1462 } 1463 1464 tgt = spdk_nvmf_tgt_create(&opts); 1465 1466 if (tgt == NULL) { 1467 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1468 "Unable to create the requested target."); 1469 free(ctx.name); 1470 return; 1471 } 1472 1473 w = spdk_jsonrpc_begin_result(request); 1474 spdk_json_write_string(w, spdk_nvmf_tgt_get_name(tgt)); 1475 spdk_jsonrpc_end_result(request, w); 1476 free(ctx.name); 1477 } 1478 SPDK_RPC_REGISTER("nvmf_create_target", rpc_nvmf_create_target, SPDK_RPC_RUNTIME); 1479 1480 static const struct spdk_json_object_decoder nvmf_rpc_destroy_target_decoder[] = { 1481 {"name", offsetof(struct nvmf_rpc_target_ctx, name), spdk_json_decode_string}, 1482 }; 1483 1484 static void 1485 nvmf_rpc_destroy_target_done(void *ctx, int status) 1486 { 1487 struct spdk_jsonrpc_request *request = ctx; 1488 struct spdk_json_write_ctx *w; 1489 1490 w = spdk_jsonrpc_begin_result(request); 1491 spdk_json_write_bool(w, true); 1492 spdk_jsonrpc_end_result(request, w); 1493 } 1494 1495 static void 1496 rpc_nvmf_delete_target(struct spdk_jsonrpc_request *request, 1497 const struct spdk_json_val *params) 1498 { 1499 struct nvmf_rpc_target_ctx ctx = {0}; 1500 struct spdk_nvmf_tgt *tgt; 1501 1502 /* Decode parameters the first time to get the transport type */ 1503 if (spdk_json_decode_object(params, nvmf_rpc_destroy_target_decoder, 1504 SPDK_COUNTOF(nvmf_rpc_destroy_target_decoder), 1505 &ctx)) { 1506 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1507 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1508 free(ctx.name); 1509 return; 1510 } 1511 1512 tgt = spdk_nvmf_get_tgt(ctx.name); 1513 1514 if (tgt == NULL) { 1515 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 1516 "The specified target doesn't exist, cannot delete it."); 1517 free(ctx.name); 1518 return; 1519 } 1520 1521 spdk_nvmf_tgt_destroy(tgt, nvmf_rpc_destroy_target_done, request); 1522 free(ctx.name); 1523 } 1524 SPDK_RPC_REGISTER("nvmf_delete_target", rpc_nvmf_delete_target, SPDK_RPC_RUNTIME); 1525 1526 static void 1527 rpc_nvmf_get_targets(struct spdk_jsonrpc_request *request, 1528 const struct spdk_json_val *params) 1529 { 1530 struct spdk_json_write_ctx *w; 1531 struct spdk_nvmf_tgt *tgt; 1532 const char *name; 1533 1534 if (params != NULL) { 1535 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 1536 "nvmf_get_targets has no parameters."); 1537 return; 1538 } 1539 1540 w = spdk_jsonrpc_begin_result(request); 1541 spdk_json_write_array_begin(w); 1542 1543 tgt = spdk_nvmf_get_first_tgt(); 1544 1545 while (tgt != NULL) { 1546 name = spdk_nvmf_tgt_get_name(tgt); 1547 spdk_json_write_string(w, name); 1548 tgt = spdk_nvmf_get_next_tgt(tgt); 1549 } 1550 1551 spdk_json_write_array_end(w); 1552 spdk_jsonrpc_end_result(request, w); 1553 } 1554 SPDK_RPC_REGISTER("nvmf_get_targets", rpc_nvmf_get_targets, SPDK_RPC_RUNTIME); 1555 1556 struct nvmf_rpc_create_transport_ctx { 1557 char *trtype; 1558 char *tgt_name; 1559 struct spdk_nvmf_transport_opts opts; 1560 struct spdk_jsonrpc_request *request; 1561 }; 1562 1563 static const struct spdk_json_object_decoder nvmf_rpc_create_transport_decoder[] = { 1564 { "trtype", offsetof(struct nvmf_rpc_create_transport_ctx, trtype), spdk_json_decode_string}, 1565 { 1566 "max_queue_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_queue_depth), 1567 spdk_json_decode_uint16, true 1568 }, 1569 { 1570 "max_qpairs_per_ctrlr", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_qpairs_per_ctrlr), 1571 spdk_json_decode_uint16, true 1572 }, 1573 { 1574 "in_capsule_data_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.in_capsule_data_size), 1575 spdk_json_decode_uint32, true 1576 }, 1577 { 1578 "max_io_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_io_size), 1579 spdk_json_decode_uint32, true 1580 }, 1581 { 1582 "io_unit_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.io_unit_size), 1583 spdk_json_decode_uint32, true 1584 }, 1585 { 1586 "max_aq_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_aq_depth), 1587 spdk_json_decode_uint32, true 1588 }, 1589 { 1590 "num_shared_buffers", offsetof(struct nvmf_rpc_create_transport_ctx, opts.num_shared_buffers), 1591 spdk_json_decode_uint32, true 1592 }, 1593 { 1594 "buf_cache_size", offsetof(struct nvmf_rpc_create_transport_ctx, opts.buf_cache_size), 1595 spdk_json_decode_uint32, true 1596 }, 1597 { 1598 "max_srq_depth", offsetof(struct nvmf_rpc_create_transport_ctx, opts.max_srq_depth), 1599 spdk_json_decode_uint32, true 1600 }, 1601 { 1602 "no_srq", offsetof(struct nvmf_rpc_create_transport_ctx, opts.no_srq), 1603 spdk_json_decode_bool, true 1604 }, 1605 { 1606 "c2h_success", offsetof(struct nvmf_rpc_create_transport_ctx, opts.c2h_success), 1607 spdk_json_decode_bool, true 1608 }, 1609 { 1610 "dif_insert_or_strip", offsetof(struct nvmf_rpc_create_transport_ctx, opts.dif_insert_or_strip), 1611 spdk_json_decode_bool, true 1612 }, 1613 { 1614 "sock_priority", offsetof(struct nvmf_rpc_create_transport_ctx, opts.sock_priority), 1615 spdk_json_decode_uint32, true 1616 }, 1617 { 1618 "tgt_name", offsetof(struct nvmf_rpc_create_transport_ctx, tgt_name), 1619 spdk_json_decode_string, true 1620 }, 1621 }; 1622 1623 static void 1624 nvmf_rpc_create_transport_ctx_free(struct nvmf_rpc_create_transport_ctx *ctx) 1625 { 1626 free(ctx->trtype); 1627 free(ctx->tgt_name); 1628 free(ctx); 1629 } 1630 1631 static void 1632 nvmf_rpc_tgt_add_transport_done(void *cb_arg, int status) 1633 { 1634 struct nvmf_rpc_create_transport_ctx *ctx = cb_arg; 1635 struct spdk_jsonrpc_request *request; 1636 struct spdk_json_write_ctx *w; 1637 1638 request = ctx->request; 1639 nvmf_rpc_create_transport_ctx_free(ctx); 1640 1641 if (status) { 1642 SPDK_ERRLOG("Failed to add transport to tgt.(%d)\n", status); 1643 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1644 "Failed to add transport to tgt.(%d)\n", 1645 status); 1646 return; 1647 } 1648 1649 w = spdk_jsonrpc_begin_result(request); 1650 spdk_json_write_bool(w, true); 1651 spdk_jsonrpc_end_result(request, w); 1652 } 1653 1654 static void 1655 rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request, 1656 const struct spdk_json_val *params) 1657 { 1658 struct nvmf_rpc_create_transport_ctx *ctx; 1659 enum spdk_nvme_transport_type trtype; 1660 struct spdk_nvmf_transport *transport; 1661 struct spdk_nvmf_tgt *tgt; 1662 1663 ctx = calloc(1, sizeof(*ctx)); 1664 if (!ctx) { 1665 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); 1666 return; 1667 } 1668 1669 /* Decode parameters the first time to get the transport type */ 1670 if (spdk_json_decode_object(params, nvmf_rpc_create_transport_decoder, 1671 SPDK_COUNTOF(nvmf_rpc_create_transport_decoder), 1672 ctx)) { 1673 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1674 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1675 nvmf_rpc_create_transport_ctx_free(ctx); 1676 return; 1677 } 1678 1679 tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 1680 if (!tgt) { 1681 SPDK_ERRLOG("Unable to find a target object.\n"); 1682 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1683 "Unable to find a target."); 1684 nvmf_rpc_create_transport_ctx_free(ctx); 1685 return; 1686 } 1687 1688 if (spdk_nvme_transport_id_parse_trtype(&trtype, ctx->trtype)) { 1689 SPDK_ERRLOG("Invalid transport type '%s'\n", ctx->trtype); 1690 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 1691 "Invalid transport type '%s'\n", ctx->trtype); 1692 nvmf_rpc_create_transport_ctx_free(ctx); 1693 return; 1694 } 1695 1696 /* Initialize all the transport options (based on transport type) and decode the 1697 * parameters again to update any options passed in rpc create transport call. 1698 */ 1699 if (!spdk_nvmf_transport_opts_init(ctx->trtype, &ctx->opts)) { 1700 /* This can happen if user specifies PCIE transport type which isn't valid for 1701 * NVMe-oF. 1702 */ 1703 SPDK_ERRLOG("Invalid transport type '%s'\n", ctx->trtype); 1704 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 1705 "Invalid transport type '%s'\n", ctx->trtype); 1706 nvmf_rpc_create_transport_ctx_free(ctx); 1707 return; 1708 } 1709 1710 if (spdk_json_decode_object(params, nvmf_rpc_create_transport_decoder, 1711 SPDK_COUNTOF(nvmf_rpc_create_transport_decoder), 1712 ctx)) { 1713 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1714 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1715 nvmf_rpc_create_transport_ctx_free(ctx); 1716 return; 1717 } 1718 1719 if (spdk_nvmf_tgt_get_transport(tgt, ctx->trtype)) { 1720 SPDK_ERRLOG("Transport type '%s' already exists\n", ctx->trtype); 1721 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1722 "Transport type '%s' already exists\n", ctx->trtype); 1723 nvmf_rpc_create_transport_ctx_free(ctx); 1724 return; 1725 } 1726 1727 transport = spdk_nvmf_transport_create(ctx->trtype, &ctx->opts); 1728 1729 if (!transport) { 1730 SPDK_ERRLOG("Transport type '%s' create failed\n", ctx->trtype); 1731 spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1732 "Transport type '%s' create failed\n", ctx->trtype); 1733 nvmf_rpc_create_transport_ctx_free(ctx); 1734 return; 1735 } 1736 1737 /* add transport to target */ 1738 ctx->request = request; 1739 spdk_nvmf_tgt_add_transport(tgt, transport, nvmf_rpc_tgt_add_transport_done, ctx); 1740 } 1741 SPDK_RPC_REGISTER("nvmf_create_transport", rpc_nvmf_create_transport, SPDK_RPC_RUNTIME) 1742 1743 static void 1744 dump_nvmf_transport(struct spdk_json_write_ctx *w, struct spdk_nvmf_transport *transport) 1745 { 1746 const struct spdk_nvmf_transport_opts *opts = spdk_nvmf_get_transport_opts(transport); 1747 spdk_nvme_transport_type_t type = spdk_nvmf_get_transport_type(transport); 1748 1749 spdk_json_write_object_begin(w); 1750 1751 spdk_json_write_named_string(w, "trtype", spdk_nvmf_get_transport_name(transport)); 1752 spdk_json_write_named_uint32(w, "max_queue_depth", opts->max_queue_depth); 1753 spdk_json_write_named_uint32(w, "max_qpairs_per_ctrlr", opts->max_qpairs_per_ctrlr); 1754 spdk_json_write_named_uint32(w, "in_capsule_data_size", opts->in_capsule_data_size); 1755 spdk_json_write_named_uint32(w, "max_io_size", opts->max_io_size); 1756 spdk_json_write_named_uint32(w, "io_unit_size", opts->io_unit_size); 1757 spdk_json_write_named_uint32(w, "max_aq_depth", opts->max_aq_depth); 1758 spdk_json_write_named_uint32(w, "num_shared_buffers", opts->num_shared_buffers); 1759 spdk_json_write_named_uint32(w, "buf_cache_size", opts->buf_cache_size); 1760 spdk_json_write_named_bool(w, "dif_insert_or_strip", opts->dif_insert_or_strip); 1761 if (type == SPDK_NVME_TRANSPORT_RDMA) { 1762 spdk_json_write_named_uint32(w, "max_srq_depth", opts->max_srq_depth); 1763 spdk_json_write_named_bool(w, "no_srq", opts->no_srq); 1764 } else if (type == SPDK_NVME_TRANSPORT_TCP) { 1765 spdk_json_write_named_bool(w, "c2h_success", opts->c2h_success); 1766 spdk_json_write_named_uint32(w, "sock_priority", opts->sock_priority); 1767 } 1768 1769 spdk_json_write_object_end(w); 1770 } 1771 1772 struct rpc_get_transport { 1773 char *tgt_name; 1774 }; 1775 1776 static const struct spdk_json_object_decoder rpc_get_transport_decoders[] = { 1777 {"tgt_name", offsetof(struct rpc_get_transport, tgt_name), spdk_json_decode_string, true}, 1778 }; 1779 1780 static void 1781 rpc_nvmf_get_transports(struct spdk_jsonrpc_request *request, 1782 const struct spdk_json_val *params) 1783 { 1784 struct rpc_get_transport req = { 0 }; 1785 struct spdk_json_write_ctx *w; 1786 struct spdk_nvmf_transport *transport; 1787 struct spdk_nvmf_tgt *tgt; 1788 1789 if (params) { 1790 if (spdk_json_decode_object(params, rpc_get_transport_decoders, 1791 SPDK_COUNTOF(rpc_get_transport_decoders), 1792 &req)) { 1793 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1794 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1795 return; 1796 } 1797 } 1798 1799 tgt = spdk_nvmf_get_tgt(req.tgt_name); 1800 if (!tgt) { 1801 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1802 "Unable to find a target."); 1803 free(req.tgt_name); 1804 return; 1805 } 1806 1807 w = spdk_jsonrpc_begin_result(request); 1808 spdk_json_write_array_begin(w); 1809 transport = spdk_nvmf_transport_get_first(tgt); 1810 while (transport) { 1811 dump_nvmf_transport(w, transport); 1812 transport = spdk_nvmf_transport_get_next(transport); 1813 } 1814 spdk_json_write_array_end(w); 1815 spdk_jsonrpc_end_result(request, w); 1816 free(req.tgt_name); 1817 } 1818 SPDK_RPC_REGISTER("nvmf_get_transports", rpc_nvmf_get_transports, SPDK_RPC_RUNTIME) 1819 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_get_transports, get_nvmf_transports) 1820 1821 struct rpc_nvmf_get_stats_ctx { 1822 char *tgt_name; 1823 struct spdk_nvmf_tgt *tgt; 1824 struct spdk_jsonrpc_request *request; 1825 struct spdk_json_write_ctx *w; 1826 }; 1827 1828 static const struct spdk_json_object_decoder rpc_get_stats_decoders[] = { 1829 {"tgt_name", offsetof(struct rpc_nvmf_get_stats_ctx, tgt_name), spdk_json_decode_string, true}, 1830 }; 1831 1832 static void 1833 free_get_stats_ctx(struct rpc_nvmf_get_stats_ctx *ctx) 1834 { 1835 free(ctx->tgt_name); 1836 free(ctx); 1837 } 1838 1839 static void 1840 rpc_nvmf_get_stats_done(struct spdk_io_channel_iter *i, int status) 1841 { 1842 struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 1843 1844 spdk_json_write_array_end(ctx->w); 1845 spdk_json_write_object_end(ctx->w); 1846 spdk_jsonrpc_end_result(ctx->request, ctx->w); 1847 free_get_stats_ctx(ctx); 1848 } 1849 1850 static void 1851 write_nvmf_transport_stats(struct spdk_json_write_ctx *w, 1852 struct spdk_nvmf_transport_poll_group_stat *stat) 1853 { 1854 uint64_t i; 1855 1856 spdk_json_write_object_begin(w); 1857 spdk_json_write_named_string(w, "trtype", 1858 spdk_nvme_transport_id_trtype_str(stat->trtype)); 1859 switch (stat->trtype) { 1860 case SPDK_NVME_TRANSPORT_RDMA: 1861 spdk_json_write_named_uint64(w, "pending_data_buffer", stat->rdma.pending_data_buffer); 1862 spdk_json_write_named_array_begin(w, "devices"); 1863 for (i = 0; i < stat->rdma.num_devices; ++i) { 1864 spdk_json_write_object_begin(w); 1865 spdk_json_write_named_string(w, "name", stat->rdma.devices[i].name); 1866 spdk_json_write_named_uint64(w, "polls", stat->rdma.devices[i].polls); 1867 spdk_json_write_named_uint64(w, "completions", stat->rdma.devices[i].completions); 1868 spdk_json_write_named_uint64(w, "requests", 1869 stat->rdma.devices[i].requests); 1870 spdk_json_write_named_uint64(w, "request_latency", 1871 stat->rdma.devices[i].request_latency); 1872 spdk_json_write_named_uint64(w, "pending_free_request", 1873 stat->rdma.devices[i].pending_free_request); 1874 spdk_json_write_named_uint64(w, "pending_rdma_read", 1875 stat->rdma.devices[i].pending_rdma_read); 1876 spdk_json_write_named_uint64(w, "pending_rdma_write", 1877 stat->rdma.devices[i].pending_rdma_write); 1878 spdk_json_write_object_end(w); 1879 } 1880 spdk_json_write_array_end(w); 1881 break; 1882 default: 1883 break; 1884 } 1885 spdk_json_write_object_end(w); 1886 } 1887 1888 static void 1889 _rpc_nvmf_get_stats(struct spdk_io_channel_iter *i) 1890 { 1891 struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 1892 struct spdk_nvmf_transport *transport; 1893 struct spdk_nvmf_poll_group_stat stat; 1894 struct spdk_nvmf_transport_poll_group_stat *trstat; 1895 int rc; 1896 1897 if (0 == spdk_nvmf_poll_group_get_stat(ctx->tgt, &stat)) { 1898 spdk_json_write_object_begin(ctx->w); 1899 spdk_json_write_named_string(ctx->w, "name", spdk_thread_get_name(spdk_get_thread())); 1900 spdk_json_write_named_uint32(ctx->w, "admin_qpairs", stat.admin_qpairs); 1901 spdk_json_write_named_uint32(ctx->w, "io_qpairs", stat.io_qpairs); 1902 spdk_json_write_named_uint64(ctx->w, "pending_bdev_io", stat.pending_bdev_io); 1903 1904 spdk_json_write_named_array_begin(ctx->w, "transports"); 1905 transport = spdk_nvmf_transport_get_first(ctx->tgt); 1906 while (transport) { 1907 rc = spdk_nvmf_transport_poll_group_get_stat(ctx->tgt, transport, &trstat); 1908 if (0 == rc) { 1909 write_nvmf_transport_stats(ctx->w, trstat); 1910 spdk_nvmf_transport_poll_group_free_stat(transport, trstat); 1911 } else if (-ENOTSUP != rc) { 1912 SPDK_ERRLOG("Failed to get poll group statistics for transport %s, errno %d\n", 1913 spdk_nvme_transport_id_trtype_str(spdk_nvmf_get_transport_type(transport)), 1914 rc); 1915 } 1916 transport = spdk_nvmf_transport_get_next(transport); 1917 } 1918 spdk_json_write_array_end(ctx->w); 1919 spdk_json_write_object_end(ctx->w); 1920 } 1921 1922 spdk_for_each_channel_continue(i, 0); 1923 } 1924 1925 1926 static void 1927 rpc_nvmf_get_stats(struct spdk_jsonrpc_request *request, 1928 const struct spdk_json_val *params) 1929 { 1930 struct rpc_nvmf_get_stats_ctx *ctx; 1931 1932 ctx = calloc(1, sizeof(*ctx)); 1933 if (!ctx) { 1934 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1935 "Memory allocation error"); 1936 return; 1937 } 1938 ctx->request = request; 1939 1940 if (params) { 1941 if (spdk_json_decode_object(params, rpc_get_stats_decoders, 1942 SPDK_COUNTOF(rpc_get_stats_decoders), 1943 ctx)) { 1944 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 1945 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); 1946 free_get_stats_ctx(ctx); 1947 return; 1948 } 1949 } 1950 1951 ctx->tgt = spdk_nvmf_get_tgt(ctx->tgt_name); 1952 if (!ctx->tgt) { 1953 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1954 "Unable to find a target."); 1955 free_get_stats_ctx(ctx); 1956 return; 1957 } 1958 1959 ctx->w = spdk_jsonrpc_begin_result(ctx->request); 1960 spdk_json_write_object_begin(ctx->w); 1961 spdk_json_write_named_uint64(ctx->w, "tick_rate", spdk_get_ticks_hz()); 1962 spdk_json_write_named_array_begin(ctx->w, "poll_groups"); 1963 1964 spdk_for_each_channel(ctx->tgt, 1965 _rpc_nvmf_get_stats, 1966 ctx, 1967 rpc_nvmf_get_stats_done); 1968 } 1969 1970 SPDK_RPC_REGISTER("nvmf_get_stats", rpc_nvmf_get_stats, SPDK_RPC_RUNTIME) 1971