1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2016 Intel Corporation. All rights reserved. 3 * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 */ 6 7 #include "spdk/stdinc.h" 8 9 #include "nvmf_internal.h" 10 #include "transport.h" 11 12 #include "spdk/assert.h" 13 #include "spdk/likely.h" 14 #include "spdk/string.h" 15 #include "spdk/trace.h" 16 #include "spdk/nvmf_spec.h" 17 #include "spdk/uuid.h" 18 #include "spdk/json.h" 19 #include "spdk/file.h" 20 #include "spdk/bit_array.h" 21 #include "spdk/bdev.h" 22 23 #define __SPDK_BDEV_MODULE_ONLY 24 #include "spdk/bdev_module.h" 25 #include "spdk/log.h" 26 #include "spdk_internal/utf.h" 27 #include "spdk_internal/usdt.h" 28 29 #define MODEL_NUMBER_DEFAULT "SPDK bdev Controller" 30 #define NVMF_SUBSYSTEM_DEFAULT_NAMESPACES 32 31 32 /* 33 * States for parsing valid domains in NQNs according to RFC 1034 34 */ 35 enum spdk_nvmf_nqn_domain_states { 36 /* First character of a domain must be a letter */ 37 SPDK_NVMF_DOMAIN_ACCEPT_LETTER = 0, 38 39 /* Subsequent characters can be any of letter, digit, or hyphen */ 40 SPDK_NVMF_DOMAIN_ACCEPT_LDH = 1, 41 42 /* A domain label must end with either a letter or digit */ 43 SPDK_NVMF_DOMAIN_ACCEPT_ANY = 2 44 }; 45 46 static int _nvmf_subsystem_destroy(struct spdk_nvmf_subsystem *subsystem); 47 48 /* Returns true if is a valid ASCII string as defined by the NVMe spec */ 49 static bool 50 nvmf_valid_ascii_string(const void *buf, size_t size) 51 { 52 const uint8_t *str = buf; 53 size_t i; 54 55 for (i = 0; i < size; i++) { 56 if (str[i] < 0x20 || str[i] > 0x7E) { 57 return false; 58 } 59 } 60 61 return true; 62 } 63 64 static bool 65 nvmf_valid_nqn(const char *nqn) 66 { 67 size_t len; 68 struct spdk_uuid uuid_value; 69 uint32_t i; 70 int bytes_consumed; 71 uint32_t domain_label_length; 72 char *reverse_domain_end; 73 uint32_t reverse_domain_end_index; 74 enum spdk_nvmf_nqn_domain_states domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LETTER; 75 76 /* Check for length requirements */ 77 len = strlen(nqn); 78 if (len > SPDK_NVMF_NQN_MAX_LEN) { 79 SPDK_ERRLOG("Invalid NQN \"%s\": length %zu > max %d\n", nqn, len, SPDK_NVMF_NQN_MAX_LEN); 80 return false; 81 } 82 83 /* The nqn must be at least as long as SPDK_NVMF_NQN_MIN_LEN to contain the necessary prefix. */ 84 if (len < SPDK_NVMF_NQN_MIN_LEN) { 85 SPDK_ERRLOG("Invalid NQN \"%s\": length %zu < min %d\n", nqn, len, SPDK_NVMF_NQN_MIN_LEN); 86 return false; 87 } 88 89 /* Check for discovery controller nqn */ 90 if (!strcmp(nqn, SPDK_NVMF_DISCOVERY_NQN)) { 91 return true; 92 } 93 94 /* Check for equality with the generic nqn structure of the form "nqn.2014-08.org.nvmexpress:uuid:11111111-2222-3333-4444-555555555555" */ 95 if (!strncmp(nqn, SPDK_NVMF_NQN_UUID_PRE, SPDK_NVMF_NQN_UUID_PRE_LEN)) { 96 if (len != SPDK_NVMF_NQN_UUID_PRE_LEN + SPDK_NVMF_UUID_STRING_LEN) { 97 SPDK_ERRLOG("Invalid NQN \"%s\": uuid is not the correct length\n", nqn); 98 return false; 99 } 100 101 if (spdk_uuid_parse(&uuid_value, &nqn[SPDK_NVMF_NQN_UUID_PRE_LEN])) { 102 SPDK_ERRLOG("Invalid NQN \"%s\": uuid is not formatted correctly\n", nqn); 103 return false; 104 } 105 return true; 106 } 107 108 /* If the nqn does not match the uuid structure, the next several checks validate the form "nqn.yyyy-mm.reverse.domain:user-string" */ 109 110 if (strncmp(nqn, "nqn.", 4) != 0) { 111 SPDK_ERRLOG("Invalid NQN \"%s\": NQN must begin with \"nqn.\".\n", nqn); 112 return false; 113 } 114 115 /* Check for yyyy-mm. */ 116 if (!(isdigit(nqn[4]) && isdigit(nqn[5]) && isdigit(nqn[6]) && isdigit(nqn[7]) && 117 nqn[8] == '-' && isdigit(nqn[9]) && isdigit(nqn[10]) && nqn[11] == '.')) { 118 SPDK_ERRLOG("Invalid date code in NQN \"%s\"\n", nqn); 119 return false; 120 } 121 122 reverse_domain_end = strchr(nqn, ':'); 123 if (reverse_domain_end != NULL && (reverse_domain_end_index = reverse_domain_end - nqn) < len - 1) { 124 } else { 125 SPDK_ERRLOG("Invalid NQN \"%s\". NQN must contain user specified name with a ':' as a prefix.\n", 126 nqn); 127 return false; 128 } 129 130 /* Check for valid reverse domain */ 131 domain_label_length = 0; 132 for (i = 12; i < reverse_domain_end_index; i++) { 133 if (domain_label_length > SPDK_DOMAIN_LABEL_MAX_LEN) { 134 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". At least one Label is too long.\n", nqn); 135 return false; 136 } 137 138 switch (domain_state) { 139 140 case SPDK_NVMF_DOMAIN_ACCEPT_LETTER: { 141 if (isalpha(nqn[i])) { 142 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_ANY; 143 domain_label_length++; 144 break; 145 } else { 146 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must start with a letter.\n", nqn); 147 return false; 148 } 149 } 150 151 case SPDK_NVMF_DOMAIN_ACCEPT_LDH: { 152 if (isalpha(nqn[i]) || isdigit(nqn[i])) { 153 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_ANY; 154 domain_label_length++; 155 break; 156 } else if (nqn[i] == '-') { 157 if (i == reverse_domain_end_index - 1) { 158 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must end with an alphanumeric symbol.\n", 159 nqn); 160 return false; 161 } 162 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LDH; 163 domain_label_length++; 164 break; 165 } else if (nqn[i] == '.') { 166 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must end with an alphanumeric symbol.\n", 167 nqn); 168 return false; 169 } else { 170 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must contain only [a-z,A-Z,0-9,'-','.'].\n", 171 nqn); 172 return false; 173 } 174 } 175 176 case SPDK_NVMF_DOMAIN_ACCEPT_ANY: { 177 if (isalpha(nqn[i]) || isdigit(nqn[i])) { 178 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_ANY; 179 domain_label_length++; 180 break; 181 } else if (nqn[i] == '-') { 182 if (i == reverse_domain_end_index - 1) { 183 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must end with an alphanumeric symbol.\n", 184 nqn); 185 return false; 186 } 187 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LDH; 188 domain_label_length++; 189 break; 190 } else if (nqn[i] == '.') { 191 domain_state = SPDK_NVMF_DOMAIN_ACCEPT_LETTER; 192 domain_label_length = 0; 193 break; 194 } else { 195 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must contain only [a-z,A-Z,0-9,'-','.'].\n", 196 nqn); 197 return false; 198 } 199 } 200 } 201 } 202 203 i = reverse_domain_end_index + 1; 204 while (i < len) { 205 bytes_consumed = utf8_valid(&nqn[i], &nqn[len]); 206 if (bytes_consumed <= 0) { 207 SPDK_ERRLOG("Invalid domain name in NQN \"%s\". Label names must contain only valid utf-8.\n", nqn); 208 return false; 209 } 210 211 i += bytes_consumed; 212 } 213 return true; 214 } 215 216 static void subsystem_state_change_on_pg(struct spdk_io_channel_iter *i); 217 218 struct spdk_nvmf_subsystem * 219 spdk_nvmf_subsystem_create(struct spdk_nvmf_tgt *tgt, 220 const char *nqn, 221 enum spdk_nvmf_subtype type, 222 uint32_t num_ns) 223 { 224 struct spdk_nvmf_subsystem *subsystem; 225 uint32_t sid; 226 227 if (spdk_nvmf_tgt_find_subsystem(tgt, nqn)) { 228 SPDK_ERRLOG("Subsystem NQN '%s' already exists\n", nqn); 229 return NULL; 230 } 231 232 if (!nvmf_valid_nqn(nqn)) { 233 return NULL; 234 } 235 236 if (type == SPDK_NVMF_SUBTYPE_DISCOVERY) { 237 if (num_ns != 0) { 238 SPDK_ERRLOG("Discovery subsystem cannot have namespaces.\n"); 239 return NULL; 240 } 241 } else if (num_ns == 0) { 242 num_ns = NVMF_SUBSYSTEM_DEFAULT_NAMESPACES; 243 } 244 245 /* Find a free subsystem id (sid) */ 246 sid = spdk_bit_array_find_first_clear(tgt->subsystem_ids, 0); 247 if (sid == UINT32_MAX) { 248 return NULL; 249 } 250 subsystem = calloc(1, sizeof(struct spdk_nvmf_subsystem)); 251 if (subsystem == NULL) { 252 return NULL; 253 } 254 255 subsystem->thread = spdk_get_thread(); 256 subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE; 257 subsystem->tgt = tgt; 258 subsystem->id = sid; 259 subsystem->subtype = type; 260 subsystem->max_nsid = num_ns; 261 subsystem->next_cntlid = 0; 262 subsystem->min_cntlid = NVMF_MIN_CNTLID; 263 subsystem->max_cntlid = NVMF_MAX_CNTLID; 264 snprintf(subsystem->subnqn, sizeof(subsystem->subnqn), "%s", nqn); 265 pthread_mutex_init(&subsystem->mutex, NULL); 266 TAILQ_INIT(&subsystem->listeners); 267 TAILQ_INIT(&subsystem->hosts); 268 TAILQ_INIT(&subsystem->ctrlrs); 269 subsystem->used_listener_ids = spdk_bit_array_create(NVMF_MAX_LISTENERS_PER_SUBSYSTEM); 270 if (subsystem->used_listener_ids == NULL) { 271 pthread_mutex_destroy(&subsystem->mutex); 272 free(subsystem); 273 return NULL; 274 } 275 276 if (num_ns != 0) { 277 subsystem->ns = calloc(num_ns, sizeof(struct spdk_nvmf_ns *)); 278 if (subsystem->ns == NULL) { 279 SPDK_ERRLOG("Namespace memory allocation failed\n"); 280 pthread_mutex_destroy(&subsystem->mutex); 281 spdk_bit_array_free(&subsystem->used_listener_ids); 282 free(subsystem); 283 return NULL; 284 } 285 subsystem->ana_group = calloc(num_ns, sizeof(uint32_t)); 286 if (subsystem->ana_group == NULL) { 287 SPDK_ERRLOG("ANA group memory allocation failed\n"); 288 pthread_mutex_destroy(&subsystem->mutex); 289 free(subsystem->ns); 290 spdk_bit_array_free(&subsystem->used_listener_ids); 291 free(subsystem); 292 return NULL; 293 } 294 } 295 296 memset(subsystem->sn, '0', sizeof(subsystem->sn) - 1); 297 subsystem->sn[sizeof(subsystem->sn) - 1] = '\0'; 298 299 snprintf(subsystem->mn, sizeof(subsystem->mn), "%s", 300 MODEL_NUMBER_DEFAULT); 301 302 spdk_bit_array_set(tgt->subsystem_ids, sid); 303 RB_INSERT(subsystem_tree, &tgt->subsystems, subsystem); 304 305 SPDK_DTRACE_PROBE1(nvmf_subsystem_create, subsystem->subnqn); 306 307 return subsystem; 308 } 309 310 /* Must hold subsystem->mutex while calling this function */ 311 static void 312 nvmf_subsystem_remove_host(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_host *host) 313 { 314 TAILQ_REMOVE(&subsystem->hosts, host, link); 315 free(host); 316 } 317 318 static void 319 _nvmf_subsystem_remove_listener(struct spdk_nvmf_subsystem *subsystem, 320 struct spdk_nvmf_subsystem_listener *listener, 321 bool stop) 322 { 323 struct spdk_nvmf_transport *transport; 324 struct spdk_nvmf_ctrlr *ctrlr; 325 326 if (stop) { 327 transport = spdk_nvmf_tgt_get_transport(subsystem->tgt, listener->trid->trstring); 328 if (transport != NULL) { 329 spdk_nvmf_transport_stop_listen(transport, listener->trid); 330 } 331 } 332 333 TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { 334 if (ctrlr->listener == listener) { 335 ctrlr->listener = NULL; 336 } 337 } 338 339 TAILQ_REMOVE(&subsystem->listeners, listener, link); 340 nvmf_update_discovery_log(listener->subsystem->tgt, NULL); 341 free(listener->ana_state); 342 spdk_bit_array_clear(subsystem->used_listener_ids, listener->id); 343 free(listener); 344 } 345 346 static void 347 _nvmf_subsystem_destroy_msg(void *cb_arg) 348 { 349 struct spdk_nvmf_subsystem *subsystem = cb_arg; 350 351 _nvmf_subsystem_destroy(subsystem); 352 } 353 354 static int 355 _nvmf_subsystem_destroy(struct spdk_nvmf_subsystem *subsystem) 356 { 357 struct spdk_nvmf_ns *ns; 358 nvmf_subsystem_destroy_cb async_destroy_cb = NULL; 359 void *async_destroy_cb_arg = NULL; 360 int rc; 361 362 if (!TAILQ_EMPTY(&subsystem->ctrlrs)) { 363 SPDK_DEBUGLOG(nvmf, "subsystem %p %s has active controllers\n", subsystem, subsystem->subnqn); 364 subsystem->async_destroy = true; 365 rc = spdk_thread_send_msg(subsystem->thread, _nvmf_subsystem_destroy_msg, subsystem); 366 if (rc) { 367 SPDK_ERRLOG("Failed to send thread msg, rc %d\n", rc); 368 assert(0); 369 return rc; 370 } 371 return -EINPROGRESS; 372 } 373 374 ns = spdk_nvmf_subsystem_get_first_ns(subsystem); 375 while (ns != NULL) { 376 struct spdk_nvmf_ns *next_ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns); 377 378 spdk_nvmf_subsystem_remove_ns(subsystem, ns->opts.nsid); 379 ns = next_ns; 380 } 381 382 free(subsystem->ns); 383 free(subsystem->ana_group); 384 385 RB_REMOVE(subsystem_tree, &subsystem->tgt->subsystems, subsystem); 386 assert(spdk_bit_array_get(subsystem->tgt->subsystem_ids, subsystem->id) == true); 387 spdk_bit_array_clear(subsystem->tgt->subsystem_ids, subsystem->id); 388 389 pthread_mutex_destroy(&subsystem->mutex); 390 391 spdk_bit_array_free(&subsystem->used_listener_ids); 392 393 if (subsystem->async_destroy) { 394 async_destroy_cb = subsystem->async_destroy_cb; 395 async_destroy_cb_arg = subsystem->async_destroy_cb_arg; 396 } 397 398 free(subsystem); 399 400 if (async_destroy_cb) { 401 async_destroy_cb(async_destroy_cb_arg); 402 } 403 404 return 0; 405 } 406 407 static struct spdk_nvmf_ns * 408 _nvmf_subsystem_get_first_zoned_ns(struct spdk_nvmf_subsystem *subsystem) 409 { 410 struct spdk_nvmf_ns *ns = spdk_nvmf_subsystem_get_first_ns(subsystem); 411 while (ns != NULL) { 412 if (ns->csi == SPDK_NVME_CSI_ZNS) { 413 return ns; 414 } 415 ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns); 416 } 417 return NULL; 418 } 419 420 int 421 spdk_nvmf_subsystem_destroy(struct spdk_nvmf_subsystem *subsystem, nvmf_subsystem_destroy_cb cpl_cb, 422 void *cpl_cb_arg) 423 { 424 struct spdk_nvmf_host *host, *host_tmp; 425 struct spdk_nvmf_transport *transport; 426 427 if (!subsystem) { 428 return -EINVAL; 429 } 430 431 SPDK_DTRACE_PROBE1(nvmf_subsystem_destroy, subsystem->subnqn); 432 433 assert(spdk_get_thread() == subsystem->thread); 434 435 if (subsystem->state != SPDK_NVMF_SUBSYSTEM_INACTIVE) { 436 SPDK_ERRLOG("Subsystem can only be destroyed in inactive state, %s state %d\n", 437 subsystem->subnqn, subsystem->state); 438 return -EAGAIN; 439 } 440 if (subsystem->destroying) { 441 SPDK_ERRLOG("Subsystem destruction is already started\n"); 442 assert(0); 443 return -EALREADY; 444 } 445 446 subsystem->destroying = true; 447 448 SPDK_DEBUGLOG(nvmf, "subsystem is %p %s\n", subsystem, subsystem->subnqn); 449 450 nvmf_subsystem_remove_all_listeners(subsystem, false); 451 452 pthread_mutex_lock(&subsystem->mutex); 453 454 TAILQ_FOREACH_SAFE(host, &subsystem->hosts, link, host_tmp) { 455 for (transport = spdk_nvmf_transport_get_first(subsystem->tgt); transport; 456 transport = spdk_nvmf_transport_get_next(transport)) { 457 if (transport->ops->subsystem_remove_host) { 458 transport->ops->subsystem_remove_host(transport, subsystem, host->nqn); 459 } 460 } 461 nvmf_subsystem_remove_host(subsystem, host); 462 } 463 464 pthread_mutex_unlock(&subsystem->mutex); 465 466 subsystem->async_destroy_cb = cpl_cb; 467 subsystem->async_destroy_cb_arg = cpl_cb_arg; 468 469 return _nvmf_subsystem_destroy(subsystem); 470 } 471 472 /* we have to use the typedef in the function declaration to appease astyle. */ 473 typedef enum spdk_nvmf_subsystem_state spdk_nvmf_subsystem_state_t; 474 475 static spdk_nvmf_subsystem_state_t 476 nvmf_subsystem_get_intermediate_state(enum spdk_nvmf_subsystem_state current_state, 477 enum spdk_nvmf_subsystem_state requested_state) 478 { 479 switch (requested_state) { 480 case SPDK_NVMF_SUBSYSTEM_INACTIVE: 481 return SPDK_NVMF_SUBSYSTEM_DEACTIVATING; 482 case SPDK_NVMF_SUBSYSTEM_ACTIVE: 483 if (current_state == SPDK_NVMF_SUBSYSTEM_PAUSED) { 484 return SPDK_NVMF_SUBSYSTEM_RESUMING; 485 } else { 486 return SPDK_NVMF_SUBSYSTEM_ACTIVATING; 487 } 488 case SPDK_NVMF_SUBSYSTEM_PAUSED: 489 return SPDK_NVMF_SUBSYSTEM_PAUSING; 490 default: 491 assert(false); 492 return SPDK_NVMF_SUBSYSTEM_NUM_STATES; 493 } 494 } 495 496 static int 497 nvmf_subsystem_set_state(struct spdk_nvmf_subsystem *subsystem, 498 enum spdk_nvmf_subsystem_state state) 499 { 500 enum spdk_nvmf_subsystem_state actual_old_state, expected_old_state; 501 bool exchanged; 502 503 switch (state) { 504 case SPDK_NVMF_SUBSYSTEM_INACTIVE: 505 expected_old_state = SPDK_NVMF_SUBSYSTEM_DEACTIVATING; 506 break; 507 case SPDK_NVMF_SUBSYSTEM_ACTIVATING: 508 expected_old_state = SPDK_NVMF_SUBSYSTEM_INACTIVE; 509 break; 510 case SPDK_NVMF_SUBSYSTEM_ACTIVE: 511 expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVATING; 512 break; 513 case SPDK_NVMF_SUBSYSTEM_PAUSING: 514 expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 515 break; 516 case SPDK_NVMF_SUBSYSTEM_PAUSED: 517 expected_old_state = SPDK_NVMF_SUBSYSTEM_PAUSING; 518 break; 519 case SPDK_NVMF_SUBSYSTEM_RESUMING: 520 expected_old_state = SPDK_NVMF_SUBSYSTEM_PAUSED; 521 break; 522 case SPDK_NVMF_SUBSYSTEM_DEACTIVATING: 523 expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 524 break; 525 default: 526 assert(false); 527 return -1; 528 } 529 530 actual_old_state = expected_old_state; 531 exchanged = __atomic_compare_exchange_n(&subsystem->state, &actual_old_state, state, false, 532 __ATOMIC_RELAXED, __ATOMIC_RELAXED); 533 if (spdk_unlikely(exchanged == false)) { 534 if (actual_old_state == SPDK_NVMF_SUBSYSTEM_RESUMING && 535 state == SPDK_NVMF_SUBSYSTEM_ACTIVE) { 536 expected_old_state = SPDK_NVMF_SUBSYSTEM_RESUMING; 537 } 538 /* This is for the case when activating the subsystem fails. */ 539 if (actual_old_state == SPDK_NVMF_SUBSYSTEM_ACTIVATING && 540 state == SPDK_NVMF_SUBSYSTEM_DEACTIVATING) { 541 expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVATING; 542 } 543 /* This is for the case when resuming the subsystem fails. */ 544 if (actual_old_state == SPDK_NVMF_SUBSYSTEM_RESUMING && 545 state == SPDK_NVMF_SUBSYSTEM_PAUSING) { 546 expected_old_state = SPDK_NVMF_SUBSYSTEM_RESUMING; 547 } 548 /* This is for the case when stopping paused subsystem */ 549 if (actual_old_state == SPDK_NVMF_SUBSYSTEM_PAUSED && 550 state == SPDK_NVMF_SUBSYSTEM_DEACTIVATING) { 551 expected_old_state = SPDK_NVMF_SUBSYSTEM_PAUSED; 552 } 553 actual_old_state = expected_old_state; 554 __atomic_compare_exchange_n(&subsystem->state, &actual_old_state, state, false, 555 __ATOMIC_RELAXED, __ATOMIC_RELAXED); 556 } 557 assert(actual_old_state == expected_old_state); 558 return actual_old_state - expected_old_state; 559 } 560 561 struct subsystem_state_change_ctx { 562 struct spdk_nvmf_subsystem *subsystem; 563 uint16_t nsid; 564 565 enum spdk_nvmf_subsystem_state original_state; 566 enum spdk_nvmf_subsystem_state requested_state; 567 568 spdk_nvmf_subsystem_state_change_done cb_fn; 569 void *cb_arg; 570 }; 571 572 static void 573 subsystem_state_change_revert_done(struct spdk_io_channel_iter *i, int status) 574 { 575 struct subsystem_state_change_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 576 577 /* Nothing to be done here if the state setting fails, we are just screwed. */ 578 if (nvmf_subsystem_set_state(ctx->subsystem, ctx->requested_state)) { 579 SPDK_ERRLOG("Unable to revert the subsystem state after operation failure.\n"); 580 } 581 582 ctx->subsystem->changing_state = false; 583 if (ctx->cb_fn) { 584 /* return a failure here. This function only exists in an error path. */ 585 ctx->cb_fn(ctx->subsystem, ctx->cb_arg, -1); 586 } 587 free(ctx); 588 } 589 590 static void 591 subsystem_state_change_done(struct spdk_io_channel_iter *i, int status) 592 { 593 struct subsystem_state_change_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 594 enum spdk_nvmf_subsystem_state intermediate_state; 595 596 SPDK_DTRACE_PROBE4(nvmf_subsystem_change_state_done, ctx->subsystem->subnqn, 597 ctx->requested_state, ctx->original_state, status); 598 599 if (status == 0) { 600 status = nvmf_subsystem_set_state(ctx->subsystem, ctx->requested_state); 601 if (status) { 602 status = -1; 603 } 604 } 605 606 if (status) { 607 intermediate_state = nvmf_subsystem_get_intermediate_state(ctx->requested_state, 608 ctx->original_state); 609 assert(intermediate_state != SPDK_NVMF_SUBSYSTEM_NUM_STATES); 610 611 if (nvmf_subsystem_set_state(ctx->subsystem, intermediate_state)) { 612 goto out; 613 } 614 ctx->requested_state = ctx->original_state; 615 spdk_for_each_channel(ctx->subsystem->tgt, 616 subsystem_state_change_on_pg, 617 ctx, 618 subsystem_state_change_revert_done); 619 return; 620 } 621 622 out: 623 ctx->subsystem->changing_state = false; 624 if (ctx->cb_fn) { 625 ctx->cb_fn(ctx->subsystem, ctx->cb_arg, status); 626 } 627 free(ctx); 628 } 629 630 static void 631 subsystem_state_change_continue(void *ctx, int status) 632 { 633 struct spdk_io_channel_iter *i = ctx; 634 struct subsystem_state_change_ctx *_ctx __attribute__((unused)); 635 636 _ctx = spdk_io_channel_iter_get_ctx(i); 637 SPDK_DTRACE_PROBE3(nvmf_pg_change_state_done, _ctx->subsystem->subnqn, 638 _ctx->requested_state, spdk_thread_get_id(spdk_get_thread())); 639 640 spdk_for_each_channel_continue(i, status); 641 } 642 643 static void 644 subsystem_state_change_on_pg(struct spdk_io_channel_iter *i) 645 { 646 struct subsystem_state_change_ctx *ctx; 647 struct spdk_io_channel *ch; 648 struct spdk_nvmf_poll_group *group; 649 650 ctx = spdk_io_channel_iter_get_ctx(i); 651 ch = spdk_io_channel_iter_get_channel(i); 652 group = spdk_io_channel_get_ctx(ch); 653 654 SPDK_DTRACE_PROBE3(nvmf_pg_change_state, ctx->subsystem->subnqn, 655 ctx->requested_state, spdk_thread_get_id(spdk_get_thread())); 656 switch (ctx->requested_state) { 657 case SPDK_NVMF_SUBSYSTEM_INACTIVE: 658 nvmf_poll_group_remove_subsystem(group, ctx->subsystem, subsystem_state_change_continue, i); 659 break; 660 case SPDK_NVMF_SUBSYSTEM_ACTIVE: 661 if (ctx->subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVATING) { 662 nvmf_poll_group_add_subsystem(group, ctx->subsystem, subsystem_state_change_continue, i); 663 } else if (ctx->subsystem->state == SPDK_NVMF_SUBSYSTEM_RESUMING) { 664 nvmf_poll_group_resume_subsystem(group, ctx->subsystem, subsystem_state_change_continue, i); 665 } 666 break; 667 case SPDK_NVMF_SUBSYSTEM_PAUSED: 668 nvmf_poll_group_pause_subsystem(group, ctx->subsystem, ctx->nsid, subsystem_state_change_continue, 669 i); 670 break; 671 default: 672 assert(false); 673 break; 674 } 675 } 676 677 static int 678 nvmf_subsystem_state_change(struct spdk_nvmf_subsystem *subsystem, 679 uint32_t nsid, 680 enum spdk_nvmf_subsystem_state requested_state, 681 spdk_nvmf_subsystem_state_change_done cb_fn, 682 void *cb_arg) 683 { 684 struct subsystem_state_change_ctx *ctx; 685 enum spdk_nvmf_subsystem_state intermediate_state; 686 int rc; 687 688 if (__sync_val_compare_and_swap(&subsystem->changing_state, false, true)) { 689 return -EBUSY; 690 } 691 692 SPDK_DTRACE_PROBE3(nvmf_subsystem_change_state, subsystem->subnqn, 693 requested_state, subsystem->state); 694 /* If we are already in the requested state, just call the callback immediately. */ 695 if (subsystem->state == requested_state) { 696 subsystem->changing_state = false; 697 if (cb_fn) { 698 cb_fn(subsystem, cb_arg, 0); 699 } 700 return 0; 701 } 702 703 intermediate_state = nvmf_subsystem_get_intermediate_state(subsystem->state, requested_state); 704 assert(intermediate_state != SPDK_NVMF_SUBSYSTEM_NUM_STATES); 705 706 ctx = calloc(1, sizeof(*ctx)); 707 if (!ctx) { 708 subsystem->changing_state = false; 709 return -ENOMEM; 710 } 711 712 ctx->original_state = subsystem->state; 713 rc = nvmf_subsystem_set_state(subsystem, intermediate_state); 714 if (rc) { 715 free(ctx); 716 subsystem->changing_state = false; 717 return rc; 718 } 719 720 ctx->subsystem = subsystem; 721 ctx->nsid = nsid; 722 ctx->requested_state = requested_state; 723 ctx->cb_fn = cb_fn; 724 ctx->cb_arg = cb_arg; 725 726 spdk_for_each_channel(subsystem->tgt, 727 subsystem_state_change_on_pg, 728 ctx, 729 subsystem_state_change_done); 730 731 return 0; 732 } 733 734 int 735 spdk_nvmf_subsystem_start(struct spdk_nvmf_subsystem *subsystem, 736 spdk_nvmf_subsystem_state_change_done cb_fn, 737 void *cb_arg) 738 { 739 return nvmf_subsystem_state_change(subsystem, 0, SPDK_NVMF_SUBSYSTEM_ACTIVE, cb_fn, cb_arg); 740 } 741 742 int 743 spdk_nvmf_subsystem_stop(struct spdk_nvmf_subsystem *subsystem, 744 spdk_nvmf_subsystem_state_change_done cb_fn, 745 void *cb_arg) 746 { 747 return nvmf_subsystem_state_change(subsystem, 0, SPDK_NVMF_SUBSYSTEM_INACTIVE, cb_fn, cb_arg); 748 } 749 750 int 751 spdk_nvmf_subsystem_pause(struct spdk_nvmf_subsystem *subsystem, 752 uint32_t nsid, 753 spdk_nvmf_subsystem_state_change_done cb_fn, 754 void *cb_arg) 755 { 756 return nvmf_subsystem_state_change(subsystem, nsid, SPDK_NVMF_SUBSYSTEM_PAUSED, cb_fn, cb_arg); 757 } 758 759 int 760 spdk_nvmf_subsystem_resume(struct spdk_nvmf_subsystem *subsystem, 761 spdk_nvmf_subsystem_state_change_done cb_fn, 762 void *cb_arg) 763 { 764 return nvmf_subsystem_state_change(subsystem, 0, SPDK_NVMF_SUBSYSTEM_ACTIVE, cb_fn, cb_arg); 765 } 766 767 struct spdk_nvmf_subsystem * 768 spdk_nvmf_subsystem_get_first(struct spdk_nvmf_tgt *tgt) 769 { 770 return RB_MIN(subsystem_tree, &tgt->subsystems); 771 } 772 773 struct spdk_nvmf_subsystem * 774 spdk_nvmf_subsystem_get_next(struct spdk_nvmf_subsystem *subsystem) 775 { 776 if (!subsystem) { 777 return NULL; 778 } 779 780 return RB_NEXT(subsystem_tree, &tgt->subsystems, subsystem); 781 } 782 783 /* Must hold subsystem->mutex while calling this function */ 784 static struct spdk_nvmf_host * 785 nvmf_subsystem_find_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn) 786 { 787 struct spdk_nvmf_host *host = NULL; 788 789 TAILQ_FOREACH(host, &subsystem->hosts, link) { 790 if (strcmp(hostnqn, host->nqn) == 0) { 791 return host; 792 } 793 } 794 795 return NULL; 796 } 797 798 int 799 spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn, 800 const struct spdk_json_val *params) 801 { 802 struct spdk_nvmf_host *host; 803 struct spdk_nvmf_transport *transport; 804 int rc; 805 806 if (!nvmf_valid_nqn(hostnqn)) { 807 return -EINVAL; 808 } 809 810 pthread_mutex_lock(&subsystem->mutex); 811 812 if (nvmf_subsystem_find_host(subsystem, hostnqn)) { 813 /* This subsystem already allows the specified host. */ 814 pthread_mutex_unlock(&subsystem->mutex); 815 return 0; 816 } 817 818 host = calloc(1, sizeof(*host)); 819 if (!host) { 820 pthread_mutex_unlock(&subsystem->mutex); 821 return -ENOMEM; 822 } 823 824 snprintf(host->nqn, sizeof(host->nqn), "%s", hostnqn); 825 826 SPDK_DTRACE_PROBE2(nvmf_subsystem_add_host, subsystem->subnqn, host->nqn); 827 828 TAILQ_INSERT_HEAD(&subsystem->hosts, host, link); 829 830 if (!TAILQ_EMPTY(&subsystem->listeners)) { 831 nvmf_update_discovery_log(subsystem->tgt, hostnqn); 832 } 833 834 for (transport = spdk_nvmf_transport_get_first(subsystem->tgt); transport; 835 transport = spdk_nvmf_transport_get_next(transport)) { 836 if (transport->ops->subsystem_add_host) { 837 rc = transport->ops->subsystem_add_host(transport, subsystem, hostnqn, params); 838 if (rc) { 839 SPDK_ERRLOG("Unable to add host to %s transport\n", transport->ops->name); 840 /* Remove this host from all transports we've managed to add it to. */ 841 pthread_mutex_unlock(&subsystem->mutex); 842 spdk_nvmf_subsystem_remove_host(subsystem, hostnqn); 843 return rc; 844 } 845 } 846 } 847 848 pthread_mutex_unlock(&subsystem->mutex); 849 850 return 0; 851 } 852 853 int 854 spdk_nvmf_subsystem_remove_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn) 855 { 856 struct spdk_nvmf_host *host; 857 struct spdk_nvmf_transport *transport; 858 859 pthread_mutex_lock(&subsystem->mutex); 860 861 host = nvmf_subsystem_find_host(subsystem, hostnqn); 862 if (host == NULL) { 863 pthread_mutex_unlock(&subsystem->mutex); 864 return -ENOENT; 865 } 866 867 SPDK_DTRACE_PROBE2(nvmf_subsystem_remove_host, subsystem->subnqn, host->nqn); 868 869 nvmf_subsystem_remove_host(subsystem, host); 870 871 if (!TAILQ_EMPTY(&subsystem->listeners)) { 872 nvmf_update_discovery_log(subsystem->tgt, hostnqn); 873 } 874 875 for (transport = spdk_nvmf_transport_get_first(subsystem->tgt); transport; 876 transport = spdk_nvmf_transport_get_next(transport)) { 877 if (transport->ops->subsystem_remove_host) { 878 transport->ops->subsystem_remove_host(transport, subsystem, hostnqn); 879 } 880 } 881 882 pthread_mutex_unlock(&subsystem->mutex); 883 884 return 0; 885 } 886 887 struct nvmf_subsystem_disconnect_host_ctx { 888 struct spdk_nvmf_subsystem *subsystem; 889 char *hostnqn; 890 spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn; 891 void *cb_arg; 892 }; 893 894 static void 895 nvmf_subsystem_disconnect_host_fini(struct spdk_io_channel_iter *i, int status) 896 { 897 struct nvmf_subsystem_disconnect_host_ctx *ctx; 898 899 ctx = spdk_io_channel_iter_get_ctx(i); 900 901 if (ctx->cb_fn) { 902 ctx->cb_fn(ctx->cb_arg, status); 903 } 904 free(ctx->hostnqn); 905 free(ctx); 906 } 907 908 static void 909 nvmf_subsystem_disconnect_qpairs_by_host(struct spdk_io_channel_iter *i) 910 { 911 struct nvmf_subsystem_disconnect_host_ctx *ctx; 912 struct spdk_nvmf_poll_group *group; 913 struct spdk_io_channel *ch; 914 struct spdk_nvmf_qpair *qpair, *tmp_qpair; 915 struct spdk_nvmf_ctrlr *ctrlr; 916 917 ctx = spdk_io_channel_iter_get_ctx(i); 918 ch = spdk_io_channel_iter_get_channel(i); 919 group = spdk_io_channel_get_ctx(ch); 920 921 TAILQ_FOREACH_SAFE(qpair, &group->qpairs, link, tmp_qpair) { 922 ctrlr = qpair->ctrlr; 923 924 if (ctrlr == NULL || ctrlr->subsys != ctx->subsystem) { 925 continue; 926 } 927 928 if (strncmp(ctrlr->hostnqn, ctx->hostnqn, sizeof(ctrlr->hostnqn)) == 0) { 929 /* Right now this does not wait for the queue pairs to actually disconnect. */ 930 spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); 931 } 932 } 933 spdk_for_each_channel_continue(i, 0); 934 } 935 936 int 937 spdk_nvmf_subsystem_disconnect_host(struct spdk_nvmf_subsystem *subsystem, 938 const char *hostnqn, 939 spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, 940 void *cb_arg) 941 { 942 struct nvmf_subsystem_disconnect_host_ctx *ctx; 943 944 ctx = calloc(1, sizeof(struct nvmf_subsystem_disconnect_host_ctx)); 945 if (ctx == NULL) { 946 return -ENOMEM; 947 } 948 949 ctx->hostnqn = strdup(hostnqn); 950 if (ctx->hostnqn == NULL) { 951 free(ctx); 952 return -ENOMEM; 953 } 954 955 ctx->subsystem = subsystem; 956 ctx->cb_fn = cb_fn; 957 ctx->cb_arg = cb_arg; 958 959 spdk_for_each_channel(subsystem->tgt, nvmf_subsystem_disconnect_qpairs_by_host, ctx, 960 nvmf_subsystem_disconnect_host_fini); 961 962 return 0; 963 } 964 965 int 966 spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, bool allow_any_host) 967 { 968 pthread_mutex_lock(&subsystem->mutex); 969 subsystem->flags.allow_any_host = allow_any_host; 970 if (!TAILQ_EMPTY(&subsystem->listeners)) { 971 nvmf_update_discovery_log(subsystem->tgt, NULL); 972 } 973 pthread_mutex_unlock(&subsystem->mutex); 974 975 return 0; 976 } 977 978 bool 979 spdk_nvmf_subsystem_get_allow_any_host(const struct spdk_nvmf_subsystem *subsystem) 980 { 981 bool allow_any_host; 982 struct spdk_nvmf_subsystem *sub; 983 984 /* Technically, taking the mutex modifies data in the subsystem. But the const 985 * is still important to convey that this doesn't mutate any other data. Cast 986 * it away to work around this. */ 987 sub = (struct spdk_nvmf_subsystem *)subsystem; 988 989 pthread_mutex_lock(&sub->mutex); 990 allow_any_host = sub->flags.allow_any_host; 991 pthread_mutex_unlock(&sub->mutex); 992 993 return allow_any_host; 994 } 995 996 bool 997 spdk_nvmf_subsystem_host_allowed(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn) 998 { 999 bool allowed; 1000 1001 if (!hostnqn) { 1002 return false; 1003 } 1004 1005 pthread_mutex_lock(&subsystem->mutex); 1006 1007 if (subsystem->flags.allow_any_host) { 1008 pthread_mutex_unlock(&subsystem->mutex); 1009 return true; 1010 } 1011 1012 allowed = nvmf_subsystem_find_host(subsystem, hostnqn) != NULL; 1013 pthread_mutex_unlock(&subsystem->mutex); 1014 1015 return allowed; 1016 } 1017 1018 struct spdk_nvmf_host * 1019 spdk_nvmf_subsystem_get_first_host(struct spdk_nvmf_subsystem *subsystem) 1020 { 1021 return TAILQ_FIRST(&subsystem->hosts); 1022 } 1023 1024 1025 struct spdk_nvmf_host * 1026 spdk_nvmf_subsystem_get_next_host(struct spdk_nvmf_subsystem *subsystem, 1027 struct spdk_nvmf_host *prev_host) 1028 { 1029 return TAILQ_NEXT(prev_host, link); 1030 } 1031 1032 const char * 1033 spdk_nvmf_host_get_nqn(const struct spdk_nvmf_host *host) 1034 { 1035 return host->nqn; 1036 } 1037 1038 struct spdk_nvmf_subsystem_listener * 1039 nvmf_subsystem_find_listener(struct spdk_nvmf_subsystem *subsystem, 1040 const struct spdk_nvme_transport_id *trid) 1041 { 1042 struct spdk_nvmf_subsystem_listener *listener; 1043 1044 TAILQ_FOREACH(listener, &subsystem->listeners, link) { 1045 if (spdk_nvme_transport_id_compare(listener->trid, trid) == 0) { 1046 return listener; 1047 } 1048 } 1049 1050 return NULL; 1051 } 1052 1053 /** 1054 * Function to be called once the target is listening. 1055 * 1056 * \param ctx Context argument passed to this function. 1057 * \param status 0 if it completed successfully, or negative errno if it failed. 1058 */ 1059 static void 1060 _nvmf_subsystem_add_listener_done(void *ctx, int status) 1061 { 1062 struct spdk_nvmf_subsystem_listener *listener = ctx; 1063 1064 if (status) { 1065 listener->cb_fn(listener->cb_arg, status); 1066 free(listener); 1067 return; 1068 } 1069 1070 TAILQ_INSERT_HEAD(&listener->subsystem->listeners, listener, link); 1071 nvmf_update_discovery_log(listener->subsystem->tgt, NULL); 1072 listener->cb_fn(listener->cb_arg, status); 1073 } 1074 1075 void 1076 spdk_nvmf_subsystem_listener_opts_init(struct spdk_nvmf_listener_opts *opts, size_t size) 1077 { 1078 if (opts == NULL) { 1079 SPDK_ERRLOG("opts should not be NULL\n"); 1080 assert(false); 1081 return; 1082 } 1083 if (size == 0) { 1084 SPDK_ERRLOG("size should not be zero\n"); 1085 assert(false); 1086 return; 1087 } 1088 1089 memset(opts, 0, size); 1090 opts->opts_size = size; 1091 1092 #define FIELD_OK(field) \ 1093 offsetof(struct spdk_nvmf_listener_opts, field) + sizeof(opts->field) <= size 1094 1095 #define SET_FIELD(field, value) \ 1096 if (FIELD_OK(field)) { \ 1097 opts->field = value; \ 1098 } \ 1099 1100 SET_FIELD(secure_channel, false); 1101 1102 #undef FIELD_OK 1103 #undef SET_FIELD 1104 } 1105 1106 static int 1107 listener_opts_copy(struct spdk_nvmf_listener_opts *src, struct spdk_nvmf_listener_opts *dst) 1108 { 1109 if (src->opts_size == 0) { 1110 SPDK_ERRLOG("source structure size should not be zero\n"); 1111 assert(false); 1112 return -EINVAL; 1113 } 1114 1115 memset(dst, 0, sizeof(*dst)); 1116 dst->opts_size = src->opts_size; 1117 1118 #define FIELD_OK(field) \ 1119 offsetof(struct spdk_nvmf_listener_opts, field) + sizeof(src->field) <= src->opts_size 1120 1121 #define SET_FIELD(field) \ 1122 if (FIELD_OK(field)) { \ 1123 dst->field = src->field; \ 1124 } \ 1125 1126 SET_FIELD(secure_channel); 1127 1128 /* We should not remove this statement, but need to update the assert statement 1129 * if we add a new field, and also add a corresponding SET_FIELD statement. */ 1130 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_listener_opts) == 9, "Incorrect size"); 1131 1132 #undef SET_FIELD 1133 #undef FIELD_OK 1134 1135 return 0; 1136 } 1137 1138 static void 1139 _nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem, 1140 struct spdk_nvme_transport_id *trid, 1141 spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, 1142 void *cb_arg, struct spdk_nvmf_listener_opts *opts) 1143 { 1144 struct spdk_nvmf_transport *transport; 1145 struct spdk_nvmf_subsystem_listener *listener; 1146 struct spdk_nvmf_listener *tr_listener; 1147 uint32_t i; 1148 uint32_t id; 1149 int rc = 0; 1150 1151 assert(cb_fn != NULL); 1152 1153 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 1154 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 1155 cb_fn(cb_arg, -EAGAIN); 1156 return; 1157 } 1158 1159 if (nvmf_subsystem_find_listener(subsystem, trid)) { 1160 /* Listener already exists in this subsystem */ 1161 cb_fn(cb_arg, 0); 1162 return; 1163 } 1164 1165 transport = spdk_nvmf_tgt_get_transport(subsystem->tgt, trid->trstring); 1166 if (!transport) { 1167 SPDK_ERRLOG("Unable to find %s transport. The transport must be created first also make sure it is properly registered.\n", 1168 trid->trstring); 1169 cb_fn(cb_arg, -EINVAL); 1170 return; 1171 } 1172 1173 tr_listener = nvmf_transport_find_listener(transport, trid); 1174 if (!tr_listener) { 1175 SPDK_ERRLOG("Cannot find transport listener for %s\n", trid->traddr); 1176 cb_fn(cb_arg, -EINVAL); 1177 return; 1178 } 1179 1180 listener = calloc(1, sizeof(*listener)); 1181 if (!listener) { 1182 cb_fn(cb_arg, -ENOMEM); 1183 return; 1184 } 1185 1186 listener->trid = &tr_listener->trid; 1187 listener->transport = transport; 1188 listener->cb_fn = cb_fn; 1189 listener->cb_arg = cb_arg; 1190 listener->subsystem = subsystem; 1191 listener->ana_state = calloc(subsystem->max_nsid, sizeof(enum spdk_nvme_ana_state)); 1192 if (!listener->ana_state) { 1193 free(listener); 1194 cb_fn(cb_arg, -ENOMEM); 1195 return; 1196 } 1197 1198 spdk_nvmf_subsystem_listener_opts_init(&listener->opts, sizeof(listener->opts)); 1199 if (opts != NULL) { 1200 rc = listener_opts_copy(opts, &listener->opts); 1201 if (rc) { 1202 SPDK_ERRLOG("Unable to copy listener options\n"); 1203 free(listener->ana_state); 1204 free(listener); 1205 cb_fn(cb_arg, -EINVAL); 1206 return; 1207 } 1208 } 1209 1210 id = spdk_bit_array_find_first_clear(subsystem->used_listener_ids, 0); 1211 if (id == UINT32_MAX) { 1212 SPDK_ERRLOG("Cannot add any more listeners\n"); 1213 free(listener->ana_state); 1214 free(listener); 1215 cb_fn(cb_arg, -EINVAL); 1216 return; 1217 } 1218 1219 spdk_bit_array_set(subsystem->used_listener_ids, id); 1220 listener->id = id; 1221 1222 for (i = 0; i < subsystem->max_nsid; i++) { 1223 listener->ana_state[i] = SPDK_NVME_ANA_OPTIMIZED_STATE; 1224 } 1225 1226 if (transport->ops->listen_associate != NULL) { 1227 rc = transport->ops->listen_associate(transport, subsystem, trid); 1228 } 1229 1230 SPDK_DTRACE_PROBE4(nvmf_subsystem_add_listener, subsystem->subnqn, listener->trid->trtype, 1231 listener->trid->traddr, listener->trid->trsvcid); 1232 1233 _nvmf_subsystem_add_listener_done(listener, rc); 1234 } 1235 1236 void 1237 spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem, 1238 struct spdk_nvme_transport_id *trid, 1239 spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, 1240 void *cb_arg) 1241 { 1242 _nvmf_subsystem_add_listener(subsystem, trid, cb_fn, cb_arg, NULL); 1243 } 1244 1245 void 1246 spdk_nvmf_subsystem_add_listener_ext(struct spdk_nvmf_subsystem *subsystem, 1247 struct spdk_nvme_transport_id *trid, 1248 spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, 1249 void *cb_arg, struct spdk_nvmf_listener_opts *opts) 1250 { 1251 _nvmf_subsystem_add_listener(subsystem, trid, cb_fn, cb_arg, opts); 1252 } 1253 1254 int 1255 spdk_nvmf_subsystem_remove_listener(struct spdk_nvmf_subsystem *subsystem, 1256 const struct spdk_nvme_transport_id *trid) 1257 { 1258 struct spdk_nvmf_subsystem_listener *listener; 1259 1260 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 1261 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 1262 return -EAGAIN; 1263 } 1264 1265 listener = nvmf_subsystem_find_listener(subsystem, trid); 1266 if (listener == NULL) { 1267 return -ENOENT; 1268 } 1269 1270 SPDK_DTRACE_PROBE4(nvmf_subsystem_remove_listener, subsystem->subnqn, listener->trid->trtype, 1271 listener->trid->traddr, listener->trid->trsvcid); 1272 1273 _nvmf_subsystem_remove_listener(subsystem, listener, false); 1274 1275 return 0; 1276 } 1277 1278 void 1279 nvmf_subsystem_remove_all_listeners(struct spdk_nvmf_subsystem *subsystem, 1280 bool stop) 1281 { 1282 struct spdk_nvmf_subsystem_listener *listener, *listener_tmp; 1283 1284 TAILQ_FOREACH_SAFE(listener, &subsystem->listeners, link, listener_tmp) { 1285 _nvmf_subsystem_remove_listener(subsystem, listener, stop); 1286 } 1287 } 1288 1289 bool 1290 spdk_nvmf_subsystem_listener_allowed(struct spdk_nvmf_subsystem *subsystem, 1291 const struct spdk_nvme_transport_id *trid) 1292 { 1293 struct spdk_nvmf_subsystem_listener *listener; 1294 1295 TAILQ_FOREACH(listener, &subsystem->listeners, link) { 1296 if (spdk_nvme_transport_id_compare(listener->trid, trid) == 0) { 1297 return true; 1298 } 1299 } 1300 1301 if (!strcmp(subsystem->subnqn, SPDK_NVMF_DISCOVERY_NQN)) { 1302 SPDK_WARNLOG("Allowing connection to discovery subsystem on %s/%s/%s, " 1303 "even though this listener was not added to the discovery " 1304 "subsystem. This behavior is deprecated and will be removed " 1305 "in a future release.\n", 1306 spdk_nvme_transport_id_trtype_str(trid->trtype), trid->traddr, trid->trsvcid); 1307 return true; 1308 } 1309 1310 return false; 1311 } 1312 1313 struct spdk_nvmf_subsystem_listener * 1314 spdk_nvmf_subsystem_get_first_listener(struct spdk_nvmf_subsystem *subsystem) 1315 { 1316 return TAILQ_FIRST(&subsystem->listeners); 1317 } 1318 1319 struct spdk_nvmf_subsystem_listener * 1320 spdk_nvmf_subsystem_get_next_listener(struct spdk_nvmf_subsystem *subsystem, 1321 struct spdk_nvmf_subsystem_listener *prev_listener) 1322 { 1323 return TAILQ_NEXT(prev_listener, link); 1324 } 1325 1326 const struct spdk_nvme_transport_id * 1327 spdk_nvmf_subsystem_listener_get_trid(struct spdk_nvmf_subsystem_listener *listener) 1328 { 1329 return listener->trid; 1330 } 1331 1332 void 1333 spdk_nvmf_subsystem_allow_any_listener(struct spdk_nvmf_subsystem *subsystem, 1334 bool allow_any_listener) 1335 { 1336 subsystem->flags.allow_any_listener = allow_any_listener; 1337 } 1338 1339 bool 1340 spdk_nvmf_subsytem_any_listener_allowed(struct spdk_nvmf_subsystem *subsystem) 1341 { 1342 return subsystem->flags.allow_any_listener; 1343 } 1344 1345 1346 struct subsystem_update_ns_ctx { 1347 struct spdk_nvmf_subsystem *subsystem; 1348 1349 spdk_nvmf_subsystem_state_change_done cb_fn; 1350 void *cb_arg; 1351 }; 1352 1353 static void 1354 subsystem_update_ns_done(struct spdk_io_channel_iter *i, int status) 1355 { 1356 struct subsystem_update_ns_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 1357 1358 if (ctx->cb_fn) { 1359 ctx->cb_fn(ctx->subsystem, ctx->cb_arg, status); 1360 } 1361 free(ctx); 1362 } 1363 1364 static void 1365 subsystem_update_ns_on_pg(struct spdk_io_channel_iter *i) 1366 { 1367 int rc; 1368 struct subsystem_update_ns_ctx *ctx; 1369 struct spdk_nvmf_poll_group *group; 1370 struct spdk_nvmf_subsystem *subsystem; 1371 1372 ctx = spdk_io_channel_iter_get_ctx(i); 1373 group = spdk_io_channel_get_ctx(spdk_io_channel_iter_get_channel(i)); 1374 subsystem = ctx->subsystem; 1375 1376 rc = nvmf_poll_group_update_subsystem(group, subsystem); 1377 spdk_for_each_channel_continue(i, rc); 1378 } 1379 1380 static int 1381 nvmf_subsystem_update_ns(struct spdk_nvmf_subsystem *subsystem, spdk_channel_for_each_cpl cpl, 1382 void *ctx) 1383 { 1384 spdk_for_each_channel(subsystem->tgt, 1385 subsystem_update_ns_on_pg, 1386 ctx, 1387 cpl); 1388 1389 return 0; 1390 } 1391 1392 static void 1393 nvmf_subsystem_ns_changed(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) 1394 { 1395 struct spdk_nvmf_ctrlr *ctrlr; 1396 1397 TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { 1398 nvmf_ctrlr_ns_changed(ctrlr, nsid); 1399 } 1400 } 1401 1402 static uint32_t nvmf_ns_reservation_clear_all_registrants(struct spdk_nvmf_ns *ns); 1403 1404 int 1405 spdk_nvmf_subsystem_remove_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) 1406 { 1407 struct spdk_nvmf_transport *transport; 1408 struct spdk_nvmf_ns *ns; 1409 1410 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 1411 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 1412 assert(false); 1413 return -1; 1414 } 1415 1416 if (nsid == 0 || nsid > subsystem->max_nsid) { 1417 return -1; 1418 } 1419 1420 ns = subsystem->ns[nsid - 1]; 1421 if (!ns) { 1422 return -1; 1423 } 1424 1425 subsystem->ns[nsid - 1] = NULL; 1426 1427 assert(ns->anagrpid - 1 < subsystem->max_nsid); 1428 assert(subsystem->ana_group[ns->anagrpid - 1] > 0); 1429 1430 subsystem->ana_group[ns->anagrpid - 1]--; 1431 1432 free(ns->ptpl_file); 1433 nvmf_ns_reservation_clear_all_registrants(ns); 1434 spdk_bdev_module_release_bdev(ns->bdev); 1435 spdk_bdev_close(ns->desc); 1436 free(ns); 1437 1438 for (transport = spdk_nvmf_transport_get_first(subsystem->tgt); transport; 1439 transport = spdk_nvmf_transport_get_next(transport)) { 1440 if (transport->ops->subsystem_remove_ns) { 1441 transport->ops->subsystem_remove_ns(transport, subsystem, nsid); 1442 } 1443 } 1444 1445 nvmf_subsystem_ns_changed(subsystem, nsid); 1446 1447 return 0; 1448 } 1449 1450 struct subsystem_ns_change_ctx { 1451 struct spdk_nvmf_subsystem *subsystem; 1452 spdk_nvmf_subsystem_state_change_done cb_fn; 1453 uint32_t nsid; 1454 }; 1455 1456 static void 1457 _nvmf_ns_hot_remove(struct spdk_nvmf_subsystem *subsystem, 1458 void *cb_arg, int status) 1459 { 1460 struct subsystem_ns_change_ctx *ctx = cb_arg; 1461 int rc; 1462 1463 rc = spdk_nvmf_subsystem_remove_ns(subsystem, ctx->nsid); 1464 if (rc != 0) { 1465 SPDK_ERRLOG("Failed to make changes to NVME-oF subsystem with id: %u\n", subsystem->id); 1466 } 1467 1468 rc = spdk_nvmf_subsystem_resume(subsystem, NULL, NULL); 1469 if (rc != 0) { 1470 SPDK_ERRLOG("Failed to resume NVME-oF subsystem with id: %u\n", subsystem->id); 1471 } 1472 1473 free(ctx); 1474 } 1475 1476 static void 1477 nvmf_ns_change_msg(void *ns_ctx) 1478 { 1479 struct subsystem_ns_change_ctx *ctx = ns_ctx; 1480 int rc; 1481 1482 SPDK_DTRACE_PROBE2(nvmf_ns_change, ctx->nsid, ctx->subsystem->subnqn); 1483 1484 rc = spdk_nvmf_subsystem_pause(ctx->subsystem, ctx->nsid, ctx->cb_fn, ctx); 1485 if (rc) { 1486 if (rc == -EBUSY) { 1487 /* Try again, this is not a permanent situation. */ 1488 spdk_thread_send_msg(spdk_get_thread(), nvmf_ns_change_msg, ctx); 1489 } else { 1490 free(ctx); 1491 SPDK_ERRLOG("Unable to pause subsystem to process namespace removal!\n"); 1492 } 1493 } 1494 } 1495 1496 static void 1497 nvmf_ns_hot_remove(void *remove_ctx) 1498 { 1499 struct spdk_nvmf_ns *ns = remove_ctx; 1500 struct subsystem_ns_change_ctx *ns_ctx; 1501 int rc; 1502 1503 /* We have to allocate a new context because this op 1504 * is asynchronous and we could lose the ns in the middle. 1505 */ 1506 ns_ctx = calloc(1, sizeof(struct subsystem_ns_change_ctx)); 1507 if (!ns_ctx) { 1508 SPDK_ERRLOG("Unable to allocate context to process namespace removal!\n"); 1509 return; 1510 } 1511 1512 ns_ctx->subsystem = ns->subsystem; 1513 ns_ctx->nsid = ns->opts.nsid; 1514 ns_ctx->cb_fn = _nvmf_ns_hot_remove; 1515 1516 rc = spdk_nvmf_subsystem_pause(ns->subsystem, ns_ctx->nsid, _nvmf_ns_hot_remove, ns_ctx); 1517 if (rc) { 1518 if (rc == -EBUSY) { 1519 /* Try again, this is not a permanent situation. */ 1520 spdk_thread_send_msg(spdk_get_thread(), nvmf_ns_change_msg, ns_ctx); 1521 } else { 1522 SPDK_ERRLOG("Unable to pause subsystem to process namespace removal!\n"); 1523 free(ns_ctx); 1524 } 1525 } 1526 } 1527 1528 static void 1529 _nvmf_ns_resize(struct spdk_nvmf_subsystem *subsystem, void *cb_arg, int status) 1530 { 1531 struct subsystem_ns_change_ctx *ctx = cb_arg; 1532 1533 nvmf_subsystem_ns_changed(subsystem, ctx->nsid); 1534 if (spdk_nvmf_subsystem_resume(subsystem, NULL, NULL) != 0) { 1535 SPDK_ERRLOG("Failed to resume NVME-oF subsystem with id: %u\n", subsystem->id); 1536 } 1537 1538 free(ctx); 1539 } 1540 1541 static void 1542 nvmf_ns_resize(void *event_ctx) 1543 { 1544 struct spdk_nvmf_ns *ns = event_ctx; 1545 struct subsystem_ns_change_ctx *ns_ctx; 1546 int rc; 1547 1548 /* We have to allocate a new context because this op 1549 * is asynchronous and we could lose the ns in the middle. 1550 */ 1551 ns_ctx = calloc(1, sizeof(struct subsystem_ns_change_ctx)); 1552 if (!ns_ctx) { 1553 SPDK_ERRLOG("Unable to allocate context to process namespace removal!\n"); 1554 return; 1555 } 1556 1557 ns_ctx->subsystem = ns->subsystem; 1558 ns_ctx->nsid = ns->opts.nsid; 1559 ns_ctx->cb_fn = _nvmf_ns_resize; 1560 1561 /* Specify 0 for the nsid here, because we do not need to pause the namespace. 1562 * Namespaces can only be resized bigger, so there is no need to quiesce I/O. 1563 */ 1564 rc = spdk_nvmf_subsystem_pause(ns->subsystem, 0, _nvmf_ns_resize, ns_ctx); 1565 if (rc) { 1566 if (rc == -EBUSY) { 1567 /* Try again, this is not a permanent situation. */ 1568 spdk_thread_send_msg(spdk_get_thread(), nvmf_ns_change_msg, ns_ctx); 1569 } else { 1570 SPDK_ERRLOG("Unable to pause subsystem to process namespace resize!\n"); 1571 free(ns_ctx); 1572 } 1573 } 1574 } 1575 1576 static void 1577 nvmf_ns_event(enum spdk_bdev_event_type type, 1578 struct spdk_bdev *bdev, 1579 void *event_ctx) 1580 { 1581 SPDK_DEBUGLOG(nvmf, "Bdev event: type %d, name %s, subsystem_id %d, ns_id %d\n", 1582 type, 1583 spdk_bdev_get_name(bdev), 1584 ((struct spdk_nvmf_ns *)event_ctx)->subsystem->id, 1585 ((struct spdk_nvmf_ns *)event_ctx)->nsid); 1586 1587 switch (type) { 1588 case SPDK_BDEV_EVENT_REMOVE: 1589 nvmf_ns_hot_remove(event_ctx); 1590 break; 1591 case SPDK_BDEV_EVENT_RESIZE: 1592 nvmf_ns_resize(event_ctx); 1593 break; 1594 default: 1595 SPDK_NOTICELOG("Unsupported bdev event: type %d\n", type); 1596 break; 1597 } 1598 } 1599 1600 void 1601 spdk_nvmf_ns_opts_get_defaults(struct spdk_nvmf_ns_opts *opts, size_t opts_size) 1602 { 1603 if (!opts) { 1604 SPDK_ERRLOG("opts should not be NULL.\n"); 1605 return; 1606 } 1607 1608 if (!opts_size) { 1609 SPDK_ERRLOG("opts_size should not be zero.\n"); 1610 return; 1611 } 1612 1613 memset(opts, 0, opts_size); 1614 opts->opts_size = opts_size; 1615 1616 #define FIELD_OK(field) \ 1617 offsetof(struct spdk_nvmf_ns_opts, field) + sizeof(opts->field) <= opts_size 1618 1619 #define SET_FIELD(field, value) \ 1620 if (FIELD_OK(field)) { \ 1621 opts->field = value; \ 1622 } \ 1623 1624 /* All current fields are set to 0 by default. */ 1625 SET_FIELD(nsid, 0); 1626 if (FIELD_OK(nguid)) { 1627 memset(opts->nguid, 0, sizeof(opts->nguid)); 1628 } 1629 if (FIELD_OK(eui64)) { 1630 memset(opts->eui64, 0, sizeof(opts->eui64)); 1631 } 1632 if (FIELD_OK(uuid)) { 1633 spdk_uuid_set_null(&opts->uuid); 1634 } 1635 SET_FIELD(anagrpid, 0); 1636 1637 #undef FIELD_OK 1638 #undef SET_FIELD 1639 } 1640 1641 static void 1642 nvmf_ns_opts_copy(struct spdk_nvmf_ns_opts *opts, 1643 const struct spdk_nvmf_ns_opts *user_opts, 1644 size_t opts_size) 1645 { 1646 #define FIELD_OK(field) \ 1647 offsetof(struct spdk_nvmf_ns_opts, field) + sizeof(opts->field) <= user_opts->opts_size 1648 1649 #define SET_FIELD(field) \ 1650 if (FIELD_OK(field)) { \ 1651 opts->field = user_opts->field; \ 1652 } \ 1653 1654 SET_FIELD(nsid); 1655 if (FIELD_OK(nguid)) { 1656 memcpy(opts->nguid, user_opts->nguid, sizeof(opts->nguid)); 1657 } 1658 if (FIELD_OK(eui64)) { 1659 memcpy(opts->eui64, user_opts->eui64, sizeof(opts->eui64)); 1660 } 1661 if (FIELD_OK(uuid)) { 1662 spdk_uuid_copy(&opts->uuid, &user_opts->uuid); 1663 } 1664 SET_FIELD(anagrpid); 1665 1666 opts->opts_size = user_opts->opts_size; 1667 1668 /* We should not remove this statement, but need to update the assert statement 1669 * if we add a new field, and also add a corresponding SET_FIELD statement. 1670 */ 1671 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_ns_opts) == 64, "Incorrect size"); 1672 1673 #undef FIELD_OK 1674 #undef SET_FIELD 1675 } 1676 1677 /* Dummy bdev module used to to claim bdevs. */ 1678 static struct spdk_bdev_module ns_bdev_module = { 1679 .name = "NVMe-oF Target", 1680 }; 1681 1682 static int nvmf_ns_load_reservation(const char *file, struct spdk_nvmf_reservation_info *info); 1683 static int nvmf_ns_reservation_restore(struct spdk_nvmf_ns *ns, 1684 struct spdk_nvmf_reservation_info *info); 1685 1686 uint32_t 1687 spdk_nvmf_subsystem_add_ns_ext(struct spdk_nvmf_subsystem *subsystem, const char *bdev_name, 1688 const struct spdk_nvmf_ns_opts *user_opts, size_t opts_size, 1689 const char *ptpl_file) 1690 { 1691 struct spdk_nvmf_transport *transport; 1692 struct spdk_nvmf_ns_opts opts; 1693 struct spdk_nvmf_ns *ns; 1694 struct spdk_nvmf_reservation_info info = {0}; 1695 int rc; 1696 bool zone_append_supported; 1697 uint64_t max_zone_append_size_kib; 1698 1699 if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 1700 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { 1701 return 0; 1702 } 1703 1704 spdk_nvmf_ns_opts_get_defaults(&opts, sizeof(opts)); 1705 if (user_opts) { 1706 nvmf_ns_opts_copy(&opts, user_opts, opts_size); 1707 } 1708 1709 if (opts.nsid == SPDK_NVME_GLOBAL_NS_TAG) { 1710 SPDK_ERRLOG("Invalid NSID %" PRIu32 "\n", opts.nsid); 1711 return 0; 1712 } 1713 1714 if (opts.nsid == 0) { 1715 /* 1716 * NSID not specified - find a free index. 1717 * 1718 * If no free slots are found, opts.nsid will be subsystem->max_nsid + 1, which will 1719 * expand max_nsid if possible. 1720 */ 1721 for (opts.nsid = 1; opts.nsid <= subsystem->max_nsid; opts.nsid++) { 1722 if (_nvmf_subsystem_get_ns(subsystem, opts.nsid) == NULL) { 1723 break; 1724 } 1725 } 1726 } 1727 1728 if (_nvmf_subsystem_get_ns(subsystem, opts.nsid)) { 1729 SPDK_ERRLOG("Requested NSID %" PRIu32 " already in use\n", opts.nsid); 1730 return 0; 1731 } 1732 1733 if (opts.nsid > subsystem->max_nsid) { 1734 SPDK_ERRLOG("NSID greater than maximum not allowed\n"); 1735 return 0; 1736 } 1737 1738 if (opts.anagrpid == 0) { 1739 opts.anagrpid = opts.nsid; 1740 } 1741 1742 if (opts.anagrpid > subsystem->max_nsid) { 1743 SPDK_ERRLOG("ANAGRPID greater than maximum NSID not allowed\n"); 1744 return 0; 1745 } 1746 1747 ns = calloc(1, sizeof(*ns)); 1748 if (ns == NULL) { 1749 SPDK_ERRLOG("Namespace allocation failed\n"); 1750 return 0; 1751 } 1752 1753 rc = spdk_bdev_open_ext(bdev_name, true, nvmf_ns_event, ns, &ns->desc); 1754 if (rc != 0) { 1755 SPDK_ERRLOG("Subsystem %s: bdev %s cannot be opened, error=%d\n", 1756 subsystem->subnqn, bdev_name, rc); 1757 free(ns); 1758 return 0; 1759 } 1760 1761 ns->bdev = spdk_bdev_desc_get_bdev(ns->desc); 1762 1763 if (spdk_bdev_get_md_size(ns->bdev) != 0) { 1764 if (!spdk_bdev_is_md_interleaved(ns->bdev)) { 1765 SPDK_ERRLOG("Can't attach bdev with separate metadata.\n"); 1766 spdk_bdev_close(ns->desc); 1767 free(ns); 1768 return 0; 1769 } 1770 1771 if (spdk_bdev_get_md_size(ns->bdev) > SPDK_BDEV_MAX_INTERLEAVED_MD_SIZE) { 1772 SPDK_ERRLOG("Maximum supported interleaved md size %u, current md size %u\n", 1773 SPDK_BDEV_MAX_INTERLEAVED_MD_SIZE, spdk_bdev_get_md_size(ns->bdev)); 1774 spdk_bdev_close(ns->desc); 1775 free(ns); 1776 return 0; 1777 } 1778 } 1779 1780 rc = spdk_bdev_module_claim_bdev(ns->bdev, ns->desc, &ns_bdev_module); 1781 if (rc != 0) { 1782 spdk_bdev_close(ns->desc); 1783 free(ns); 1784 return 0; 1785 } 1786 1787 /* Cache the zcopy capability of the bdev device */ 1788 ns->zcopy = spdk_bdev_io_type_supported(ns->bdev, SPDK_BDEV_IO_TYPE_ZCOPY); 1789 1790 if (spdk_uuid_is_null(&opts.uuid)) { 1791 opts.uuid = *spdk_bdev_get_uuid(ns->bdev); 1792 } 1793 1794 /* if nguid descriptor is supported by bdev module (nvme) then uuid = nguid */ 1795 if (spdk_mem_all_zero(opts.nguid, sizeof(opts.nguid))) { 1796 SPDK_STATIC_ASSERT(sizeof(opts.nguid) == sizeof(opts.uuid), "size mismatch"); 1797 memcpy(opts.nguid, spdk_bdev_get_uuid(ns->bdev), sizeof(opts.nguid)); 1798 } 1799 1800 if (spdk_bdev_is_zoned(ns->bdev)) { 1801 SPDK_DEBUGLOG(nvmf, "The added namespace is backed by a zoned block device.\n"); 1802 ns->csi = SPDK_NVME_CSI_ZNS; 1803 1804 zone_append_supported = spdk_bdev_io_type_supported(ns->bdev, 1805 SPDK_BDEV_IO_TYPE_ZONE_APPEND); 1806 max_zone_append_size_kib = spdk_bdev_get_max_zone_append_size( 1807 ns->bdev) * spdk_bdev_get_block_size(ns->bdev); 1808 1809 if (_nvmf_subsystem_get_first_zoned_ns(subsystem) != NULL && 1810 (subsystem->zone_append_supported != zone_append_supported || 1811 subsystem->max_zone_append_size_kib != max_zone_append_size_kib)) { 1812 SPDK_ERRLOG("Namespaces with different zone append support or different zone append size are not allowed.\n"); 1813 goto err_ns_reservation_restore; 1814 } 1815 1816 subsystem->zone_append_supported = zone_append_supported; 1817 subsystem->max_zone_append_size_kib = max_zone_append_size_kib; 1818 } 1819 1820 ns->opts = opts; 1821 ns->subsystem = subsystem; 1822 subsystem->ns[opts.nsid - 1] = ns; 1823 ns->nsid = opts.nsid; 1824 ns->anagrpid = opts.anagrpid; 1825 subsystem->ana_group[ns->anagrpid - 1]++; 1826 TAILQ_INIT(&ns->registrants); 1827 if (ptpl_file) { 1828 rc = nvmf_ns_load_reservation(ptpl_file, &info); 1829 if (!rc) { 1830 rc = nvmf_ns_reservation_restore(ns, &info); 1831 if (rc) { 1832 SPDK_ERRLOG("Subsystem restore reservation failed\n"); 1833 goto err_ns_reservation_restore; 1834 } 1835 } 1836 ns->ptpl_file = strdup(ptpl_file); 1837 if (!ns->ptpl_file) { 1838 SPDK_ERRLOG("Namespace ns->ptpl_file allocation failed\n"); 1839 goto err_strdup; 1840 } 1841 } 1842 1843 for (transport = spdk_nvmf_transport_get_first(subsystem->tgt); transport; 1844 transport = spdk_nvmf_transport_get_next(transport)) { 1845 if (transport->ops->subsystem_add_ns) { 1846 rc = transport->ops->subsystem_add_ns(transport, subsystem, ns); 1847 if (rc) { 1848 SPDK_ERRLOG("Namespace attachment is not allowed by %s transport\n", transport->ops->name); 1849 goto err_subsystem_add_ns; 1850 } 1851 } 1852 } 1853 1854 SPDK_DEBUGLOG(nvmf, "Subsystem %s: bdev %s assigned nsid %" PRIu32 "\n", 1855 spdk_nvmf_subsystem_get_nqn(subsystem), 1856 bdev_name, 1857 opts.nsid); 1858 1859 nvmf_subsystem_ns_changed(subsystem, opts.nsid); 1860 1861 SPDK_DTRACE_PROBE2(nvmf_subsystem_add_ns, subsystem->subnqn, ns->nsid); 1862 1863 return opts.nsid; 1864 1865 err_subsystem_add_ns: 1866 free(ns->ptpl_file); 1867 err_strdup: 1868 nvmf_ns_reservation_clear_all_registrants(ns); 1869 err_ns_reservation_restore: 1870 subsystem->ns[opts.nsid - 1] = NULL; 1871 spdk_bdev_module_release_bdev(ns->bdev); 1872 spdk_bdev_close(ns->desc); 1873 free(ns); 1874 1875 return 0; 1876 } 1877 1878 static uint32_t 1879 nvmf_subsystem_get_next_allocated_nsid(struct spdk_nvmf_subsystem *subsystem, 1880 uint32_t prev_nsid) 1881 { 1882 uint32_t nsid; 1883 1884 if (prev_nsid >= subsystem->max_nsid) { 1885 return 0; 1886 } 1887 1888 for (nsid = prev_nsid + 1; nsid <= subsystem->max_nsid; nsid++) { 1889 if (subsystem->ns[nsid - 1]) { 1890 return nsid; 1891 } 1892 } 1893 1894 return 0; 1895 } 1896 1897 struct spdk_nvmf_ns * 1898 spdk_nvmf_subsystem_get_first_ns(struct spdk_nvmf_subsystem *subsystem) 1899 { 1900 uint32_t first_nsid; 1901 1902 first_nsid = nvmf_subsystem_get_next_allocated_nsid(subsystem, 0); 1903 return _nvmf_subsystem_get_ns(subsystem, first_nsid); 1904 } 1905 1906 struct spdk_nvmf_ns * 1907 spdk_nvmf_subsystem_get_next_ns(struct spdk_nvmf_subsystem *subsystem, 1908 struct spdk_nvmf_ns *prev_ns) 1909 { 1910 uint32_t next_nsid; 1911 1912 next_nsid = nvmf_subsystem_get_next_allocated_nsid(subsystem, prev_ns->opts.nsid); 1913 return _nvmf_subsystem_get_ns(subsystem, next_nsid); 1914 } 1915 1916 struct spdk_nvmf_ns * 1917 spdk_nvmf_subsystem_get_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) 1918 { 1919 return _nvmf_subsystem_get_ns(subsystem, nsid); 1920 } 1921 1922 uint32_t 1923 spdk_nvmf_ns_get_id(const struct spdk_nvmf_ns *ns) 1924 { 1925 return ns->opts.nsid; 1926 } 1927 1928 struct spdk_bdev * 1929 spdk_nvmf_ns_get_bdev(struct spdk_nvmf_ns *ns) 1930 { 1931 return ns->bdev; 1932 } 1933 1934 void 1935 spdk_nvmf_ns_get_opts(const struct spdk_nvmf_ns *ns, struct spdk_nvmf_ns_opts *opts, 1936 size_t opts_size) 1937 { 1938 memset(opts, 0, opts_size); 1939 memcpy(opts, &ns->opts, spdk_min(sizeof(ns->opts), opts_size)); 1940 } 1941 1942 const char * 1943 spdk_nvmf_subsystem_get_sn(const struct spdk_nvmf_subsystem *subsystem) 1944 { 1945 return subsystem->sn; 1946 } 1947 1948 int 1949 spdk_nvmf_subsystem_set_sn(struct spdk_nvmf_subsystem *subsystem, const char *sn) 1950 { 1951 size_t len, max_len; 1952 1953 max_len = sizeof(subsystem->sn) - 1; 1954 len = strlen(sn); 1955 if (len > max_len) { 1956 SPDK_DEBUGLOG(nvmf, "Invalid sn \"%s\": length %zu > max %zu\n", 1957 sn, len, max_len); 1958 return -1; 1959 } 1960 1961 if (!nvmf_valid_ascii_string(sn, len)) { 1962 SPDK_DEBUGLOG(nvmf, "Non-ASCII sn\n"); 1963 SPDK_LOGDUMP(nvmf, "sn", sn, len); 1964 return -1; 1965 } 1966 1967 snprintf(subsystem->sn, sizeof(subsystem->sn), "%s", sn); 1968 1969 return 0; 1970 } 1971 1972 const char * 1973 spdk_nvmf_subsystem_get_mn(const struct spdk_nvmf_subsystem *subsystem) 1974 { 1975 return subsystem->mn; 1976 } 1977 1978 int 1979 spdk_nvmf_subsystem_set_mn(struct spdk_nvmf_subsystem *subsystem, const char *mn) 1980 { 1981 size_t len, max_len; 1982 1983 if (mn == NULL) { 1984 mn = MODEL_NUMBER_DEFAULT; 1985 } 1986 max_len = sizeof(subsystem->mn) - 1; 1987 len = strlen(mn); 1988 if (len > max_len) { 1989 SPDK_DEBUGLOG(nvmf, "Invalid mn \"%s\": length %zu > max %zu\n", 1990 mn, len, max_len); 1991 return -1; 1992 } 1993 1994 if (!nvmf_valid_ascii_string(mn, len)) { 1995 SPDK_DEBUGLOG(nvmf, "Non-ASCII mn\n"); 1996 SPDK_LOGDUMP(nvmf, "mn", mn, len); 1997 return -1; 1998 } 1999 2000 snprintf(subsystem->mn, sizeof(subsystem->mn), "%s", mn); 2001 2002 return 0; 2003 } 2004 2005 const char * 2006 spdk_nvmf_subsystem_get_nqn(const struct spdk_nvmf_subsystem *subsystem) 2007 { 2008 return subsystem->subnqn; 2009 } 2010 2011 /* We have to use the typedef in the function declaration to appease astyle. */ 2012 typedef enum spdk_nvmf_subtype spdk_nvmf_subtype_t; 2013 2014 spdk_nvmf_subtype_t 2015 spdk_nvmf_subsystem_get_type(struct spdk_nvmf_subsystem *subsystem) 2016 { 2017 return subsystem->subtype; 2018 } 2019 2020 uint32_t 2021 spdk_nvmf_subsystem_get_max_nsid(struct spdk_nvmf_subsystem *subsystem) 2022 { 2023 return subsystem->max_nsid; 2024 } 2025 2026 int 2027 nvmf_subsystem_set_cntlid_range(struct spdk_nvmf_subsystem *subsystem, 2028 uint16_t min_cntlid, uint16_t max_cntlid) 2029 { 2030 if (subsystem->state != SPDK_NVMF_SUBSYSTEM_INACTIVE) { 2031 return -EAGAIN; 2032 } 2033 2034 if (min_cntlid > max_cntlid) { 2035 return -EINVAL; 2036 } 2037 /* The spec reserves cntlid values in the range FFF0h to FFFFh. */ 2038 if (min_cntlid < NVMF_MIN_CNTLID || min_cntlid > NVMF_MAX_CNTLID || 2039 max_cntlid < NVMF_MIN_CNTLID || max_cntlid > NVMF_MAX_CNTLID) { 2040 return -EINVAL; 2041 } 2042 subsystem->min_cntlid = min_cntlid; 2043 subsystem->max_cntlid = max_cntlid; 2044 if (subsystem->next_cntlid < min_cntlid || subsystem->next_cntlid > max_cntlid - 1) { 2045 subsystem->next_cntlid = min_cntlid - 1; 2046 } 2047 2048 return 0; 2049 } 2050 2051 static uint16_t 2052 nvmf_subsystem_gen_cntlid(struct spdk_nvmf_subsystem *subsystem) 2053 { 2054 int count; 2055 2056 /* 2057 * In the worst case, we might have to try all CNTLID values between min_cntlid and max_cntlid 2058 * before we find one that is unused (or find that all values are in use). 2059 */ 2060 for (count = 0; count < subsystem->max_cntlid - subsystem->min_cntlid + 1; count++) { 2061 subsystem->next_cntlid++; 2062 if (subsystem->next_cntlid > subsystem->max_cntlid) { 2063 subsystem->next_cntlid = subsystem->min_cntlid; 2064 } 2065 2066 /* Check if a controller with this cntlid currently exists. */ 2067 if (nvmf_subsystem_get_ctrlr(subsystem, subsystem->next_cntlid) == NULL) { 2068 /* Found unused cntlid */ 2069 return subsystem->next_cntlid; 2070 } 2071 } 2072 2073 /* All valid cntlid values are in use. */ 2074 return 0xFFFF; 2075 } 2076 2077 int 2078 nvmf_subsystem_add_ctrlr(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr) 2079 { 2080 2081 if (ctrlr->dynamic_ctrlr) { 2082 ctrlr->cntlid = nvmf_subsystem_gen_cntlid(subsystem); 2083 if (ctrlr->cntlid == 0xFFFF) { 2084 /* Unable to get a cntlid */ 2085 SPDK_ERRLOG("Reached max simultaneous ctrlrs\n"); 2086 return -EBUSY; 2087 } 2088 } else if (nvmf_subsystem_get_ctrlr(subsystem, ctrlr->cntlid) != NULL) { 2089 SPDK_ERRLOG("Ctrlr with cntlid %u already exist\n", ctrlr->cntlid); 2090 return -EEXIST; 2091 } 2092 2093 TAILQ_INSERT_TAIL(&subsystem->ctrlrs, ctrlr, link); 2094 2095 SPDK_DTRACE_PROBE3(nvmf_subsystem_add_ctrlr, subsystem->subnqn, ctrlr, ctrlr->hostnqn); 2096 2097 return 0; 2098 } 2099 2100 void 2101 nvmf_subsystem_remove_ctrlr(struct spdk_nvmf_subsystem *subsystem, 2102 struct spdk_nvmf_ctrlr *ctrlr) 2103 { 2104 SPDK_DTRACE_PROBE3(nvmf_subsystem_remove_ctrlr, subsystem->subnqn, ctrlr, ctrlr->hostnqn); 2105 2106 assert(spdk_get_thread() == subsystem->thread); 2107 assert(subsystem == ctrlr->subsys); 2108 SPDK_DEBUGLOG(nvmf, "remove ctrlr %p id 0x%x from subsys %p %s\n", ctrlr, ctrlr->cntlid, subsystem, 2109 subsystem->subnqn); 2110 TAILQ_REMOVE(&subsystem->ctrlrs, ctrlr, link); 2111 } 2112 2113 struct spdk_nvmf_ctrlr * 2114 nvmf_subsystem_get_ctrlr(struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid) 2115 { 2116 struct spdk_nvmf_ctrlr *ctrlr; 2117 2118 TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { 2119 if (ctrlr->cntlid == cntlid) { 2120 return ctrlr; 2121 } 2122 } 2123 2124 return NULL; 2125 } 2126 2127 uint32_t 2128 spdk_nvmf_subsystem_get_max_namespaces(const struct spdk_nvmf_subsystem *subsystem) 2129 { 2130 return subsystem->max_nsid; 2131 } 2132 2133 uint16_t 2134 spdk_nvmf_subsystem_get_min_cntlid(const struct spdk_nvmf_subsystem *subsystem) 2135 { 2136 return subsystem->min_cntlid; 2137 } 2138 2139 uint16_t 2140 spdk_nvmf_subsystem_get_max_cntlid(const struct spdk_nvmf_subsystem *subsystem) 2141 { 2142 return subsystem->max_cntlid; 2143 } 2144 2145 struct _nvmf_ns_registrant { 2146 uint64_t rkey; 2147 char *host_uuid; 2148 }; 2149 2150 struct _nvmf_ns_registrants { 2151 size_t num_regs; 2152 struct _nvmf_ns_registrant reg[SPDK_NVMF_MAX_NUM_REGISTRANTS]; 2153 }; 2154 2155 struct _nvmf_ns_reservation { 2156 bool ptpl_activated; 2157 enum spdk_nvme_reservation_type rtype; 2158 uint64_t crkey; 2159 char *bdev_uuid; 2160 char *holder_uuid; 2161 struct _nvmf_ns_registrants regs; 2162 }; 2163 2164 static const struct spdk_json_object_decoder nvmf_ns_pr_reg_decoders[] = { 2165 {"rkey", offsetof(struct _nvmf_ns_registrant, rkey), spdk_json_decode_uint64}, 2166 {"host_uuid", offsetof(struct _nvmf_ns_registrant, host_uuid), spdk_json_decode_string}, 2167 }; 2168 2169 static int 2170 nvmf_decode_ns_pr_reg(const struct spdk_json_val *val, void *out) 2171 { 2172 struct _nvmf_ns_registrant *reg = out; 2173 2174 return spdk_json_decode_object(val, nvmf_ns_pr_reg_decoders, 2175 SPDK_COUNTOF(nvmf_ns_pr_reg_decoders), reg); 2176 } 2177 2178 static int 2179 nvmf_decode_ns_pr_regs(const struct spdk_json_val *val, void *out) 2180 { 2181 struct _nvmf_ns_registrants *regs = out; 2182 2183 return spdk_json_decode_array(val, nvmf_decode_ns_pr_reg, regs->reg, 2184 SPDK_NVMF_MAX_NUM_REGISTRANTS, ®s->num_regs, 2185 sizeof(struct _nvmf_ns_registrant)); 2186 } 2187 2188 static const struct spdk_json_object_decoder nvmf_ns_pr_decoders[] = { 2189 {"ptpl", offsetof(struct _nvmf_ns_reservation, ptpl_activated), spdk_json_decode_bool, true}, 2190 {"rtype", offsetof(struct _nvmf_ns_reservation, rtype), spdk_json_decode_uint32, true}, 2191 {"crkey", offsetof(struct _nvmf_ns_reservation, crkey), spdk_json_decode_uint64, true}, 2192 {"bdev_uuid", offsetof(struct _nvmf_ns_reservation, bdev_uuid), spdk_json_decode_string}, 2193 {"holder_uuid", offsetof(struct _nvmf_ns_reservation, holder_uuid), spdk_json_decode_string, true}, 2194 {"registrants", offsetof(struct _nvmf_ns_reservation, regs), nvmf_decode_ns_pr_regs}, 2195 }; 2196 2197 static int 2198 nvmf_ns_load_reservation(const char *file, struct spdk_nvmf_reservation_info *info) 2199 { 2200 FILE *fd; 2201 size_t json_size; 2202 ssize_t values_cnt, rc; 2203 void *json = NULL, *end; 2204 struct spdk_json_val *values = NULL; 2205 struct _nvmf_ns_reservation res = {}; 2206 uint32_t i; 2207 2208 fd = fopen(file, "r"); 2209 /* It's not an error if the file does not exist */ 2210 if (!fd) { 2211 SPDK_NOTICELOG("File %s does not exist\n", file); 2212 return -ENOENT; 2213 } 2214 2215 /* Load all persist file contents into a local buffer */ 2216 json = spdk_posix_file_load(fd, &json_size); 2217 fclose(fd); 2218 if (!json) { 2219 SPDK_ERRLOG("Load persit file %s failed\n", file); 2220 return -ENOMEM; 2221 } 2222 2223 rc = spdk_json_parse(json, json_size, NULL, 0, &end, 0); 2224 if (rc < 0) { 2225 SPDK_NOTICELOG("Parsing JSON configuration failed (%zd)\n", rc); 2226 goto exit; 2227 } 2228 2229 values_cnt = rc; 2230 values = calloc(values_cnt, sizeof(struct spdk_json_val)); 2231 if (values == NULL) { 2232 goto exit; 2233 } 2234 2235 rc = spdk_json_parse(json, json_size, values, values_cnt, &end, 0); 2236 if (rc != values_cnt) { 2237 SPDK_ERRLOG("Parsing JSON configuration failed (%zd)\n", rc); 2238 goto exit; 2239 } 2240 2241 /* Decode json */ 2242 if (spdk_json_decode_object(values, nvmf_ns_pr_decoders, 2243 SPDK_COUNTOF(nvmf_ns_pr_decoders), 2244 &res)) { 2245 SPDK_ERRLOG("Invalid objects in the persist file %s\n", file); 2246 rc = -EINVAL; 2247 goto exit; 2248 } 2249 2250 if (res.regs.num_regs > SPDK_NVMF_MAX_NUM_REGISTRANTS) { 2251 SPDK_ERRLOG("Can only support up to %u registrants\n", SPDK_NVMF_MAX_NUM_REGISTRANTS); 2252 rc = -ERANGE; 2253 goto exit; 2254 } 2255 2256 rc = 0; 2257 info->ptpl_activated = res.ptpl_activated; 2258 info->rtype = res.rtype; 2259 info->crkey = res.crkey; 2260 snprintf(info->bdev_uuid, sizeof(info->bdev_uuid), "%s", res.bdev_uuid); 2261 snprintf(info->holder_uuid, sizeof(info->holder_uuid), "%s", res.holder_uuid); 2262 info->num_regs = res.regs.num_regs; 2263 for (i = 0; i < res.regs.num_regs; i++) { 2264 info->registrants[i].rkey = res.regs.reg[i].rkey; 2265 snprintf(info->registrants[i].host_uuid, sizeof(info->registrants[i].host_uuid), "%s", 2266 res.regs.reg[i].host_uuid); 2267 } 2268 2269 exit: 2270 free(json); 2271 free(values); 2272 free(res.bdev_uuid); 2273 free(res.holder_uuid); 2274 for (i = 0; i < res.regs.num_regs; i++) { 2275 free(res.regs.reg[i].host_uuid); 2276 } 2277 2278 return rc; 2279 } 2280 2281 static bool nvmf_ns_reservation_all_registrants_type(struct spdk_nvmf_ns *ns); 2282 2283 static int 2284 nvmf_ns_reservation_restore(struct spdk_nvmf_ns *ns, struct spdk_nvmf_reservation_info *info) 2285 { 2286 uint32_t i; 2287 struct spdk_nvmf_registrant *reg, *holder = NULL; 2288 struct spdk_uuid bdev_uuid, holder_uuid; 2289 bool rkey_flag = false; 2290 2291 SPDK_DEBUGLOG(nvmf, "NSID %u, PTPL %u, Number of registrants %u\n", 2292 ns->nsid, info->ptpl_activated, info->num_regs); 2293 2294 /* it's not an error */ 2295 if (!info->ptpl_activated || !info->num_regs) { 2296 return 0; 2297 } 2298 2299 /* Check info->crkey exist or not in info->registrants[i].rkey */ 2300 for (i = 0; i < info->num_regs; i++) { 2301 if (info->crkey == info->registrants[i].rkey) { 2302 rkey_flag = true; 2303 } 2304 } 2305 if (!rkey_flag) { 2306 return -EINVAL; 2307 } 2308 2309 spdk_uuid_parse(&bdev_uuid, info->bdev_uuid); 2310 if (spdk_uuid_compare(&bdev_uuid, spdk_bdev_get_uuid(ns->bdev))) { 2311 SPDK_ERRLOG("Existing bdev UUID is not same with configuration file\n"); 2312 return -EINVAL; 2313 } 2314 2315 ns->crkey = info->crkey; 2316 ns->rtype = info->rtype; 2317 ns->ptpl_activated = info->ptpl_activated; 2318 spdk_uuid_parse(&holder_uuid, info->holder_uuid); 2319 2320 SPDK_DEBUGLOG(nvmf, "Bdev UUID %s\n", info->bdev_uuid); 2321 if (info->rtype) { 2322 SPDK_DEBUGLOG(nvmf, "Holder UUID %s, RTYPE %u, RKEY 0x%"PRIx64"\n", 2323 info->holder_uuid, info->rtype, info->crkey); 2324 } 2325 2326 for (i = 0; i < info->num_regs; i++) { 2327 reg = calloc(1, sizeof(*reg)); 2328 if (!reg) { 2329 return -ENOMEM; 2330 } 2331 spdk_uuid_parse(®->hostid, info->registrants[i].host_uuid); 2332 reg->rkey = info->registrants[i].rkey; 2333 TAILQ_INSERT_TAIL(&ns->registrants, reg, link); 2334 if (!spdk_uuid_compare(&holder_uuid, ®->hostid)) { 2335 holder = reg; 2336 } 2337 SPDK_DEBUGLOG(nvmf, "Registrant RKEY 0x%"PRIx64", Host UUID %s\n", 2338 info->registrants[i].rkey, info->registrants[i].host_uuid); 2339 } 2340 2341 if (nvmf_ns_reservation_all_registrants_type(ns)) { 2342 ns->holder = TAILQ_FIRST(&ns->registrants); 2343 } else { 2344 ns->holder = holder; 2345 } 2346 2347 return 0; 2348 } 2349 2350 static int 2351 nvmf_ns_json_write_cb(void *cb_ctx, const void *data, size_t size) 2352 { 2353 char *file = cb_ctx; 2354 size_t rc; 2355 FILE *fd; 2356 2357 fd = fopen(file, "w"); 2358 if (!fd) { 2359 SPDK_ERRLOG("Can't open file %s for write\n", file); 2360 return -ENOENT; 2361 } 2362 rc = fwrite(data, 1, size, fd); 2363 fclose(fd); 2364 2365 return rc == size ? 0 : -1; 2366 } 2367 2368 static int 2369 nvmf_ns_reservation_update(const char *file, struct spdk_nvmf_reservation_info *info) 2370 { 2371 struct spdk_json_write_ctx *w; 2372 uint32_t i; 2373 int rc = 0; 2374 2375 w = spdk_json_write_begin(nvmf_ns_json_write_cb, (void *)file, 0); 2376 if (w == NULL) { 2377 return -ENOMEM; 2378 } 2379 /* clear the configuration file */ 2380 if (!info->ptpl_activated) { 2381 goto exit; 2382 } 2383 2384 spdk_json_write_object_begin(w); 2385 spdk_json_write_named_bool(w, "ptpl", info->ptpl_activated); 2386 spdk_json_write_named_uint32(w, "rtype", info->rtype); 2387 spdk_json_write_named_uint64(w, "crkey", info->crkey); 2388 spdk_json_write_named_string(w, "bdev_uuid", info->bdev_uuid); 2389 spdk_json_write_named_string(w, "holder_uuid", info->holder_uuid); 2390 2391 spdk_json_write_named_array_begin(w, "registrants"); 2392 for (i = 0; i < info->num_regs; i++) { 2393 spdk_json_write_object_begin(w); 2394 spdk_json_write_named_uint64(w, "rkey", info->registrants[i].rkey); 2395 spdk_json_write_named_string(w, "host_uuid", info->registrants[i].host_uuid); 2396 spdk_json_write_object_end(w); 2397 } 2398 spdk_json_write_array_end(w); 2399 spdk_json_write_object_end(w); 2400 2401 exit: 2402 rc = spdk_json_write_end(w); 2403 return rc; 2404 } 2405 2406 static int 2407 nvmf_ns_update_reservation_info(struct spdk_nvmf_ns *ns) 2408 { 2409 struct spdk_nvmf_reservation_info info; 2410 struct spdk_nvmf_registrant *reg, *tmp; 2411 uint32_t i = 0; 2412 2413 assert(ns != NULL); 2414 2415 if (!ns->bdev || !ns->ptpl_file) { 2416 return 0; 2417 } 2418 2419 memset(&info, 0, sizeof(info)); 2420 spdk_uuid_fmt_lower(info.bdev_uuid, sizeof(info.bdev_uuid), spdk_bdev_get_uuid(ns->bdev)); 2421 2422 if (ns->rtype) { 2423 info.rtype = ns->rtype; 2424 info.crkey = ns->crkey; 2425 if (!nvmf_ns_reservation_all_registrants_type(ns)) { 2426 assert(ns->holder != NULL); 2427 spdk_uuid_fmt_lower(info.holder_uuid, sizeof(info.holder_uuid), &ns->holder->hostid); 2428 } 2429 } 2430 2431 TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) { 2432 spdk_uuid_fmt_lower(info.registrants[i].host_uuid, sizeof(info.registrants[i].host_uuid), 2433 ®->hostid); 2434 info.registrants[i++].rkey = reg->rkey; 2435 } 2436 2437 info.num_regs = i; 2438 info.ptpl_activated = ns->ptpl_activated; 2439 2440 return nvmf_ns_reservation_update(ns->ptpl_file, &info); 2441 } 2442 2443 static struct spdk_nvmf_registrant * 2444 nvmf_ns_reservation_get_registrant(struct spdk_nvmf_ns *ns, 2445 struct spdk_uuid *uuid) 2446 { 2447 struct spdk_nvmf_registrant *reg, *tmp; 2448 2449 TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) { 2450 if (!spdk_uuid_compare(®->hostid, uuid)) { 2451 return reg; 2452 } 2453 } 2454 2455 return NULL; 2456 } 2457 2458 /* Generate reservation notice log to registered HostID controllers */ 2459 static void 2460 nvmf_subsystem_gen_ctrlr_notification(struct spdk_nvmf_subsystem *subsystem, 2461 struct spdk_nvmf_ns *ns, 2462 struct spdk_uuid *hostid_list, 2463 uint32_t num_hostid, 2464 enum spdk_nvme_reservation_notification_log_page_type type) 2465 { 2466 struct spdk_nvmf_ctrlr *ctrlr; 2467 uint32_t i; 2468 2469 for (i = 0; i < num_hostid; i++) { 2470 TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { 2471 if (!spdk_uuid_compare(&ctrlr->hostid, &hostid_list[i])) { 2472 nvmf_ctrlr_reservation_notice_log(ctrlr, ns, type); 2473 } 2474 } 2475 } 2476 } 2477 2478 /* Get all registrants' hostid other than the controller who issued the command */ 2479 static uint32_t 2480 nvmf_ns_reservation_get_all_other_hostid(struct spdk_nvmf_ns *ns, 2481 struct spdk_uuid *hostid_list, 2482 uint32_t max_num_hostid, 2483 struct spdk_uuid *current_hostid) 2484 { 2485 struct spdk_nvmf_registrant *reg, *tmp; 2486 uint32_t num_hostid = 0; 2487 2488 TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) { 2489 if (spdk_uuid_compare(®->hostid, current_hostid)) { 2490 if (num_hostid == max_num_hostid) { 2491 assert(false); 2492 return max_num_hostid; 2493 } 2494 hostid_list[num_hostid++] = reg->hostid; 2495 } 2496 } 2497 2498 return num_hostid; 2499 } 2500 2501 /* Calculate the unregistered HostID list according to list 2502 * prior to execute preempt command and list after executing 2503 * preempt command. 2504 */ 2505 static uint32_t 2506 nvmf_ns_reservation_get_unregistered_hostid(struct spdk_uuid *old_hostid_list, 2507 uint32_t old_num_hostid, 2508 struct spdk_uuid *remaining_hostid_list, 2509 uint32_t remaining_num_hostid) 2510 { 2511 struct spdk_uuid temp_hostid_list[SPDK_NVMF_MAX_NUM_REGISTRANTS]; 2512 uint32_t i, j, num_hostid = 0; 2513 bool found; 2514 2515 if (!remaining_num_hostid) { 2516 return old_num_hostid; 2517 } 2518 2519 for (i = 0; i < old_num_hostid; i++) { 2520 found = false; 2521 for (j = 0; j < remaining_num_hostid; j++) { 2522 if (!spdk_uuid_compare(&old_hostid_list[i], &remaining_hostid_list[j])) { 2523 found = true; 2524 break; 2525 } 2526 } 2527 if (!found) { 2528 spdk_uuid_copy(&temp_hostid_list[num_hostid++], &old_hostid_list[i]); 2529 } 2530 } 2531 2532 if (num_hostid) { 2533 memcpy(old_hostid_list, temp_hostid_list, sizeof(struct spdk_uuid) * num_hostid); 2534 } 2535 2536 return num_hostid; 2537 } 2538 2539 /* current reservation type is all registrants or not */ 2540 static bool 2541 nvmf_ns_reservation_all_registrants_type(struct spdk_nvmf_ns *ns) 2542 { 2543 return (ns->rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS || 2544 ns->rtype == SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS); 2545 } 2546 2547 /* current registrant is reservation holder or not */ 2548 static bool 2549 nvmf_ns_reservation_registrant_is_holder(struct spdk_nvmf_ns *ns, 2550 struct spdk_nvmf_registrant *reg) 2551 { 2552 if (!reg) { 2553 return false; 2554 } 2555 2556 if (nvmf_ns_reservation_all_registrants_type(ns)) { 2557 return true; 2558 } 2559 2560 return (ns->holder == reg); 2561 } 2562 2563 static int 2564 nvmf_ns_reservation_add_registrant(struct spdk_nvmf_ns *ns, 2565 struct spdk_nvmf_ctrlr *ctrlr, 2566 uint64_t nrkey) 2567 { 2568 struct spdk_nvmf_registrant *reg; 2569 2570 reg = calloc(1, sizeof(*reg)); 2571 if (!reg) { 2572 return -ENOMEM; 2573 } 2574 2575 reg->rkey = nrkey; 2576 /* set hostid for the registrant */ 2577 spdk_uuid_copy(®->hostid, &ctrlr->hostid); 2578 TAILQ_INSERT_TAIL(&ns->registrants, reg, link); 2579 ns->gen++; 2580 2581 return 0; 2582 } 2583 2584 static void 2585 nvmf_ns_reservation_release_reservation(struct spdk_nvmf_ns *ns) 2586 { 2587 ns->rtype = 0; 2588 ns->crkey = 0; 2589 ns->holder = NULL; 2590 } 2591 2592 /* release the reservation if the last registrant was removed */ 2593 static void 2594 nvmf_ns_reservation_check_release_on_remove_registrant(struct spdk_nvmf_ns *ns, 2595 struct spdk_nvmf_registrant *reg) 2596 { 2597 struct spdk_nvmf_registrant *next_reg; 2598 2599 /* no reservation holder */ 2600 if (!ns->holder) { 2601 assert(ns->rtype == 0); 2602 return; 2603 } 2604 2605 next_reg = TAILQ_FIRST(&ns->registrants); 2606 if (next_reg && nvmf_ns_reservation_all_registrants_type(ns)) { 2607 /* the next valid registrant is the new holder now */ 2608 ns->holder = next_reg; 2609 } else if (nvmf_ns_reservation_registrant_is_holder(ns, reg)) { 2610 /* release the reservation */ 2611 nvmf_ns_reservation_release_reservation(ns); 2612 } 2613 } 2614 2615 static void 2616 nvmf_ns_reservation_remove_registrant(struct spdk_nvmf_ns *ns, 2617 struct spdk_nvmf_registrant *reg) 2618 { 2619 TAILQ_REMOVE(&ns->registrants, reg, link); 2620 nvmf_ns_reservation_check_release_on_remove_registrant(ns, reg); 2621 free(reg); 2622 ns->gen++; 2623 return; 2624 } 2625 2626 static uint32_t 2627 nvmf_ns_reservation_remove_registrants_by_key(struct spdk_nvmf_ns *ns, 2628 uint64_t rkey) 2629 { 2630 struct spdk_nvmf_registrant *reg, *tmp; 2631 uint32_t count = 0; 2632 2633 TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) { 2634 if (reg->rkey == rkey) { 2635 nvmf_ns_reservation_remove_registrant(ns, reg); 2636 count++; 2637 } 2638 } 2639 return count; 2640 } 2641 2642 static uint32_t 2643 nvmf_ns_reservation_remove_all_other_registrants(struct spdk_nvmf_ns *ns, 2644 struct spdk_nvmf_registrant *reg) 2645 { 2646 struct spdk_nvmf_registrant *reg_tmp, *reg_tmp2; 2647 uint32_t count = 0; 2648 2649 TAILQ_FOREACH_SAFE(reg_tmp, &ns->registrants, link, reg_tmp2) { 2650 if (reg_tmp != reg) { 2651 nvmf_ns_reservation_remove_registrant(ns, reg_tmp); 2652 count++; 2653 } 2654 } 2655 return count; 2656 } 2657 2658 static uint32_t 2659 nvmf_ns_reservation_clear_all_registrants(struct spdk_nvmf_ns *ns) 2660 { 2661 struct spdk_nvmf_registrant *reg, *reg_tmp; 2662 uint32_t count = 0; 2663 2664 TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, reg_tmp) { 2665 nvmf_ns_reservation_remove_registrant(ns, reg); 2666 count++; 2667 } 2668 return count; 2669 } 2670 2671 static void 2672 nvmf_ns_reservation_acquire_reservation(struct spdk_nvmf_ns *ns, uint64_t rkey, 2673 enum spdk_nvme_reservation_type rtype, 2674 struct spdk_nvmf_registrant *holder) 2675 { 2676 ns->rtype = rtype; 2677 ns->crkey = rkey; 2678 assert(ns->holder == NULL); 2679 ns->holder = holder; 2680 } 2681 2682 static bool 2683 nvmf_ns_reservation_register(struct spdk_nvmf_ns *ns, 2684 struct spdk_nvmf_ctrlr *ctrlr, 2685 struct spdk_nvmf_request *req) 2686 { 2687 struct spdk_nvme_reservation_register_data key = { 0 }; 2688 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 2689 uint8_t rrega, iekey, cptpl, rtype; 2690 struct spdk_nvmf_registrant *reg; 2691 uint8_t status = SPDK_NVME_SC_SUCCESS; 2692 bool update_sgroup = false; 2693 struct spdk_uuid hostid_list[SPDK_NVMF_MAX_NUM_REGISTRANTS]; 2694 uint32_t num_hostid = 0; 2695 int rc; 2696 2697 rrega = cmd->cdw10_bits.resv_register.rrega; 2698 iekey = cmd->cdw10_bits.resv_register.iekey; 2699 cptpl = cmd->cdw10_bits.resv_register.cptpl; 2700 2701 if (req->iovcnt > 0 && req->length >= sizeof(key)) { 2702 struct spdk_iov_xfer ix; 2703 spdk_iov_xfer_init(&ix, req->iov, req->iovcnt); 2704 spdk_iov_xfer_to_buf(&ix, &key, sizeof(key)); 2705 } else { 2706 SPDK_ERRLOG("No key provided. Failing request.\n"); 2707 status = SPDK_NVME_SC_INVALID_FIELD; 2708 goto exit; 2709 } 2710 2711 SPDK_DEBUGLOG(nvmf, "REGISTER: RREGA %u, IEKEY %u, CPTPL %u, " 2712 "NRKEY 0x%"PRIx64", NRKEY 0x%"PRIx64"\n", 2713 rrega, iekey, cptpl, key.crkey, key.nrkey); 2714 2715 if (cptpl == SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON) { 2716 /* Ture to OFF state, and need to be updated in the configuration file */ 2717 if (ns->ptpl_activated) { 2718 ns->ptpl_activated = 0; 2719 update_sgroup = true; 2720 } 2721 } else if (cptpl == SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS) { 2722 if (ns->ptpl_file == NULL) { 2723 status = SPDK_NVME_SC_INVALID_FIELD; 2724 goto exit; 2725 } else if (ns->ptpl_activated == 0) { 2726 ns->ptpl_activated = 1; 2727 update_sgroup = true; 2728 } 2729 } 2730 2731 /* current Host Identifier has registrant or not */ 2732 reg = nvmf_ns_reservation_get_registrant(ns, &ctrlr->hostid); 2733 2734 switch (rrega) { 2735 case SPDK_NVME_RESERVE_REGISTER_KEY: 2736 if (!reg) { 2737 /* register new controller */ 2738 if (key.nrkey == 0) { 2739 SPDK_ERRLOG("Can't register zeroed new key\n"); 2740 status = SPDK_NVME_SC_INVALID_FIELD; 2741 goto exit; 2742 } 2743 rc = nvmf_ns_reservation_add_registrant(ns, ctrlr, key.nrkey); 2744 if (rc < 0) { 2745 status = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 2746 goto exit; 2747 } 2748 update_sgroup = true; 2749 } else { 2750 /* register with same key is not an error */ 2751 if (reg->rkey != key.nrkey) { 2752 SPDK_ERRLOG("The same host already register a " 2753 "key with 0x%"PRIx64"\n", 2754 reg->rkey); 2755 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2756 goto exit; 2757 } 2758 } 2759 break; 2760 case SPDK_NVME_RESERVE_UNREGISTER_KEY: 2761 if (!reg || (!iekey && reg->rkey != key.crkey)) { 2762 SPDK_ERRLOG("No registrant or current key doesn't match " 2763 "with existing registrant key\n"); 2764 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2765 goto exit; 2766 } 2767 2768 rtype = ns->rtype; 2769 num_hostid = nvmf_ns_reservation_get_all_other_hostid(ns, hostid_list, 2770 SPDK_NVMF_MAX_NUM_REGISTRANTS, 2771 &ctrlr->hostid); 2772 2773 nvmf_ns_reservation_remove_registrant(ns, reg); 2774 2775 if (!ns->rtype && num_hostid && (rtype == SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY || 2776 rtype == SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY)) { 2777 nvmf_subsystem_gen_ctrlr_notification(ns->subsystem, ns, 2778 hostid_list, 2779 num_hostid, 2780 SPDK_NVME_RESERVATION_RELEASED); 2781 } 2782 update_sgroup = true; 2783 break; 2784 case SPDK_NVME_RESERVE_REPLACE_KEY: 2785 if (key.nrkey == 0) { 2786 SPDK_ERRLOG("Can't register zeroed new key\n"); 2787 status = SPDK_NVME_SC_INVALID_FIELD; 2788 goto exit; 2789 } 2790 /* Registrant exists */ 2791 if (reg) { 2792 if (!iekey && reg->rkey != key.crkey) { 2793 SPDK_ERRLOG("Current key doesn't match " 2794 "existing registrant key\n"); 2795 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2796 goto exit; 2797 } 2798 if (reg->rkey == key.nrkey) { 2799 goto exit; 2800 } 2801 reg->rkey = key.nrkey; 2802 } else if (iekey) { /* No registrant but IEKEY is set */ 2803 /* new registrant */ 2804 rc = nvmf_ns_reservation_add_registrant(ns, ctrlr, key.nrkey); 2805 if (rc < 0) { 2806 status = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 2807 goto exit; 2808 } 2809 } else { /* No registrant */ 2810 SPDK_ERRLOG("No registrant\n"); 2811 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2812 goto exit; 2813 2814 } 2815 update_sgroup = true; 2816 break; 2817 default: 2818 status = SPDK_NVME_SC_INVALID_FIELD; 2819 goto exit; 2820 } 2821 2822 exit: 2823 if (update_sgroup) { 2824 rc = nvmf_ns_update_reservation_info(ns); 2825 if (rc != 0) { 2826 status = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 2827 } 2828 } 2829 req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 2830 req->rsp->nvme_cpl.status.sc = status; 2831 return update_sgroup; 2832 } 2833 2834 static bool 2835 nvmf_ns_reservation_acquire(struct spdk_nvmf_ns *ns, 2836 struct spdk_nvmf_ctrlr *ctrlr, 2837 struct spdk_nvmf_request *req) 2838 { 2839 struct spdk_nvme_reservation_acquire_data key = { 0 }; 2840 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 2841 uint8_t racqa, iekey, rtype; 2842 struct spdk_nvmf_registrant *reg; 2843 bool all_regs = false; 2844 uint32_t count = 0; 2845 bool update_sgroup = true; 2846 struct spdk_uuid hostid_list[SPDK_NVMF_MAX_NUM_REGISTRANTS]; 2847 uint32_t num_hostid = 0; 2848 struct spdk_uuid new_hostid_list[SPDK_NVMF_MAX_NUM_REGISTRANTS]; 2849 uint32_t new_num_hostid = 0; 2850 bool reservation_released = false; 2851 uint8_t status = SPDK_NVME_SC_SUCCESS; 2852 2853 racqa = cmd->cdw10_bits.resv_acquire.racqa; 2854 iekey = cmd->cdw10_bits.resv_acquire.iekey; 2855 rtype = cmd->cdw10_bits.resv_acquire.rtype; 2856 2857 if (req->iovcnt > 0 && req->length >= sizeof(key)) { 2858 struct spdk_iov_xfer ix; 2859 spdk_iov_xfer_init(&ix, req->iov, req->iovcnt); 2860 spdk_iov_xfer_to_buf(&ix, &key, sizeof(key)); 2861 } else { 2862 SPDK_ERRLOG("No key provided. Failing request.\n"); 2863 status = SPDK_NVME_SC_INVALID_FIELD; 2864 goto exit; 2865 } 2866 2867 SPDK_DEBUGLOG(nvmf, "ACQUIRE: RACQA %u, IEKEY %u, RTYPE %u, " 2868 "NRKEY 0x%"PRIx64", PRKEY 0x%"PRIx64"\n", 2869 racqa, iekey, rtype, key.crkey, key.prkey); 2870 2871 if (iekey || rtype > SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS) { 2872 SPDK_ERRLOG("Ignore existing key field set to 1\n"); 2873 status = SPDK_NVME_SC_INVALID_FIELD; 2874 update_sgroup = false; 2875 goto exit; 2876 } 2877 2878 reg = nvmf_ns_reservation_get_registrant(ns, &ctrlr->hostid); 2879 /* must be registrant and CRKEY must match */ 2880 if (!reg || reg->rkey != key.crkey) { 2881 SPDK_ERRLOG("No registrant or current key doesn't match " 2882 "with existing registrant key\n"); 2883 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2884 update_sgroup = false; 2885 goto exit; 2886 } 2887 2888 all_regs = nvmf_ns_reservation_all_registrants_type(ns); 2889 2890 switch (racqa) { 2891 case SPDK_NVME_RESERVE_ACQUIRE: 2892 /* it's not an error for the holder to acquire same reservation type again */ 2893 if (nvmf_ns_reservation_registrant_is_holder(ns, reg) && ns->rtype == rtype) { 2894 /* do nothing */ 2895 update_sgroup = false; 2896 } else if (ns->holder == NULL) { 2897 /* first time to acquire the reservation */ 2898 nvmf_ns_reservation_acquire_reservation(ns, key.crkey, rtype, reg); 2899 } else { 2900 SPDK_ERRLOG("Invalid rtype or current registrant is not holder\n"); 2901 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2902 update_sgroup = false; 2903 goto exit; 2904 } 2905 break; 2906 case SPDK_NVME_RESERVE_PREEMPT: 2907 /* no reservation holder */ 2908 if (!ns->holder) { 2909 /* unregister with PRKEY */ 2910 nvmf_ns_reservation_remove_registrants_by_key(ns, key.prkey); 2911 break; 2912 } 2913 num_hostid = nvmf_ns_reservation_get_all_other_hostid(ns, hostid_list, 2914 SPDK_NVMF_MAX_NUM_REGISTRANTS, 2915 &ctrlr->hostid); 2916 2917 /* only 1 reservation holder and reservation key is valid */ 2918 if (!all_regs) { 2919 /* preempt itself */ 2920 if (nvmf_ns_reservation_registrant_is_holder(ns, reg) && 2921 ns->crkey == key.prkey) { 2922 ns->rtype = rtype; 2923 reservation_released = true; 2924 break; 2925 } 2926 2927 if (ns->crkey == key.prkey) { 2928 nvmf_ns_reservation_remove_registrant(ns, ns->holder); 2929 nvmf_ns_reservation_acquire_reservation(ns, key.crkey, rtype, reg); 2930 reservation_released = true; 2931 } else if (key.prkey != 0) { 2932 nvmf_ns_reservation_remove_registrants_by_key(ns, key.prkey); 2933 } else { 2934 /* PRKEY is zero */ 2935 SPDK_ERRLOG("Current PRKEY is zero\n"); 2936 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2937 update_sgroup = false; 2938 goto exit; 2939 } 2940 } else { 2941 /* release all other registrants except for the current one */ 2942 if (key.prkey == 0) { 2943 nvmf_ns_reservation_remove_all_other_registrants(ns, reg); 2944 assert(ns->holder == reg); 2945 } else { 2946 count = nvmf_ns_reservation_remove_registrants_by_key(ns, key.prkey); 2947 if (count == 0) { 2948 SPDK_ERRLOG("PRKEY doesn't match any registrant\n"); 2949 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 2950 update_sgroup = false; 2951 goto exit; 2952 } 2953 } 2954 } 2955 break; 2956 default: 2957 status = SPDK_NVME_SC_INVALID_FIELD; 2958 update_sgroup = false; 2959 break; 2960 } 2961 2962 exit: 2963 if (update_sgroup && racqa == SPDK_NVME_RESERVE_PREEMPT) { 2964 new_num_hostid = nvmf_ns_reservation_get_all_other_hostid(ns, new_hostid_list, 2965 SPDK_NVMF_MAX_NUM_REGISTRANTS, 2966 &ctrlr->hostid); 2967 /* Preempt notification occurs on the unregistered controllers 2968 * other than the controller who issued the command. 2969 */ 2970 num_hostid = nvmf_ns_reservation_get_unregistered_hostid(hostid_list, 2971 num_hostid, 2972 new_hostid_list, 2973 new_num_hostid); 2974 if (num_hostid) { 2975 nvmf_subsystem_gen_ctrlr_notification(ns->subsystem, ns, 2976 hostid_list, 2977 num_hostid, 2978 SPDK_NVME_REGISTRATION_PREEMPTED); 2979 2980 } 2981 /* Reservation released notification occurs on the 2982 * controllers which are the remaining registrants other than 2983 * the controller who issued the command. 2984 */ 2985 if (reservation_released && new_num_hostid) { 2986 nvmf_subsystem_gen_ctrlr_notification(ns->subsystem, ns, 2987 new_hostid_list, 2988 new_num_hostid, 2989 SPDK_NVME_RESERVATION_RELEASED); 2990 2991 } 2992 } 2993 if (update_sgroup && ns->ptpl_activated) { 2994 if (nvmf_ns_update_reservation_info(ns)) { 2995 status = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 2996 } 2997 } 2998 req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 2999 req->rsp->nvme_cpl.status.sc = status; 3000 return update_sgroup; 3001 } 3002 3003 static bool 3004 nvmf_ns_reservation_release(struct spdk_nvmf_ns *ns, 3005 struct spdk_nvmf_ctrlr *ctrlr, 3006 struct spdk_nvmf_request *req) 3007 { 3008 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 3009 uint8_t rrela, iekey, rtype; 3010 struct spdk_nvmf_registrant *reg; 3011 uint64_t crkey = 0; 3012 uint8_t status = SPDK_NVME_SC_SUCCESS; 3013 bool update_sgroup = true; 3014 struct spdk_uuid hostid_list[SPDK_NVMF_MAX_NUM_REGISTRANTS]; 3015 uint32_t num_hostid = 0; 3016 3017 rrela = cmd->cdw10_bits.resv_release.rrela; 3018 iekey = cmd->cdw10_bits.resv_release.iekey; 3019 rtype = cmd->cdw10_bits.resv_release.rtype; 3020 3021 if (req->iovcnt > 0 && req->length >= sizeof(crkey)) { 3022 struct spdk_iov_xfer ix; 3023 spdk_iov_xfer_init(&ix, req->iov, req->iovcnt); 3024 spdk_iov_xfer_to_buf(&ix, &crkey, sizeof(crkey)); 3025 } else { 3026 SPDK_ERRLOG("No key provided. Failing request.\n"); 3027 status = SPDK_NVME_SC_INVALID_FIELD; 3028 goto exit; 3029 } 3030 3031 SPDK_DEBUGLOG(nvmf, "RELEASE: RRELA %u, IEKEY %u, RTYPE %u, " 3032 "CRKEY 0x%"PRIx64"\n", rrela, iekey, rtype, crkey); 3033 3034 if (iekey) { 3035 SPDK_ERRLOG("Ignore existing key field set to 1\n"); 3036 status = SPDK_NVME_SC_INVALID_FIELD; 3037 update_sgroup = false; 3038 goto exit; 3039 } 3040 3041 reg = nvmf_ns_reservation_get_registrant(ns, &ctrlr->hostid); 3042 if (!reg || reg->rkey != crkey) { 3043 SPDK_ERRLOG("No registrant or current key doesn't match " 3044 "with existing registrant key\n"); 3045 status = SPDK_NVME_SC_RESERVATION_CONFLICT; 3046 update_sgroup = false; 3047 goto exit; 3048 } 3049 3050 num_hostid = nvmf_ns_reservation_get_all_other_hostid(ns, hostid_list, 3051 SPDK_NVMF_MAX_NUM_REGISTRANTS, 3052 &ctrlr->hostid); 3053 3054 switch (rrela) { 3055 case SPDK_NVME_RESERVE_RELEASE: 3056 if (!ns->holder) { 3057 SPDK_DEBUGLOG(nvmf, "RELEASE: no holder\n"); 3058 update_sgroup = false; 3059 goto exit; 3060 } 3061 if (ns->rtype != rtype) { 3062 SPDK_ERRLOG("Type doesn't match\n"); 3063 status = SPDK_NVME_SC_INVALID_FIELD; 3064 update_sgroup = false; 3065 goto exit; 3066 } 3067 if (!nvmf_ns_reservation_registrant_is_holder(ns, reg)) { 3068 /* not the reservation holder, this isn't an error */ 3069 update_sgroup = false; 3070 goto exit; 3071 } 3072 3073 rtype = ns->rtype; 3074 nvmf_ns_reservation_release_reservation(ns); 3075 3076 if (num_hostid && rtype != SPDK_NVME_RESERVE_WRITE_EXCLUSIVE && 3077 rtype != SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS) { 3078 nvmf_subsystem_gen_ctrlr_notification(ns->subsystem, ns, 3079 hostid_list, 3080 num_hostid, 3081 SPDK_NVME_RESERVATION_RELEASED); 3082 } 3083 break; 3084 case SPDK_NVME_RESERVE_CLEAR: 3085 nvmf_ns_reservation_clear_all_registrants(ns); 3086 if (num_hostid) { 3087 nvmf_subsystem_gen_ctrlr_notification(ns->subsystem, ns, 3088 hostid_list, 3089 num_hostid, 3090 SPDK_NVME_RESERVATION_PREEMPTED); 3091 } 3092 break; 3093 default: 3094 status = SPDK_NVME_SC_INVALID_FIELD; 3095 update_sgroup = false; 3096 goto exit; 3097 } 3098 3099 exit: 3100 if (update_sgroup && ns->ptpl_activated) { 3101 if (nvmf_ns_update_reservation_info(ns)) { 3102 status = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 3103 } 3104 } 3105 req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 3106 req->rsp->nvme_cpl.status.sc = status; 3107 return update_sgroup; 3108 } 3109 3110 static void 3111 nvmf_ns_reservation_report(struct spdk_nvmf_ns *ns, 3112 struct spdk_nvmf_ctrlr *ctrlr, 3113 struct spdk_nvmf_request *req) 3114 { 3115 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 3116 struct spdk_nvmf_registrant *reg, *tmp; 3117 struct spdk_nvme_reservation_status_extended_data status_data = { 0 }; 3118 struct spdk_iov_xfer ix; 3119 uint32_t transfer_len; 3120 uint32_t regctl = 0; 3121 uint8_t status = SPDK_NVME_SC_SUCCESS; 3122 3123 if (req->iovcnt == 0) { 3124 SPDK_ERRLOG("No data transfer specified for request. " 3125 " Unable to transfer back response.\n"); 3126 status = SPDK_NVME_SC_INVALID_FIELD; 3127 goto exit; 3128 } 3129 3130 if (!cmd->cdw11_bits.resv_report.eds) { 3131 SPDK_ERRLOG("NVMeoF uses extended controller data structure, " 3132 "please set EDS bit in cdw11 and try again\n"); 3133 status = SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT; 3134 goto exit; 3135 } 3136 3137 /* Number of Dwords of the Reservation Status data structure to transfer */ 3138 transfer_len = (cmd->cdw10 + 1) * sizeof(uint32_t); 3139 3140 if (transfer_len < sizeof(struct spdk_nvme_reservation_status_extended_data)) { 3141 status = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 3142 goto exit; 3143 } 3144 3145 spdk_iov_xfer_init(&ix, req->iov, req->iovcnt); 3146 3147 status_data.data.gen = ns->gen; 3148 status_data.data.rtype = ns->rtype; 3149 status_data.data.ptpls = ns->ptpl_activated; 3150 3151 TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) { 3152 regctl++; 3153 } 3154 3155 /* 3156 * We report the number of registrants as per the spec here, even if 3157 * the iov isn't big enough to contain them all. In that case, the 3158 * spdk_iov_xfer_from_buf() won't actually copy any of the remaining 3159 * data; as it keeps track of the iov cursor itself, it's simplest to 3160 * just walk the entire list anyway. 3161 */ 3162 status_data.data.regctl = regctl; 3163 3164 spdk_iov_xfer_from_buf(&ix, &status_data, sizeof(status_data)); 3165 3166 TAILQ_FOREACH_SAFE(reg, &ns->registrants, link, tmp) { 3167 struct spdk_nvme_registered_ctrlr_extended_data ctrlr_data = { 0 }; 3168 3169 /* Set to 0xffffh for dynamic controller */ 3170 ctrlr_data.cntlid = 0xffff; 3171 ctrlr_data.rcsts.status = (ns->holder == reg) ? true : false; 3172 ctrlr_data.rkey = reg->rkey; 3173 spdk_uuid_copy((struct spdk_uuid *)ctrlr_data.hostid, ®->hostid); 3174 3175 spdk_iov_xfer_from_buf(&ix, &ctrlr_data, sizeof(ctrlr_data)); 3176 } 3177 3178 exit: 3179 req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 3180 req->rsp->nvme_cpl.status.sc = status; 3181 return; 3182 } 3183 3184 static void 3185 nvmf_ns_reservation_complete(void *ctx) 3186 { 3187 struct spdk_nvmf_request *req = ctx; 3188 3189 spdk_nvmf_request_complete(req); 3190 } 3191 3192 static void 3193 _nvmf_ns_reservation_update_done(struct spdk_nvmf_subsystem *subsystem, 3194 void *cb_arg, int status) 3195 { 3196 struct spdk_nvmf_request *req = (struct spdk_nvmf_request *)cb_arg; 3197 struct spdk_nvmf_poll_group *group = req->qpair->group; 3198 3199 spdk_thread_send_msg(group->thread, nvmf_ns_reservation_complete, req); 3200 } 3201 3202 void 3203 nvmf_ns_reservation_request(void *ctx) 3204 { 3205 struct spdk_nvmf_request *req = (struct spdk_nvmf_request *)ctx; 3206 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 3207 struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr; 3208 struct subsystem_update_ns_ctx *update_ctx; 3209 uint32_t nsid; 3210 struct spdk_nvmf_ns *ns; 3211 bool update_sgroup = false; 3212 3213 nsid = cmd->nsid; 3214 ns = _nvmf_subsystem_get_ns(ctrlr->subsys, nsid); 3215 assert(ns != NULL); 3216 3217 switch (cmd->opc) { 3218 case SPDK_NVME_OPC_RESERVATION_REGISTER: 3219 update_sgroup = nvmf_ns_reservation_register(ns, ctrlr, req); 3220 break; 3221 case SPDK_NVME_OPC_RESERVATION_ACQUIRE: 3222 update_sgroup = nvmf_ns_reservation_acquire(ns, ctrlr, req); 3223 break; 3224 case SPDK_NVME_OPC_RESERVATION_RELEASE: 3225 update_sgroup = nvmf_ns_reservation_release(ns, ctrlr, req); 3226 break; 3227 case SPDK_NVME_OPC_RESERVATION_REPORT: 3228 nvmf_ns_reservation_report(ns, ctrlr, req); 3229 break; 3230 default: 3231 break; 3232 } 3233 3234 /* update reservation information to subsystem's poll group */ 3235 if (update_sgroup) { 3236 update_ctx = calloc(1, sizeof(*update_ctx)); 3237 if (update_ctx == NULL) { 3238 SPDK_ERRLOG("Can't alloc subsystem poll group update context\n"); 3239 goto update_done; 3240 } 3241 update_ctx->subsystem = ctrlr->subsys; 3242 update_ctx->cb_fn = _nvmf_ns_reservation_update_done; 3243 update_ctx->cb_arg = req; 3244 3245 nvmf_subsystem_update_ns(ctrlr->subsys, subsystem_update_ns_done, update_ctx); 3246 return; 3247 } 3248 3249 update_done: 3250 _nvmf_ns_reservation_update_done(ctrlr->subsys, (void *)req, 0); 3251 } 3252 3253 int 3254 spdk_nvmf_subsystem_set_ana_reporting(struct spdk_nvmf_subsystem *subsystem, 3255 bool ana_reporting) 3256 { 3257 if (subsystem->state != SPDK_NVMF_SUBSYSTEM_INACTIVE) { 3258 return -EAGAIN; 3259 } 3260 3261 subsystem->flags.ana_reporting = ana_reporting; 3262 3263 return 0; 3264 } 3265 3266 bool 3267 nvmf_subsystem_get_ana_reporting(struct spdk_nvmf_subsystem *subsystem) 3268 { 3269 return subsystem->flags.ana_reporting; 3270 } 3271 3272 struct subsystem_listener_update_ctx { 3273 struct spdk_nvmf_subsystem_listener *listener; 3274 3275 spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn; 3276 void *cb_arg; 3277 }; 3278 3279 static void 3280 subsystem_listener_update_done(struct spdk_io_channel_iter *i, int status) 3281 { 3282 struct subsystem_listener_update_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 3283 3284 if (ctx->cb_fn) { 3285 ctx->cb_fn(ctx->cb_arg, status); 3286 } 3287 free(ctx); 3288 } 3289 3290 static void 3291 subsystem_listener_update_on_pg(struct spdk_io_channel_iter *i) 3292 { 3293 struct subsystem_listener_update_ctx *ctx = spdk_io_channel_iter_get_ctx(i); 3294 struct spdk_nvmf_subsystem_listener *listener; 3295 struct spdk_nvmf_poll_group *group; 3296 struct spdk_nvmf_ctrlr *ctrlr; 3297 3298 listener = ctx->listener; 3299 group = spdk_io_channel_get_ctx(spdk_io_channel_iter_get_channel(i)); 3300 3301 TAILQ_FOREACH(ctrlr, &listener->subsystem->ctrlrs, link) { 3302 if (ctrlr->thread != spdk_get_thread()) { 3303 continue; 3304 } 3305 3306 if (ctrlr->admin_qpair && ctrlr->admin_qpair->group == group && ctrlr->listener == listener) { 3307 nvmf_ctrlr_async_event_ana_change_notice(ctrlr); 3308 } 3309 } 3310 3311 spdk_for_each_channel_continue(i, 0); 3312 } 3313 3314 void 3315 nvmf_subsystem_set_ana_state(struct spdk_nvmf_subsystem *subsystem, 3316 const struct spdk_nvme_transport_id *trid, 3317 enum spdk_nvme_ana_state ana_state, uint32_t anagrpid, 3318 spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, void *cb_arg) 3319 { 3320 struct spdk_nvmf_subsystem_listener *listener; 3321 struct subsystem_listener_update_ctx *ctx; 3322 uint32_t i; 3323 3324 assert(cb_fn != NULL); 3325 assert(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || 3326 subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED); 3327 3328 if (!subsystem->flags.ana_reporting) { 3329 SPDK_ERRLOG("ANA reporting is disabled\n"); 3330 cb_fn(cb_arg, -EINVAL); 3331 return; 3332 } 3333 3334 /* ANA Change state is not used, ANA Persistent Loss state 3335 * is not supported yet. 3336 */ 3337 if (!(ana_state == SPDK_NVME_ANA_OPTIMIZED_STATE || 3338 ana_state == SPDK_NVME_ANA_NON_OPTIMIZED_STATE || 3339 ana_state == SPDK_NVME_ANA_INACCESSIBLE_STATE)) { 3340 SPDK_ERRLOG("ANA state %d is not supported\n", ana_state); 3341 cb_fn(cb_arg, -ENOTSUP); 3342 return; 3343 } 3344 3345 if (anagrpid > subsystem->max_nsid) { 3346 SPDK_ERRLOG("ANA group ID %" PRIu32 " is more than maximum\n", anagrpid); 3347 cb_fn(cb_arg, -EINVAL); 3348 return; 3349 } 3350 3351 listener = nvmf_subsystem_find_listener(subsystem, trid); 3352 if (!listener) { 3353 SPDK_ERRLOG("Unable to find listener.\n"); 3354 cb_fn(cb_arg, -EINVAL); 3355 return; 3356 } 3357 3358 if (anagrpid != 0 && listener->ana_state[anagrpid - 1] == ana_state) { 3359 cb_fn(cb_arg, 0); 3360 return; 3361 } 3362 3363 ctx = calloc(1, sizeof(*ctx)); 3364 if (!ctx) { 3365 SPDK_ERRLOG("Unable to allocate context\n"); 3366 cb_fn(cb_arg, -ENOMEM); 3367 return; 3368 } 3369 3370 for (i = 1; i <= subsystem->max_nsid; i++) { 3371 if (anagrpid == 0 || i == anagrpid) { 3372 listener->ana_state[i - 1] = ana_state; 3373 } 3374 } 3375 listener->ana_state_change_count++; 3376 3377 ctx->listener = listener; 3378 ctx->cb_fn = cb_fn; 3379 ctx->cb_arg = cb_arg; 3380 3381 spdk_for_each_channel(subsystem->tgt, 3382 subsystem_listener_update_on_pg, 3383 ctx, 3384 subsystem_listener_update_done); 3385 } 3386