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