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