1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * 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/stdinc.h" 35 36 #include "nvmf_internal.h" 37 #include "transport.h" 38 39 #include "spdk/event.h" 40 #include "spdk/likely.h" 41 #include "spdk/string.h" 42 #include "spdk/trace.h" 43 #include "spdk/nvmf_spec.h" 44 #include "spdk/uuid.h" 45 46 #include "spdk/bdev_module.h" 47 #include "spdk_internal/log.h" 48 #include "spdk_internal/utf.h" 49 50 /* 51 * States for parsing valid domains in NQNs according to RFC 1034 52 */ 53 enum spdk_nvmf_nqn_domain_states { 54 /* First character of a domain must be a letter */ 55 SPDK_NVMF_DOMAIN_ACCEPT_LETTER = 0, 56 57 /* Subsequent characters can be any of letter, digit, or hyphen */ 58 SPDK_NVMF_DOMAIN_ACCEPT_LDH = 1, 59 60 /* A domain label must end with either a letter or digit */ 61 SPDK_NVMF_DOMAIN_ACCEPT_ANY = 2 62 }; 63 64 /* Returns true if is a valid ASCII string as defined by the NVMe spec */ 65 static bool 66 spdk_nvmf_valid_ascii_string(const void *buf, size_t size) 67 { 68 const uint8_t *str = buf; 69 size_t i; 70 71 for (i = 0; i < size; i++) { 72 if (str[i] < 0x20 || str[i] > 0x7E) { 73 return false; 74 } 75 } 76 77 return true; 78 } 79 80 static bool 81 spdk_nvmf_valid_nqn(const char *nqn) 82 { 83 size_t len; 84 struct spdk_uuid uuid_value; 85 uint32_t i; 86 int bytes_consumed; 87 uint32_t domain_label_length; 88 char *reverse_domain_end; 89 uint32_t reverse_domain_end_index; 90 enum spdk_nvmf_nqn_domain_states domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LETTER; 91 92 /* Check for length requirements */ 93 len = strlen(nqn); 94 if (len > SPDK_NVMF_NQN_MAX_LEN) { 95 SPDK_ERRLOG("Invalid NQN \"%s\": length %zu > max %d\n", nqn, len, SPDK_NVMF_NQN_MAX_LEN); 96 return false; 97 } 98 99 /* The nqn must be at least as long as SPDK_NVMF_NQN_MIN_LEN to contain the necessary prefix. */ 100 if (len < SPDK_NVMF_NQN_MIN_LEN) { 101 SPDK_ERRLOG("Invalid NQN \"%s\": length %zu < min %d\n", nqn, len, SPDK_NVMF_NQN_MIN_LEN); 102 return false; 103 } 104 105 /* Check for discovery controller nqn */ 106 if (!strcmp(nqn, SPDK_NVMF_DISCOVERY_NQN)) { 107 return true; 108 } 109 110 /* Check for equality with the generic nqn structure of the form "nqn.2014-08.org.nvmexpress:uuid:11111111-2222-3333-4444-555555555555" */ 111 if (!strncmp(nqn, SPDK_NVMF_NQN_UUID_PRE, SPDK_NVMF_NQN_UUID_PRE_LEN)) { 112 if (len != SPDK_NVMF_NQN_UUID_PRE_LEN + SPDK_NVMF_UUID_STRING_LEN) { 113 SPDK_ERRLOG("Invalid NQN \"%s\": uuid is not the correct length\n", nqn); 114 return false; 115 } 116 117 if (spdk_uuid_parse(&uuid_value, &nqn[SPDK_NVMF_NQN_UUID_PRE_LEN])) { 118 SPDK_ERRLOG("Invalid NQN \"%s\": uuid is not formatted correctly\n", nqn); 119 return false; 120 } 121 return true; 122 } 123 124 /* If the nqn does not match the uuid structure, the next several checks validate the form "nqn.yyyy-mm.reverse.domain:user-string" */ 125 126 if (strncmp(nqn, "nqn.", 4) != 0) { 127 SPDK_ERRLOG("Invalid NQN \"%s\": NQN must begin with \"nqn.\".\n", nqn); 128 return false; 129 } 130 131 /* Check for yyyy-mm. */ 132 if (!(isdigit(nqn[4]) && isdigit(nqn[5]) && isdigit(nqn[6]) && isdigit(nqn[7]) && 133 nqn[8] == '-' && isdigit(nqn[9]) && isdigit(nqn[10]) && nqn[11] == '.')) { 134 SPDK_ERRLOG("Invalid date code in NQN \"%s\"\n", nqn); 135 return false; 136 } 137 138 reverse_domain_end = strchr(nqn, ':'); 139 if (reverse_domain_end != NULL && (reverse_domain_end_index = reverse_domain_end - nqn) < len - 1) { 140 } else { 141 SPDK_ERRLOG("Invalid NQN \"%s\". NQN must contain user specified name with a ':' as a prefix.\n", 142 nqn); 143 return false; 144 } 145 146 /* Check for valid reverse domain */ 147 domain_label_length = 0; 148 for (i = 12; i < reverse_domain_end_index; i++) { 149 if (domain_label_length > SPDK_DOMAIN_LABEL_MAX_LEN) { 150 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". At least one Label is too long.\n", nqn); 151 return false; 152 } 153 154 switch (domain_state) { 155 156 case SPDK_NVMF_DOMAIN_ACCEPT_LETTER: { 157 if (isalpha(nqn[i])) { 158 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_ANY; 159 domain_label_length++; 160 break; 161 } else { 162 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must start with a letter.\n", nqn); 163 return false; 164 } 165 } 166 167 case SPDK_NVMF_DOMAIN_ACCEPT_LDH: { 168 if (isalpha(nqn[i]) || isdigit(nqn[i])) { 169 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_ANY; 170 domain_label_length++; 171 break; 172 } else if (nqn[i] == '-') { 173 if (i == reverse_domain_end_index - 1) { 174 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must end with an alphanumeric symbol.\n", 175 nqn); 176 return false; 177 } 178 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LDH; 179 domain_label_length++; 180 break; 181 } else if (nqn[i] == '.') { 182 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must end with an alphanumeric symbol.\n", 183 nqn); 184 return false; 185 } else { 186 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must contain only [a-z,A-Z,0-9,'-','.'].\n", 187 nqn); 188 return false; 189 } 190 } 191 192 case SPDK_NVMF_DOMAIN_ACCEPT_ANY: { 193 if (isalpha(nqn[i]) || isdigit(nqn[i])) { 194 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_ANY; 195 domain_label_length++; 196 break; 197 } else if (nqn[i] == '-') { 198 if (i == reverse_domain_end_index - 1) { 199 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must end with an alphanumeric symbol.\n", 200 nqn); 201 return false; 202 } 203 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LDH; 204 domain_label_length++; 205 break; 206 } else if (nqn[i] == '.') { 207 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LETTER; 208 domain_label_length = 0; 209 break; 210 } else { 211 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must contain only [a-z,A-Z,0-9,'-','.'].\n", 212 nqn); 213 return false; 214 } 215 } 216 } 217 } 218 219 i = reverse_domain_end_index + 1; 220 while (i < len) { 221 bytes_consumed = utf8_valid(&nqn[i], &nqn[len]); 222 if (bytes_consumed <= 0) { 223 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must contain only valid utf-8.\n", nqn); 224 return false; 225 } 226 227 i += bytes_consumed; 228 } 229 return true; 230 } 231 232 struct spdk_nvmf_subsystem * 233 spdk_nvmf_subsystem_create(struct spdk_nvmf_tgt *tgt, 234 const char *nqn, 235 enum spdk_nvmf_subtype type, 236 uint32_t num_ns) 237 { 238 struct spdk_nvmf_subsystem *subsystem; 239 uint32_t sid; 240 241 if (spdk_nvmf_tgt_find_subsystem(tgt, nqn)) { 242 SPDK_ERRLOG("Subsystem NQN '%s' already exists\n", nqn); 243 return NULL; 244 } 245 246 if (!spdk_nvmf_valid_nqn(nqn)) { 247 return NULL; 248 } 249 250 if (type == SPDK_NVMF_SUBTYPE_DISCOVERY && num_ns != 0) { 251 SPDK_ERRLOG("Discovery subsystem cannot have namespaces.\n"); 252 return NULL; 253 } 254 255 /* Find a free subsystem id (sid) */ 256 for (sid = 0; sid < tgt->opts.max_subsystems; sid++) { 257 if (tgt->subsystems[sid] == NULL) { 258 break; 259 } 260 } 261 if (sid >= tgt->opts.max_subsystems) { 262 return NULL; 263 } 264 265 subsystem = calloc(1, sizeof(struct spdk_nvmf_subsystem)); 266 if (subsystem == NULL) { 267 return NULL; 268 } 269 270 subsystem->thread = spdk_get_thread(); 271 subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE; 272 subsystem->tgt = tgt; 273 subsystem->id = sid; 274 subsystem->subtype = type; 275 subsystem->max_nsid = num_ns; 276 subsystem->max_allowed_nsid = num_ns; 277 subsystem->next_cntlid = 0; 278 snprintf(subsystem->subnqn, sizeof(subsystem->subnqn), "%s", nqn); 279 TAILQ_INIT(&subsystem->listeners); 280 TAILQ_INIT(&subsystem->hosts); 281 TAILQ_INIT(&subsystem->ctrlrs); 282 283 if (num_ns != 0) { 284 subsystem->ns = calloc(num_ns, sizeof(struct spdk_nvmf_ns *)); 285 if (subsystem->ns == NULL) { 286 SPDK_ERRLOG("Namespace memory allocation failed\n"); 287 free(subsystem); 288 return NULL; 289 } 290 } 291 292 tgt->subsystems[sid] = subsystem; 293 tgt->discovery_genctr++; 294 295 return subsystem; 296 } 297 298 static void 299 _spdk_nvmf_subsystem_remove_host(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_host *host) 300 { 301 TAILQ_REMOVE(&subsystem->hosts, host, link); 302 free(host->nqn); 303 free(host); 304 } 305 306 static int _spdk_nvmf_subsystem_remove_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid); 307 308 void 309 spdk_nvmf_subsystem_destroy(struct spdk_nvmf_subsystem *subsystem) 310 { 311 struct spdk_nvmf_listener *listener, *listener_tmp; 312 struct spdk_nvmf_host *host, *host_tmp; 313 struct spdk_nvmf_ctrlr *ctrlr, *ctrlr_tmp; 314 struct spdk_nvmf_ns *ns; 315 316 if (!subsystem) { 317 return; 318 } 319 320 assert(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 321 322 SPDK_DEBUGLOG(SPDK_LOG_NVMF, "subsystem is %p\n", subsystem); 323 324 TAILQ_FOREACH_SAFE(listener, &subsystem->listeners, link, listener_tmp) { 325 TAILQ_REMOVE(&subsystem->listeners, listener, link); 326 free(listener); 327 } 328 329 TAILQ_FOREACH_SAFE(host, &subsystem->hosts, link, host_tmp) { 330 _spdk_nvmf_subsystem_remove_host(subsystem, host); 331 } 332 333 TAILQ_FOREACH_SAFE(ctrlr, &subsystem->ctrlrs, link, ctrlr_tmp) { 334 spdk_nvmf_ctrlr_destruct(ctrlr); 335 } 336 337 ns = spdk_nvmf_subsystem_get_first_ns(subsystem); 338 while (ns != NULL) { 339 struct spdk_nvmf_ns *next_ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns); 340 341 _spdk_nvmf_subsystem_remove_ns(subsystem, ns->opts.nsid); 342 ns = next_ns; 343 } 344 345 free(subsystem->ns); 346 347 subsystem->tgt->subsystems[subsystem->id] = NULL; 348 subsystem->tgt->discovery_genctr++; 349 350 free(subsystem); 351 } 352 353 static int 354 spdk_nvmf_subsystem_set_state(struct spdk_nvmf_subsystem *subsystem, 355 enum spdk_nvmf_subsystem_state state) 356 { 357 enum spdk_nvmf_subsystem_state actual_old_state, expected_old_state; 358 359 switch (state) { 360 case SPDK_NVMF_SUBSYSTEM_INACTIVE: 361 expected_old_state = SPDK_NVMF_SUBSYSTEM_DEACTIVATING; 362 break; 363 case SPDK_NVMF_SUBSYSTEM_ACTIVATING: 364 expected_old_state = SPDK_NVMF_SUBSYSTEM_INACTIVE; 365 break; 366 case SPDK_NVMF_SUBSYSTEM_ACTIVE: 367 expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVATING; 368 break; 369 case SPDK_NVMF_SUBSYSTEM_PAUSING: 370 expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 371 break; 372 case SPDK_NVMF_SUBSYSTEM_PAUSED: 373 expected_old_state = SPDK_NVMF_SUBSYSTEM_PAUSING; 374 break; 375 case SPDK_NVMF_SUBSYSTEM_RESUMING: 376 expected_old_state = SPDK_NVMF_SUBSYSTEM_PAUSED; 377 break; 378 case SPDK_NVMF_SUBSYSTEM_DEACTIVATING: 379 expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 380 break; 381 default: 382 assert(false); 383 return -1; 384 } 385 386 actual_old_state = __sync_val_compare_and_swap(&subsystem->state, expected_old_state, state); 387 if (actual_old_state != expected_old_state) { 388 if (actual_old_state == SPDK_NVMF_SUBSYSTEM_RESUMING && 389 state == SPDK_NVMF_SUBSYSTEM_ACTIVE) { 390 expected_old_state = SPDK_NVMF_SUBSYSTEM_RESUMING; 391 } 392 actual_old_state = __sync_val_compare_and_swap(&subsystem->state, expected_old_state, state); 393 } 394 assert(actual_old_state == expected_old_state); 395 return actual_old_state - expected_old_state; 396 } 397 398 struct subsystem_state_change_ctx { 399 struct spdk_nvmf_subsystem *subsystem; 400 401 enum spdk_nvmf_subsystem_state requested_state; 402 403 spdk_nvmf_subsystem_state_change_done cb_fn; 404 void *cb_arg; 405 }; 406 407 static void 408 subsystem_state_change_done(struct spdk_io_channel_iter *i, int status) 409 { 410 struct subsystem_state_change_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 411 412 if (status == 0) { 413 status = spdk_nvmf_subsystem_set_state(ctx->subsystem, ctx->requested_state); 414 if (status) { 415 status = -1; 416 } 417 } 418 419 if (ctx->cb_fn) { 420 ctx->cb_fn(ctx->subsystem, ctx->cb_arg, status); 421 } 422 free(ctx); 423 } 424 425 static void 426 subsystem_state_change_on_pg(struct spdk_io_channel_iter *i) 427 { 428 struct subsystem_state_change_ctx *ctx; 429 struct spdk_io_channel *ch; 430 struct spdk_nvmf_poll_group *group; 431 int rc = -1; 432 433 ctx = spdk_io_channel_iter_get_ctx(i); 434 ch = spdk_io_channel_iter_get_channel(i); 435 group = spdk_io_channel_get_ctx(ch); 436 437 switch (ctx->requested_state) { 438 case SPDK_NVMF_SUBSYSTEM_INACTIVE: 439 rc = spdk_nvmf_poll_group_remove_subsystem(group, ctx->subsystem); 440 break; 441 case SPDK_NVMF_SUBSYSTEM_ACTIVE: 442 if (ctx->subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVATING) { 443 rc = spdk_nvmf_poll_group_add_subsystem(group, ctx->subsystem); 444 } else if (ctx->subsystem->state == SPDK_NVMF_SUBSYSTEM_RESUMING) { 445 rc = spdk_nvmf_poll_group_resume_subsystem(group, ctx->subsystem); 446 } 447 break; 448 case SPDK_NVMF_SUBSYSTEM_PAUSED: 449 rc = spdk_nvmf_poll_group_pause_subsystem(group, ctx->subsystem); 450 break; 451 default: 452 assert(false); 453 break; 454 } 455 456 spdk_for_each_channel_continue(i, rc); 457 } 458 459 static int 460 spdk_nvmf_subsystem_state_change(struct spdk_nvmf_subsystem *subsystem, 461 enum spdk_nvmf_subsystem_state requested_state, 462 spdk_nvmf_subsystem_state_change_done cb_fn, 463 void *cb_arg) 464 { 465 struct subsystem_state_change_ctx *ctx; 466 enum spdk_nvmf_subsystem_state intermediate_state; 467 int rc; 468 469 switch (requested_state) { 470 case SPDK_NVMF_SUBSYSTEM_INACTIVE: 471 intermediate_state = SPDK_NVMF_SUBSYSTEM_DEACTIVATING; 472 break; 473 case SPDK_NVMF_SUBSYSTEM_ACTIVE: 474 if (subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED) { 475 intermediate_state = SPDK_NVMF_SUBSYSTEM_RESUMING; 476 } else { 477 intermediate_state = SPDK_NVMF_SUBSYSTEM_ACTIVATING; 478 } 479 break; 480 case SPDK_NVMF_SUBSYSTEM_PAUSED: 481 intermediate_state = SPDK_NVMF_SUBSYSTEM_PAUSING; 482 break; 483 default: 484 assert(false); 485 return -EINVAL; 486 } 487 488 ctx = calloc(1, sizeof(*ctx)); 489 if (!ctx) { 490 return -ENOMEM; 491 } 492 493 rc = spdk_nvmf_subsystem_set_state(subsystem, intermediate_state); 494 if (rc) { 495 free(ctx); 496 return rc; 497 } 498 499 ctx->subsystem = subsystem; 500 ctx->requested_state = requested_state; 501 ctx->cb_fn = cb_fn; 502 ctx->cb_arg = cb_arg; 503 504 spdk_for_each_channel(subsystem->tgt, 505 subsystem_state_change_on_pg, 506 ctx, 507 subsystem_state_change_done); 508 509 return 0; 510 } 511 512 int 513 spdk_nvmf_subsystem_start(struct spdk_nvmf_subsystem *subsystem, 514 spdk_nvmf_subsystem_state_change_done cb_fn, 515 void *cb_arg) 516 { 517 return spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_ACTIVE, cb_fn, cb_arg); 518 } 519 520 int 521 spdk_nvmf_subsystem_stop(struct spdk_nvmf_subsystem *subsystem, 522 spdk_nvmf_subsystem_state_change_done cb_fn, 523 void *cb_arg) 524 { 525 return spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_INACTIVE, cb_fn, cb_arg); 526 } 527 528 int 529 spdk_nvmf_subsystem_pause(struct spdk_nvmf_subsystem *subsystem, 530 spdk_nvmf_subsystem_state_change_done cb_fn, 531 void *cb_arg) 532 { 533 return spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_PAUSED, cb_fn, cb_arg); 534 } 535 536 int 537 spdk_nvmf_subsystem_resume(struct spdk_nvmf_subsystem *subsystem, 538 spdk_nvmf_subsystem_state_change_done cb_fn, 539 void *cb_arg) 540 { 541 return spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_ACTIVE, cb_fn, cb_arg); 542 } 543 544 struct spdk_nvmf_subsystem * 545 spdk_nvmf_subsystem_get_first(struct spdk_nvmf_tgt *tgt) 546 { 547 struct spdk_nvmf_subsystem *subsystem; 548 uint32_t sid; 549 550 for (sid = 0; sid < tgt->opts.max_subsystems; sid++) { 551 subsystem = tgt->subsystems[sid]; 552 if (subsystem) { 553 return subsystem; 554 } 555 } 556 557 return NULL; 558 } 559 560 struct spdk_nvmf_subsystem * 561 spdk_nvmf_subsystem_get_next(struct spdk_nvmf_subsystem *subsystem) 562 { 563 uint32_t sid; 564 struct spdk_nvmf_tgt *tgt; 565 566 if (!subsystem) { 567 return NULL; 568 } 569 570 tgt = subsystem->tgt; 571 572 for (sid = subsystem->id + 1; sid < tgt->opts.max_subsystems; sid++) { 573 subsystem = tgt->subsystems[sid]; 574 if (subsystem) { 575 return subsystem; 576 } 577 } 578 579 return NULL; 580 } 581 582 static struct spdk_nvmf_host * 583 _spdk_nvmf_subsystem_find_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn) 584 { 585 struct spdk_nvmf_host *host = NULL; 586 587 TAILQ_FOREACH(host, &subsystem->hosts, link) { 588 if (strcmp(hostnqn, host->nqn) == 0) { 589 return host; 590 } 591 } 592 593 return NULL; 594 } 595 596 int 597 spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn) 598 { 599 struct spdk_nvmf_host *host; 600 601 if (!spdk_nvmf_valid_nqn(hostnqn)) { 602 return -EINVAL; 603 } 604 605 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 606 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 607 return -EAGAIN; 608 } 609 610 if (_spdk_nvmf_subsystem_find_host(subsystem, hostnqn)) { 611 /* This subsystem already allows the specified host. */ 612 return 0; 613 } 614 615 host = calloc(1, sizeof(*host)); 616 if (!host) { 617 return -ENOMEM; 618 } 619 host->nqn = strdup(hostnqn); 620 if (!host->nqn) { 621 free(host); 622 return -ENOMEM; 623 } 624 625 TAILQ_INSERT_HEAD(&subsystem->hosts, host, link); 626 subsystem->tgt->discovery_genctr++; 627 628 return 0; 629 } 630 631 int 632 spdk_nvmf_subsystem_remove_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn) 633 { 634 struct spdk_nvmf_host *host; 635 636 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 637 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 638 return -EAGAIN; 639 } 640 641 host = _spdk_nvmf_subsystem_find_host(subsystem, hostnqn); 642 if (host == NULL) { 643 return -ENOENT; 644 } 645 646 _spdk_nvmf_subsystem_remove_host(subsystem, host); 647 return 0; 648 } 649 650 int 651 spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, bool allow_any_host) 652 { 653 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 654 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 655 return -EAGAIN; 656 } 657 658 subsystem->allow_any_host = allow_any_host; 659 660 return 0; 661 } 662 663 bool 664 spdk_nvmf_subsystem_get_allow_any_host(const struct spdk_nvmf_subsystem *subsystem) 665 { 666 return subsystem->allow_any_host; 667 } 668 669 bool 670 spdk_nvmf_subsystem_host_allowed(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn) 671 { 672 if (!hostnqn) { 673 return false; 674 } 675 676 if (subsystem->allow_any_host) { 677 return true; 678 } 679 680 return _spdk_nvmf_subsystem_find_host(subsystem, hostnqn) != NULL; 681 } 682 683 struct spdk_nvmf_host * 684 spdk_nvmf_subsystem_get_first_host(struct spdk_nvmf_subsystem *subsystem) 685 { 686 return TAILQ_FIRST(&subsystem->hosts); 687 } 688 689 690 struct spdk_nvmf_host * 691 spdk_nvmf_subsystem_get_next_host(struct spdk_nvmf_subsystem *subsystem, 692 struct spdk_nvmf_host *prev_host) 693 { 694 return TAILQ_NEXT(prev_host, link); 695 } 696 697 const char * 698 spdk_nvmf_host_get_nqn(struct spdk_nvmf_host *host) 699 { 700 return host->nqn; 701 } 702 703 static struct spdk_nvmf_listener * 704 _spdk_nvmf_subsystem_find_listener(struct spdk_nvmf_subsystem *subsystem, 705 const struct spdk_nvme_transport_id *trid) 706 { 707 struct spdk_nvmf_listener *listener; 708 709 TAILQ_FOREACH(listener, &subsystem->listeners, link) { 710 if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) { 711 return listener; 712 } 713 } 714 715 return NULL; 716 } 717 718 int 719 spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem, 720 struct spdk_nvme_transport_id *trid) 721 { 722 struct spdk_nvmf_transport *transport; 723 struct spdk_nvmf_listener *listener; 724 725 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 726 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 727 return -EAGAIN; 728 } 729 730 if (_spdk_nvmf_subsystem_find_listener(subsystem, trid)) { 731 /* Listener already exists in this subsystem */ 732 return 0; 733 } 734 735 transport = spdk_nvmf_tgt_get_transport(subsystem->tgt, trid->trtype); 736 if (transport == NULL) { 737 SPDK_ERRLOG("Unknown transport type %d\n", trid->trtype); 738 return -EINVAL; 739 } 740 741 listener = calloc(1, sizeof(*listener)); 742 if (!listener) { 743 return -ENOMEM; 744 } 745 746 listener->trid = *trid; 747 listener->transport = transport; 748 749 TAILQ_INSERT_HEAD(&subsystem->listeners, listener, link); 750 751 return 0; 752 } 753 754 int 755 spdk_nvmf_subsystem_remove_listener(struct spdk_nvmf_subsystem *subsystem, 756 const struct spdk_nvme_transport_id *trid) 757 { 758 struct spdk_nvmf_listener *listener; 759 760 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 761 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 762 return -EAGAIN; 763 } 764 765 listener = _spdk_nvmf_subsystem_find_listener(subsystem, trid); 766 if (listener == NULL) { 767 return -ENOENT; 768 } 769 770 TAILQ_REMOVE(&subsystem->listeners, listener, link); 771 free(listener); 772 773 return 0; 774 } 775 776 /* 777 * TODO: this is the whitelist and will be called during connection setup 778 */ 779 bool 780 spdk_nvmf_subsystem_listener_allowed(struct spdk_nvmf_subsystem *subsystem, 781 struct spdk_nvme_transport_id *trid) 782 { 783 struct spdk_nvmf_listener *listener; 784 785 if (TAILQ_EMPTY(&subsystem->listeners)) { 786 return true; 787 } 788 789 TAILQ_FOREACH(listener, &subsystem->listeners, link) { 790 if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) { 791 return true; 792 } 793 } 794 795 return false; 796 } 797 798 struct spdk_nvmf_listener * 799 spdk_nvmf_subsystem_get_first_listener(struct spdk_nvmf_subsystem *subsystem) 800 { 801 return TAILQ_FIRST(&subsystem->listeners); 802 } 803 804 struct spdk_nvmf_listener * 805 spdk_nvmf_subsystem_get_next_listener(struct spdk_nvmf_subsystem *subsystem, 806 struct spdk_nvmf_listener *prev_listener) 807 { 808 return TAILQ_NEXT(prev_listener, link); 809 } 810 811 const struct spdk_nvme_transport_id * 812 spdk_nvmf_listener_get_trid(struct spdk_nvmf_listener *listener) 813 { 814 return &listener->trid; 815 } 816 817 struct subsystem_update_ns_ctx { 818 struct spdk_nvmf_subsystem *subsystem; 819 820 spdk_nvmf_subsystem_state_change_done cb_fn; 821 void *cb_arg; 822 }; 823 824 static void 825 subsystem_update_ns_done(struct spdk_io_channel_iter *i, int status) 826 { 827 struct subsystem_update_ns_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 828 829 if (ctx->cb_fn) { 830 ctx->cb_fn(ctx->subsystem, ctx->cb_arg, status); 831 } 832 free(ctx); 833 } 834 835 static void 836 subsystem_update_ns_on_pg(struct spdk_io_channel_iter *i) 837 { 838 int rc; 839 struct subsystem_update_ns_ctx *ctx; 840 struct spdk_nvmf_poll_group *group; 841 struct spdk_nvmf_subsystem *subsystem; 842 843 ctx = spdk_io_channel_iter_get_ctx(i); 844 group = spdk_io_channel_get_ctx(spdk_io_channel_iter_get_channel(i)); 845 subsystem = ctx->subsystem; 846 847 rc = spdk_nvmf_poll_group_update_subsystem(group, subsystem); 848 spdk_for_each_channel_continue(i, rc); 849 } 850 851 static int 852 spdk_nvmf_subsystem_update_ns(struct spdk_nvmf_subsystem *subsystem, spdk_channel_for_each_cpl cpl, 853 void *ctx) 854 { 855 spdk_for_each_channel(subsystem->tgt, 856 subsystem_update_ns_on_pg, 857 ctx, 858 cpl); 859 860 return 0; 861 } 862 863 static void 864 spdk_nvmf_subsystem_ns_changed(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) 865 { 866 struct spdk_nvmf_ctrlr *ctrlr; 867 868 TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { 869 spdk_nvmf_ctrlr_ns_changed(ctrlr, nsid); 870 } 871 } 872 873 static int 874 _spdk_nvmf_subsystem_remove_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) 875 { 876 struct spdk_nvmf_ns *ns; 877 878 assert(subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED || 879 subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); 880 881 if (nsid == 0 || nsid > subsystem->max_nsid) { 882 return -1; 883 } 884 885 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 886 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 887 return -1; 888 } 889 890 ns = subsystem->ns[nsid - 1]; 891 if (!ns) { 892 return -1; 893 } 894 895 subsystem->ns[nsid - 1] = NULL; 896 897 spdk_bdev_close(ns->desc); 898 free(ns); 899 900 spdk_nvmf_subsystem_ns_changed(subsystem, nsid); 901 902 return 0; 903 } 904 905 int 906 spdk_nvmf_subsystem_remove_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid, 907 spdk_nvmf_subsystem_state_change_done cb_fn, void *cb_arg) 908 { 909 int rc; 910 struct subsystem_update_ns_ctx *ctx; 911 912 rc = _spdk_nvmf_subsystem_remove_ns(subsystem, nsid); 913 if (rc < 0) { 914 return rc; 915 } 916 917 ctx = calloc(1, sizeof(*ctx)); 918 919 if (ctx == NULL) { 920 return -ENOMEM; 921 } 922 923 ctx->subsystem = subsystem; 924 ctx->cb_fn = cb_fn; 925 ctx->cb_arg = cb_arg; 926 927 spdk_nvmf_subsystem_update_ns(subsystem, subsystem_update_ns_done, ctx); 928 929 return 0; 930 } 931 932 static void 933 _spdk_nvmf_ns_hot_remove_done(struct spdk_nvmf_subsystem *subsystem, void *cb_arg, int status) 934 { 935 if (status != 0) { 936 SPDK_ERRLOG("Failed to make changes to NVMe-oF subsystem with id %u\n", subsystem->id); 937 } 938 spdk_nvmf_subsystem_resume(subsystem, NULL, NULL); 939 } 940 941 static void 942 _spdk_nvmf_ns_hot_remove(struct spdk_nvmf_subsystem *subsystem, 943 void *cb_arg, int status) 944 { 945 struct spdk_nvmf_ns *ns = cb_arg; 946 947 spdk_nvmf_subsystem_remove_ns(subsystem, ns->opts.nsid, _spdk_nvmf_ns_hot_remove_done, 948 subsystem); 949 } 950 951 static void 952 spdk_nvmf_ns_hot_remove(void *remove_ctx) 953 { 954 struct spdk_nvmf_ns *ns = remove_ctx; 955 int rc; 956 957 rc = spdk_nvmf_subsystem_pause(ns->subsystem, _spdk_nvmf_ns_hot_remove, ns); 958 if (rc) { 959 SPDK_ERRLOG("Unable to pause subsystem to process namespace removal!\n"); 960 } 961 } 962 963 void 964 spdk_nvmf_ns_opts_get_defaults(struct spdk_nvmf_ns_opts *opts, size_t opts_size) 965 { 966 /* All current fields are set to 0 by default. */ 967 memset(opts, 0, opts_size); 968 } 969 970 uint32_t 971 spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bdev *bdev, 972 const struct spdk_nvmf_ns_opts *user_opts, size_t opts_size) 973 { 974 struct spdk_nvmf_ns_opts opts; 975 struct spdk_nvmf_ns *ns; 976 int rc; 977 978 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 979 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 980 return 0; 981 } 982 983 spdk_nvmf_ns_opts_get_defaults(&opts, sizeof(opts)); 984 if (user_opts) { 985 memcpy(&opts, user_opts, spdk_min(sizeof(opts), opts_size)); 986 } 987 988 if (spdk_mem_all_zero(&opts.uuid, sizeof(opts.uuid))) { 989 opts.uuid = *spdk_bdev_get_uuid(bdev); 990 } 991 992 if (opts.nsid == SPDK_NVME_GLOBAL_NS_TAG) { 993 SPDK_ERRLOG("Invalid NSID %" PRIu32 "\n", opts.nsid); 994 return 0; 995 } 996 997 if (opts.nsid == 0) { 998 /* 999 * NSID not specified - find a free index. 1000 * 1001 * If no free slots are found, opts.nsid will be subsystem->max_nsid + 1, which will 1002 * expand max_nsid if possible. 1003 */ 1004 for (opts.nsid = 1; opts.nsid <= subsystem->max_nsid; opts.nsid++) { 1005 if (_spdk_nvmf_subsystem_get_ns(subsystem, opts.nsid) == NULL) { 1006 break; 1007 } 1008 } 1009 } 1010 1011 if (_spdk_nvmf_subsystem_get_ns(subsystem, opts.nsid)) { 1012 SPDK_ERRLOG("Requested NSID %" PRIu32 " already in use\n", opts.nsid); 1013 return 0; 1014 } 1015 1016 if (opts.nsid > subsystem->max_nsid) { 1017 struct spdk_nvmf_ns **new_ns_array; 1018 1019 /* If MaxNamespaces was specified, we can't extend max_nsid beyond it. */ 1020 if (subsystem->max_allowed_nsid > 0 && opts.nsid > subsystem->max_allowed_nsid) { 1021 SPDK_ERRLOG("Can't extend NSID range above MaxNamespaces\n"); 1022 return 0; 1023 } 1024 1025 /* If a controller is connected, we can't change NN. */ 1026 if (!TAILQ_EMPTY(&subsystem->ctrlrs)) { 1027 SPDK_ERRLOG("Can't extend NSID range while controllers are connected\n"); 1028 return 0; 1029 } 1030 1031 new_ns_array = realloc(subsystem->ns, sizeof(struct spdk_nvmf_ns *) * opts.nsid); 1032 if (new_ns_array == NULL) { 1033 SPDK_ERRLOG("Memory allocation error while resizing namespace array.\n"); 1034 return 0; 1035 } 1036 1037 memset(new_ns_array + subsystem->max_nsid, 0, 1038 sizeof(struct spdk_nvmf_ns *) * (opts.nsid - subsystem->max_nsid)); 1039 subsystem->ns = new_ns_array; 1040 subsystem->max_nsid = opts.nsid; 1041 } 1042 1043 ns = calloc(1, sizeof(*ns)); 1044 if (ns == NULL) { 1045 SPDK_ERRLOG("Namespace allocation failed\n"); 1046 return 0; 1047 } 1048 1049 ns->bdev = bdev; 1050 ns->opts = opts; 1051 ns->subsystem = subsystem; 1052 rc = spdk_bdev_open(bdev, true, spdk_nvmf_ns_hot_remove, ns, &ns->desc); 1053 if (rc != 0) { 1054 SPDK_ERRLOG("Subsystem %s: bdev %s cannot be opened, error=%d\n", 1055 subsystem->subnqn, spdk_bdev_get_name(bdev), rc); 1056 free(ns); 1057 return 0; 1058 } 1059 subsystem->ns[opts.nsid - 1] = ns; 1060 1061 SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Subsystem %s: bdev %s assigned nsid %" PRIu32 "\n", 1062 spdk_nvmf_subsystem_get_nqn(subsystem), 1063 spdk_bdev_get_name(bdev), 1064 opts.nsid); 1065 1066 spdk_nvmf_subsystem_ns_changed(subsystem, opts.nsid); 1067 1068 return opts.nsid; 1069 } 1070 1071 static uint32_t 1072 spdk_nvmf_subsystem_get_next_allocated_nsid(struct spdk_nvmf_subsystem *subsystem, 1073 uint32_t prev_nsid) 1074 { 1075 uint32_t nsid; 1076 1077 if (prev_nsid >= subsystem->max_nsid) { 1078 return 0; 1079 } 1080 1081 for (nsid = prev_nsid + 1; nsid <= subsystem->max_nsid; nsid++) { 1082 if (subsystem->ns[nsid - 1]) { 1083 return nsid; 1084 } 1085 } 1086 1087 return 0; 1088 } 1089 1090 struct spdk_nvmf_ns * 1091 spdk_nvmf_subsystem_get_first_ns(struct spdk_nvmf_subsystem *subsystem) 1092 { 1093 uint32_t first_nsid; 1094 1095 first_nsid = spdk_nvmf_subsystem_get_next_allocated_nsid(subsystem, 0); 1096 return _spdk_nvmf_subsystem_get_ns(subsystem, first_nsid); 1097 } 1098 1099 struct spdk_nvmf_ns * 1100 spdk_nvmf_subsystem_get_next_ns(struct spdk_nvmf_subsystem *subsystem, 1101 struct spdk_nvmf_ns *prev_ns) 1102 { 1103 uint32_t next_nsid; 1104 1105 next_nsid = spdk_nvmf_subsystem_get_next_allocated_nsid(subsystem, prev_ns->opts.nsid); 1106 return _spdk_nvmf_subsystem_get_ns(subsystem, next_nsid); 1107 } 1108 1109 struct spdk_nvmf_ns * 1110 spdk_nvmf_subsystem_get_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) 1111 { 1112 return _spdk_nvmf_subsystem_get_ns(subsystem, nsid); 1113 } 1114 1115 uint32_t 1116 spdk_nvmf_ns_get_id(const struct spdk_nvmf_ns *ns) 1117 { 1118 return ns->opts.nsid; 1119 } 1120 1121 struct spdk_bdev * 1122 spdk_nvmf_ns_get_bdev(struct spdk_nvmf_ns *ns) 1123 { 1124 return ns->bdev; 1125 } 1126 1127 void 1128 spdk_nvmf_ns_get_opts(const struct spdk_nvmf_ns *ns, struct spdk_nvmf_ns_opts *opts, 1129 size_t opts_size) 1130 { 1131 memset(opts, 0, opts_size); 1132 memcpy(opts, &ns->opts, spdk_min(sizeof(ns->opts), opts_size)); 1133 } 1134 1135 const char * 1136 spdk_nvmf_subsystem_get_sn(const struct spdk_nvmf_subsystem *subsystem) 1137 { 1138 return subsystem->sn; 1139 } 1140 1141 int 1142 spdk_nvmf_subsystem_set_sn(struct spdk_nvmf_subsystem *subsystem, const char *sn) 1143 { 1144 size_t len, max_len; 1145 1146 max_len = sizeof(subsystem->sn) - 1; 1147 len = strlen(sn); 1148 if (len > max_len) { 1149 SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Invalid sn \"%s\": length %zu > max %zu\n", 1150 sn, len, max_len); 1151 return -1; 1152 } 1153 1154 if (!spdk_nvmf_valid_ascii_string(sn, len)) { 1155 SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Non-ASCII sn\n"); 1156 SPDK_TRACEDUMP(SPDK_LOG_NVMF, "sn", sn, len); 1157 return -1; 1158 } 1159 1160 snprintf(subsystem->sn, sizeof(subsystem->sn), "%s", sn); 1161 1162 return 0; 1163 } 1164 1165 const char * 1166 spdk_nvmf_subsystem_get_nqn(struct spdk_nvmf_subsystem *subsystem) 1167 { 1168 return subsystem->subnqn; 1169 } 1170 1171 /* Workaround for astyle formatting bug */ 1172 typedef enum spdk_nvmf_subtype nvmf_subtype_t; 1173 1174 nvmf_subtype_t 1175 spdk_nvmf_subsystem_get_type(struct spdk_nvmf_subsystem *subsystem) 1176 { 1177 return subsystem->subtype; 1178 } 1179 1180 static uint16_t 1181 spdk_nvmf_subsystem_gen_cntlid(struct spdk_nvmf_subsystem *subsystem) 1182 { 1183 int count; 1184 1185 /* 1186 * In the worst case, we might have to try all CNTLID values between 1 and 0xFFF0 - 1 1187 * before we find one that is unused (or find that all values are in use). 1188 */ 1189 for (count = 0; count < 0xFFF0 - 1; count++) { 1190 subsystem->next_cntlid++; 1191 if (subsystem->next_cntlid >= 0xFFF0) { 1192 /* The spec reserves cntlid values in the range FFF0h to FFFFh. */ 1193 subsystem->next_cntlid = 1; 1194 } 1195 1196 /* Check if a controller with this cntlid currently exists. */ 1197 if (spdk_nvmf_subsystem_get_ctrlr(subsystem, subsystem->next_cntlid) == NULL) { 1198 /* Found unused cntlid */ 1199 return subsystem->next_cntlid; 1200 } 1201 } 1202 1203 /* All valid cntlid values are in use. */ 1204 return 0xFFFF; 1205 } 1206 1207 int 1208 spdk_nvmf_subsystem_add_ctrlr(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr) 1209 { 1210 ctrlr->cntlid = spdk_nvmf_subsystem_gen_cntlid(subsystem); 1211 if (ctrlr->cntlid == 0xFFFF) { 1212 /* Unable to get a cntlid */ 1213 SPDK_ERRLOG("Reached max simultaneous ctrlrs\n"); 1214 return -EBUSY; 1215 } 1216 1217 TAILQ_INSERT_TAIL(&subsystem->ctrlrs, ctrlr, link); 1218 1219 return 0; 1220 } 1221 1222 void 1223 spdk_nvmf_subsystem_remove_ctrlr(struct spdk_nvmf_subsystem *subsystem, 1224 struct spdk_nvmf_ctrlr *ctrlr) 1225 { 1226 assert(subsystem == ctrlr->subsys); 1227 TAILQ_REMOVE(&subsystem->ctrlrs, ctrlr, link); 1228 } 1229 1230 struct spdk_nvmf_ctrlr * 1231 spdk_nvmf_subsystem_get_ctrlr(struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid) 1232 { 1233 struct spdk_nvmf_ctrlr *ctrlr; 1234 1235 TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { 1236 if (ctrlr->cntlid == cntlid) { 1237 return ctrlr; 1238 } 1239 } 1240 1241 return NULL; 1242 } 1243 1244 uint32_t 1245 spdk_nvmf_subsystem_get_max_namespaces(const struct spdk_nvmf_subsystem *subsystem) 1246 { 1247 return subsystem->max_allowed_nsid; 1248 } 1249