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