1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 #include "spdk/blob.h" 38 39 #include "lib/test_env.c" 40 #include "../bs_dev_common.c" 41 #include "blobstore.c" 42 #include "request.c" 43 44 struct spdk_blob_store *g_bs; 45 spdk_blob_id g_blobid; 46 struct spdk_blob *g_blob; 47 int g_bserrno; 48 struct spdk_xattr_names *g_names; 49 int g_done; 50 51 bool g_scheduler_delay = false; 52 53 struct scheduled_ops { 54 spdk_thread_fn fn; 55 void *ctx; 56 57 TAILQ_ENTRY(scheduled_ops) ops_queue; 58 }; 59 60 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 61 62 static void 63 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 64 { 65 if (g_scheduler_delay) { 66 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 67 68 ops->fn = fn; 69 ops->ctx = ctx; 70 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 71 } else { 72 fn(ctx); 73 } 74 } 75 76 static void 77 _bs_flush_scheduler(void) 78 { 79 struct scheduled_ops *ops, *tmp; 80 81 TAILQ_FOREACH_SAFE(ops, &g_scheduled_ops, ops_queue, tmp) { 82 ops->fn(ops->ctx); 83 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 84 free(ops); 85 } 86 } 87 88 static void 89 bs_op_complete(void *cb_arg, int bserrno) 90 { 91 g_bserrno = bserrno; 92 } 93 94 static void 95 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 96 int bserrno) 97 { 98 g_bs = bs; 99 g_bserrno = bserrno; 100 } 101 102 static void 103 blob_op_complete(void *cb_arg, int bserrno) 104 { 105 g_bserrno = bserrno; 106 } 107 108 static void 109 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 110 { 111 g_blobid = blobid; 112 g_bserrno = bserrno; 113 } 114 115 static void 116 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 117 { 118 g_blob = blb; 119 g_bserrno = bserrno; 120 } 121 122 static void 123 blob_init(void) 124 { 125 struct spdk_bs_dev *dev; 126 127 dev = init_dev(); 128 129 /* should fail for an unsupported blocklen */ 130 dev->blocklen = 500; 131 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 132 CU_ASSERT(g_bserrno == -EINVAL); 133 /* 134 * Normally dev gets deleted as part of the dev->destroy callback. But 135 * that doesn't get invoked when init() fails. So manually free it here 136 * instead. Probably blobstore should still destroy the dev when init 137 * fails, but we'll do that in a separate patch. 138 */ 139 free(dev); 140 141 dev = init_dev(); 142 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 143 CU_ASSERT(g_bserrno == 0); 144 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 145 146 spdk_bs_unload(g_bs, bs_op_complete, NULL); 147 CU_ASSERT(g_bserrno == 0); 148 g_bs = NULL; 149 } 150 151 static void 152 blob_super(void) 153 { 154 struct spdk_blob_store *bs; 155 struct spdk_bs_dev *dev; 156 spdk_blob_id blobid; 157 158 dev = init_dev(); 159 160 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 161 CU_ASSERT(g_bserrno == 0); 162 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 163 bs = g_bs; 164 165 /* Get the super blob without having set one */ 166 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 167 CU_ASSERT(g_bserrno == -ENOENT); 168 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 169 170 /* Create a blob */ 171 spdk_bs_md_create_blob(bs, 172 blob_op_with_id_complete, NULL); 173 CU_ASSERT(g_bserrno == 0); 174 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 175 blobid = g_blobid; 176 177 /* Set the blob as the super blob */ 178 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 179 CU_ASSERT(g_bserrno == 0); 180 181 /* Get the super blob */ 182 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 183 CU_ASSERT(g_bserrno == 0); 184 CU_ASSERT(blobid == g_blobid); 185 186 spdk_bs_unload(g_bs, bs_op_complete, NULL); 187 CU_ASSERT(g_bserrno == 0); 188 g_bs = NULL; 189 } 190 191 static void 192 blob_open(void) 193 { 194 struct spdk_blob_store *bs; 195 struct spdk_bs_dev *dev; 196 struct spdk_blob *blob; 197 spdk_blob_id blobid, blobid2; 198 199 dev = init_dev(); 200 201 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 202 CU_ASSERT(g_bserrno == 0); 203 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 204 bs = g_bs; 205 206 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 207 CU_ASSERT(g_bserrno == 0); 208 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 209 blobid = g_blobid; 210 211 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 212 CU_ASSERT(g_bserrno == 0); 213 CU_ASSERT(g_blob != NULL); 214 blob = g_blob; 215 216 blobid2 = spdk_blob_get_id(blob); 217 CU_ASSERT(blobid == blobid2); 218 219 /* Try to open file again. It should return success. */ 220 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 221 CU_ASSERT(g_bserrno == 0); 222 CU_ASSERT(blob == g_blob); 223 224 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 225 CU_ASSERT(g_bserrno == 0); 226 CU_ASSERT(blob == NULL); 227 228 /* 229 * Close the file a second time, releasing the second reference. This 230 * should succeed. 231 */ 232 blob = g_blob; 233 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 234 CU_ASSERT(g_bserrno == 0); 235 236 /* 237 * Try to open file again. It should succeed. This tests the case 238 * where the file is opened, closed, then re-opened again. 239 */ 240 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 241 CU_ASSERT(g_bserrno == 0); 242 CU_ASSERT(g_blob != NULL); 243 blob = g_blob; 244 245 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 246 CU_ASSERT(g_bserrno == 0); 247 248 spdk_bs_unload(g_bs, bs_op_complete, NULL); 249 CU_ASSERT(g_bserrno == 0); 250 g_bs = NULL; 251 } 252 253 static void 254 blob_delete(void) 255 { 256 struct spdk_blob_store *bs; 257 struct spdk_bs_dev *dev; 258 spdk_blob_id blobid; 259 260 dev = init_dev(); 261 262 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 263 CU_ASSERT(g_bserrno == 0); 264 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 265 bs = g_bs; 266 267 /* Create a blob and then delete it. */ 268 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 269 CU_ASSERT(g_bserrno == 0); 270 CU_ASSERT(g_blobid > 0); 271 blobid = g_blobid; 272 273 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 274 CU_ASSERT(g_bserrno == 0); 275 276 /* Try to open the blob */ 277 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 278 CU_ASSERT(g_bserrno == -ENOENT); 279 280 spdk_bs_unload(g_bs, bs_op_complete, NULL); 281 CU_ASSERT(g_bserrno == 0); 282 g_bs = NULL; 283 } 284 285 static void 286 blob_resize(void) 287 { 288 struct spdk_blob_store *bs; 289 struct spdk_bs_dev *dev; 290 struct spdk_blob *blob; 291 spdk_blob_id blobid; 292 uint64_t free_clusters; 293 int rc; 294 295 dev = init_dev(); 296 297 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 298 CU_ASSERT(g_bserrno == 0); 299 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 300 bs = g_bs; 301 free_clusters = spdk_bs_free_cluster_count(bs); 302 303 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 304 CU_ASSERT(g_bserrno == 0); 305 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 306 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 307 blobid = g_blobid; 308 309 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 310 CU_ASSERT(g_bserrno == 0); 311 CU_ASSERT(g_blob != NULL); 312 blob = g_blob; 313 314 /* The blob started at 0 clusters. Resize it to be 5. */ 315 rc = spdk_bs_md_resize_blob(blob, 5); 316 CU_ASSERT(rc == 0); 317 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 318 319 /* Shrink the blob to 3 clusters. This will not actually release 320 * the old clusters until the blob is synced. 321 */ 322 rc = spdk_bs_md_resize_blob(blob, 3); 323 CU_ASSERT(rc == 0); 324 /* Verify there are still 5 clusters in use */ 325 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 326 327 spdk_bs_md_sync_blob(blob, blob_op_complete, NULL); 328 CU_ASSERT(g_bserrno == 0); 329 /* Now there are only 3 clusters in use */ 330 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 331 332 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 333 rc = spdk_bs_md_resize_blob(blob, 10); 334 CU_ASSERT(rc == 0); 335 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 336 337 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 338 CU_ASSERT(g_bserrno == 0); 339 340 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 341 CU_ASSERT(g_bserrno == 0); 342 343 spdk_bs_unload(g_bs, bs_op_complete, NULL); 344 CU_ASSERT(g_bserrno == 0); 345 g_bs = NULL; 346 } 347 348 static void 349 channel_ops(void) 350 { 351 struct spdk_blob_store *bs; 352 struct spdk_bs_dev *dev; 353 struct spdk_io_channel *channel; 354 355 dev = init_dev(); 356 357 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 358 CU_ASSERT(g_bserrno == 0); 359 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 360 bs = g_bs; 361 362 channel = spdk_bs_alloc_io_channel(bs); 363 CU_ASSERT(channel != NULL); 364 365 spdk_bs_free_io_channel(channel); 366 367 spdk_bs_unload(g_bs, bs_op_complete, NULL); 368 CU_ASSERT(g_bserrno == 0); 369 g_bs = NULL; 370 } 371 372 static void 373 blob_write(void) 374 { 375 struct spdk_blob_store *bs; 376 struct spdk_bs_dev *dev; 377 struct spdk_blob *blob; 378 struct spdk_io_channel *channel; 379 spdk_blob_id blobid; 380 uint64_t pages_per_cluster; 381 uint8_t payload[10 * 4096]; 382 int rc; 383 384 dev = init_dev(); 385 386 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 387 CU_ASSERT(g_bserrno == 0); 388 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 389 bs = g_bs; 390 391 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 392 393 channel = spdk_bs_alloc_io_channel(bs); 394 CU_ASSERT(channel != NULL); 395 396 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 397 CU_ASSERT(g_bserrno == 0); 398 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 399 blobid = g_blobid; 400 401 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 402 CU_ASSERT(g_bserrno == 0); 403 CU_ASSERT(g_blob != NULL); 404 blob = g_blob; 405 406 /* Write to a blob with 0 size */ 407 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 408 CU_ASSERT(g_bserrno == -EINVAL); 409 410 /* Resize the blob */ 411 rc = spdk_bs_md_resize_blob(blob, 5); 412 CU_ASSERT(rc == 0); 413 414 /* Write to the blob */ 415 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 416 CU_ASSERT(g_bserrno == 0); 417 418 /* Write starting beyond the end */ 419 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 420 NULL); 421 CU_ASSERT(g_bserrno == -EINVAL); 422 423 /* Write starting at a valid location but going off the end */ 424 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 425 blob_op_complete, NULL); 426 CU_ASSERT(g_bserrno == -EINVAL); 427 428 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 429 CU_ASSERT(g_bserrno == 0); 430 431 spdk_bs_free_io_channel(channel); 432 433 spdk_bs_unload(g_bs, bs_op_complete, NULL); 434 CU_ASSERT(g_bserrno == 0); 435 g_bs = NULL; 436 } 437 438 static void 439 blob_read(void) 440 { 441 struct spdk_blob_store *bs; 442 struct spdk_bs_dev *dev; 443 struct spdk_blob *blob; 444 struct spdk_io_channel *channel; 445 spdk_blob_id blobid; 446 uint64_t pages_per_cluster; 447 uint8_t payload[10 * 4096]; 448 int rc; 449 450 dev = init_dev(); 451 452 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 453 CU_ASSERT(g_bserrno == 0); 454 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 455 bs = g_bs; 456 457 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 458 459 channel = spdk_bs_alloc_io_channel(bs); 460 CU_ASSERT(channel != NULL); 461 462 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 463 CU_ASSERT(g_bserrno == 0); 464 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 465 blobid = g_blobid; 466 467 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 468 CU_ASSERT(g_bserrno == 0); 469 CU_ASSERT(g_blob != NULL); 470 blob = g_blob; 471 472 /* Read from a blob with 0 size */ 473 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 474 CU_ASSERT(g_bserrno == -EINVAL); 475 476 /* Resize the blob */ 477 rc = spdk_bs_md_resize_blob(blob, 5); 478 CU_ASSERT(rc == 0); 479 480 /* Read from the blob */ 481 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 482 CU_ASSERT(g_bserrno == 0); 483 484 /* Read starting beyond the end */ 485 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 486 NULL); 487 CU_ASSERT(g_bserrno == -EINVAL); 488 489 /* Read starting at a valid location but going off the end */ 490 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 491 blob_op_complete, NULL); 492 CU_ASSERT(g_bserrno == -EINVAL); 493 494 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 495 CU_ASSERT(g_bserrno == 0); 496 497 spdk_bs_free_io_channel(channel); 498 499 spdk_bs_unload(g_bs, bs_op_complete, NULL); 500 CU_ASSERT(g_bserrno == 0); 501 g_bs = NULL; 502 } 503 504 static void 505 blob_rw_verify(void) 506 { 507 struct spdk_blob_store *bs; 508 struct spdk_bs_dev *dev; 509 struct spdk_blob *blob; 510 struct spdk_io_channel *channel; 511 spdk_blob_id blobid; 512 uint8_t payload_read[10 * 4096]; 513 uint8_t payload_write[10 * 4096]; 514 int rc; 515 516 dev = init_dev(); 517 518 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 519 CU_ASSERT(g_bserrno == 0); 520 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 521 bs = g_bs; 522 523 channel = spdk_bs_alloc_io_channel(bs); 524 CU_ASSERT(channel != NULL); 525 526 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 527 CU_ASSERT(g_bserrno == 0); 528 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 529 blobid = g_blobid; 530 531 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 532 CU_ASSERT(g_bserrno == 0); 533 CU_ASSERT(g_blob != NULL); 534 blob = g_blob; 535 536 rc = spdk_bs_md_resize_blob(blob, 32); 537 CU_ASSERT(rc == 0); 538 539 memset(payload_write, 0xE5, sizeof(payload_write)); 540 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 541 CU_ASSERT(g_bserrno == 0); 542 543 memset(payload_read, 0x00, sizeof(payload_read)); 544 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 545 CU_ASSERT(g_bserrno == 0); 546 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 547 548 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 549 CU_ASSERT(g_bserrno == 0); 550 551 spdk_bs_free_io_channel(channel); 552 553 spdk_bs_unload(g_bs, bs_op_complete, NULL); 554 CU_ASSERT(g_bserrno == 0); 555 g_bs = NULL; 556 } 557 558 static void 559 blob_rw_verify_iov(void) 560 { 561 struct spdk_blob_store *bs; 562 struct spdk_bs_dev *dev; 563 struct spdk_blob *blob; 564 struct spdk_io_channel *channel; 565 spdk_blob_id blobid; 566 uint8_t payload_read[10 * 4096]; 567 uint8_t payload_write[10 * 4096]; 568 struct iovec iov_read[3]; 569 struct iovec iov_write[3]; 570 void *buf; 571 int rc; 572 573 dev = init_dev(); 574 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 575 576 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 577 CU_ASSERT(g_bserrno == 0); 578 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 579 bs = g_bs; 580 581 channel = spdk_bs_alloc_io_channel(bs); 582 CU_ASSERT(channel != NULL); 583 584 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 585 CU_ASSERT(g_bserrno == 0); 586 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 587 blobid = g_blobid; 588 589 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 590 CU_ASSERT(g_bserrno == 0); 591 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 592 blob = g_blob; 593 594 rc = spdk_bs_md_resize_blob(blob, 2); 595 CU_ASSERT(rc == 0); 596 597 /* 598 * Manually adjust the offset of the blob's second cluster. This allows 599 * us to make sure that the readv/write code correctly accounts for I/O 600 * that cross cluster boundaries. Start by asserting that the allocated 601 * clusters are where we expect before modifying the second cluster. 602 */ 603 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 604 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 605 blob->active.clusters[1] = 3 * 256; 606 607 memset(payload_write, 0xE5, sizeof(payload_write)); 608 iov_write[0].iov_base = payload_write; 609 iov_write[0].iov_len = 1 * 4096; 610 iov_write[1].iov_base = payload_write + 1 * 4096; 611 iov_write[1].iov_len = 5 * 4096; 612 iov_write[2].iov_base = payload_write + 6 * 4096; 613 iov_write[2].iov_len = 4 * 4096; 614 /* 615 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 616 * will get written to the first cluster, the last 4 to the second cluster. 617 */ 618 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 619 CU_ASSERT(g_bserrno == 0); 620 621 memset(payload_read, 0xAA, sizeof(payload_read)); 622 iov_read[0].iov_base = payload_read; 623 iov_read[0].iov_len = 3 * 4096; 624 iov_read[1].iov_base = payload_read + 3 * 4096; 625 iov_read[1].iov_len = 4 * 4096; 626 iov_read[2].iov_base = payload_read + 7 * 4096; 627 iov_read[2].iov_len = 3 * 4096; 628 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 629 CU_ASSERT(g_bserrno == 0); 630 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 631 632 buf = calloc(1, 256 * 4096); 633 /* Check that cluster 2 on "disk" was not modified. */ 634 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 635 free(buf); 636 637 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 638 CU_ASSERT(g_bserrno == 0); 639 640 spdk_bs_free_io_channel(channel); 641 642 spdk_bs_unload(g_bs, bs_op_complete, NULL); 643 CU_ASSERT(g_bserrno == 0); 644 g_bs = NULL; 645 } 646 647 static uint32_t 648 bs_channel_get_req_count(struct spdk_io_channel *_channel) 649 { 650 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 651 struct spdk_bs_request_set *set; 652 uint32_t count = 0; 653 654 TAILQ_FOREACH(set, &channel->reqs, link) { 655 count++; 656 } 657 658 return count; 659 } 660 661 static void 662 blob_rw_verify_iov_nomem(void) 663 { 664 struct spdk_blob_store *bs; 665 struct spdk_bs_dev *dev; 666 struct spdk_blob *blob; 667 struct spdk_io_channel *channel; 668 spdk_blob_id blobid; 669 uint8_t payload_write[10 * 4096]; 670 struct iovec iov_write[3]; 671 uint32_t req_count; 672 int rc; 673 674 dev = init_dev(); 675 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 676 677 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 678 CU_ASSERT(g_bserrno == 0); 679 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 680 bs = g_bs; 681 682 channel = spdk_bs_alloc_io_channel(bs); 683 CU_ASSERT(channel != NULL); 684 685 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 686 CU_ASSERT(g_bserrno == 0); 687 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 688 blobid = g_blobid; 689 690 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 691 CU_ASSERT(g_bserrno == 0); 692 CU_ASSERT(g_blob != NULL); 693 blob = g_blob; 694 695 rc = spdk_bs_md_resize_blob(blob, 2); 696 CU_ASSERT(rc == 0); 697 698 /* 699 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 700 * will get written to the first cluster, the last 4 to the second cluster. 701 */ 702 iov_write[0].iov_base = payload_write; 703 iov_write[0].iov_len = 1 * 4096; 704 iov_write[1].iov_base = payload_write + 1 * 4096; 705 iov_write[1].iov_len = 5 * 4096; 706 iov_write[2].iov_base = payload_write + 6 * 4096; 707 iov_write[2].iov_len = 4 * 4096; 708 MOCK_SET(calloc, void *, NULL); 709 req_count = bs_channel_get_req_count(channel); 710 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 711 CU_ASSERT(g_bserrno = -ENOMEM); 712 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 713 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 714 715 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 716 CU_ASSERT(g_bserrno == 0); 717 718 spdk_bs_free_io_channel(channel); 719 720 spdk_bs_unload(g_bs, bs_op_complete, NULL); 721 CU_ASSERT(g_bserrno == 0); 722 g_bs = NULL; 723 } 724 725 static void 726 blob_iter(void) 727 { 728 struct spdk_blob_store *bs; 729 struct spdk_bs_dev *dev; 730 struct spdk_blob *blob; 731 spdk_blob_id blobid; 732 733 dev = init_dev(); 734 735 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 736 CU_ASSERT(g_bserrno == 0); 737 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 738 bs = g_bs; 739 740 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 741 CU_ASSERT(g_blob == NULL); 742 CU_ASSERT(g_bserrno == -ENOENT); 743 744 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 745 CU_ASSERT(g_bserrno == 0); 746 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 747 blobid = g_blobid; 748 749 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 750 CU_ASSERT(g_blob != NULL); 751 CU_ASSERT(g_bserrno == 0); 752 blob = g_blob; 753 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 754 755 spdk_bs_md_iter_next(bs, &blob, blob_op_with_handle_complete, NULL); 756 CU_ASSERT(g_blob == NULL); 757 CU_ASSERT(g_bserrno == -ENOENT); 758 759 spdk_bs_unload(g_bs, bs_op_complete, NULL); 760 CU_ASSERT(g_bserrno == 0); 761 g_bs = NULL; 762 } 763 764 static void 765 blob_xattr(void) 766 { 767 struct spdk_blob_store *bs; 768 struct spdk_bs_dev *dev; 769 struct spdk_blob *blob; 770 spdk_blob_id blobid; 771 uint64_t length; 772 int rc; 773 const char *name1, *name2; 774 const void *value; 775 size_t value_len; 776 struct spdk_xattr_names *names; 777 778 dev = init_dev(); 779 780 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 781 CU_ASSERT(g_bserrno == 0); 782 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 783 bs = g_bs; 784 785 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 786 CU_ASSERT(g_bserrno == 0); 787 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 788 blobid = g_blobid; 789 790 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 791 CU_ASSERT(g_bserrno == 0); 792 CU_ASSERT(g_blob != NULL); 793 blob = g_blob; 794 795 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 796 CU_ASSERT(rc == 0); 797 798 length = 2345; 799 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 800 CU_ASSERT(rc == 0); 801 802 /* Overwrite "length" xattr. */ 803 length = 3456; 804 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 805 CU_ASSERT(rc == 0); 806 807 value = NULL; 808 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 809 CU_ASSERT(rc == 0); 810 SPDK_CU_ASSERT_FATAL(value != NULL); 811 CU_ASSERT(*(uint64_t *)value == length); 812 CU_ASSERT(value_len == 8); 813 814 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 815 CU_ASSERT(rc == -ENOENT); 816 817 names = NULL; 818 rc = spdk_bs_md_get_xattr_names(blob, &names); 819 CU_ASSERT(rc == 0); 820 SPDK_CU_ASSERT_FATAL(names != NULL); 821 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 822 name1 = spdk_xattr_names_get_name(names, 0); 823 SPDK_CU_ASSERT_FATAL(name1 != NULL); 824 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 825 name2 = spdk_xattr_names_get_name(names, 1); 826 SPDK_CU_ASSERT_FATAL(name2 != NULL); 827 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 828 CU_ASSERT(strcmp(name1, name2)); 829 spdk_xattr_names_free(names); 830 831 rc = spdk_blob_md_remove_xattr(blob, "name"); 832 CU_ASSERT(rc == 0); 833 834 rc = spdk_blob_md_remove_xattr(blob, "foobar"); 835 CU_ASSERT(rc == -ENOENT); 836 837 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 838 839 spdk_bs_unload(g_bs, bs_op_complete, NULL); 840 CU_ASSERT(g_bserrno == 0); 841 g_bs = NULL; 842 } 843 844 static void 845 bs_load(void) 846 { 847 struct spdk_bs_dev *dev; 848 spdk_blob_id blobid; 849 struct spdk_blob *blob; 850 uint64_t length; 851 int rc; 852 const void *value; 853 size_t value_len; 854 855 dev = init_dev(); 856 857 /* Initialize a new blob store */ 858 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 859 CU_ASSERT(g_bserrno == 0); 860 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 861 862 /* Create a blob */ 863 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 864 CU_ASSERT(g_bserrno == 0); 865 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 866 blobid = g_blobid; 867 868 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 869 CU_ASSERT(g_bserrno == 0); 870 CU_ASSERT(g_blob != NULL); 871 blob = g_blob; 872 873 /* Set some xattrs */ 874 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 875 CU_ASSERT(rc == 0); 876 877 length = 2345; 878 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 879 CU_ASSERT(rc == 0); 880 881 /* Resize the blob */ 882 rc = spdk_bs_md_resize_blob(blob, 10); 883 CU_ASSERT(rc == 0); 884 885 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 886 CU_ASSERT(g_bserrno == 0); 887 blob = NULL; 888 g_blob = NULL; 889 g_blobid = SPDK_BLOBID_INVALID; 890 891 /* Unload the blob store */ 892 spdk_bs_unload(g_bs, bs_op_complete, NULL); 893 CU_ASSERT(g_bserrno == 0); 894 g_bs = NULL; 895 g_blob = NULL; 896 g_blobid = 0; 897 898 dev = init_dev(); 899 /* Load an existing blob store */ 900 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 901 CU_ASSERT(g_bserrno == 0); 902 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 903 904 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 905 CU_ASSERT(g_bserrno == 0); 906 CU_ASSERT(g_blob != NULL); 907 blob = g_blob; 908 909 /* Get the xattrs */ 910 value = NULL; 911 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 912 CU_ASSERT(rc == 0); 913 SPDK_CU_ASSERT_FATAL(value != NULL); 914 CU_ASSERT(*(uint64_t *)value == length); 915 CU_ASSERT(value_len == 8); 916 917 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 918 CU_ASSERT(rc == -ENOENT); 919 920 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 921 922 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 923 CU_ASSERT(g_bserrno == 0); 924 blob = NULL; 925 g_blob = NULL; 926 g_blobid = SPDK_BLOBID_INVALID; 927 928 spdk_bs_unload(g_bs, bs_op_complete, NULL); 929 CU_ASSERT(g_bserrno == 0); 930 g_bs = NULL; 931 } 932 933 /* 934 * Create a blobstore and then unload it, while delaying all scheduled operations 935 * until after spdk_bs_unload call has finished. This ensures the memory associated 936 * with the internal blobstore channels is not touched after it is freed. 937 */ 938 static void 939 bs_unload_delayed(void) 940 { 941 struct spdk_bs_dev *dev; 942 943 dev = init_dev(); 944 945 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 946 CU_ASSERT(g_bserrno == 0); 947 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 948 949 g_scheduler_delay = true; 950 951 g_bserrno = -1; 952 spdk_bs_unload(g_bs, bs_op_complete, NULL); 953 CU_ASSERT(g_bserrno == 0); 954 g_bs = NULL; 955 956 _bs_flush_scheduler(); 957 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 958 959 g_scheduler_delay = false; 960 } 961 962 /* 963 * Create a blobstore with a cluster size different than the default, and ensure it is 964 * persisted. 965 */ 966 static void 967 bs_cluster_sz(void) 968 { 969 struct spdk_bs_dev *dev; 970 struct spdk_bs_opts opts; 971 uint32_t cluster_sz; 972 973 dev = init_dev(); 974 spdk_bs_opts_init(&opts); 975 opts.cluster_sz *= 2; 976 cluster_sz = opts.cluster_sz; 977 978 /* Initialize a new blob store */ 979 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 980 CU_ASSERT(g_bserrno == 0); 981 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 982 983 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 984 985 /* Unload the blob store */ 986 spdk_bs_unload(g_bs, bs_op_complete, NULL); 987 CU_ASSERT(g_bserrno == 0); 988 g_bs = NULL; 989 g_blob = NULL; 990 g_blobid = 0; 991 992 dev = init_dev(); 993 /* Load an existing blob store */ 994 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 995 CU_ASSERT(g_bserrno == 0); 996 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 997 998 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 999 1000 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1001 CU_ASSERT(g_bserrno == 0); 1002 g_bs = NULL; 1003 } 1004 1005 /* 1006 * Test resizing of the metadata blob. This requires creating enough blobs 1007 * so that one cluster is not enough to fit the metadata for those blobs. 1008 * To induce this condition to happen more quickly, we reduce the cluster 1009 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1010 */ 1011 static void 1012 bs_resize_md(void) 1013 { 1014 const int CLUSTER_PAGE_COUNT = 4; 1015 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1016 struct spdk_bs_dev *dev; 1017 struct spdk_bs_opts opts; 1018 uint32_t cluster_sz; 1019 spdk_blob_id blobids[NUM_BLOBS]; 1020 int i; 1021 1022 1023 dev = init_dev(); 1024 spdk_bs_opts_init(&opts); 1025 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1026 cluster_sz = opts.cluster_sz; 1027 1028 /* Initialize a new blob store */ 1029 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1030 CU_ASSERT(g_bserrno == 0); 1031 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1032 1033 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1034 1035 for (i = 0; i < NUM_BLOBS; i++) { 1036 g_bserrno = -1; 1037 g_blobid = SPDK_BLOBID_INVALID; 1038 spdk_bs_md_create_blob(g_bs, 1039 blob_op_with_id_complete, NULL); 1040 CU_ASSERT(g_bserrno == 0); 1041 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1042 blobids[i] = g_blobid; 1043 } 1044 1045 /* Unload the blob store */ 1046 g_bserrno = -1; 1047 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1048 CU_ASSERT(g_bserrno == 0); 1049 1050 /* Load an existing blob store */ 1051 g_bserrno = -1; 1052 g_bs = NULL; 1053 dev = init_dev(); 1054 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 1055 CU_ASSERT(g_bserrno == 0); 1056 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1057 1058 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1059 1060 for (i = 0; i < NUM_BLOBS; i++) { 1061 g_bserrno = -1; 1062 g_blob = NULL; 1063 spdk_bs_md_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1064 CU_ASSERT(g_bserrno == 0); 1065 CU_ASSERT(g_blob != NULL); 1066 g_bserrno = -1; 1067 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1068 CU_ASSERT(g_bserrno == 0); 1069 } 1070 1071 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1072 CU_ASSERT(g_bserrno == 0); 1073 g_bs = NULL; 1074 } 1075 1076 /* Try to hit all of the corner cases associated with serializing 1077 * a blob to disk 1078 */ 1079 static void 1080 blob_serialize(void) 1081 { 1082 struct spdk_bs_dev *dev; 1083 struct spdk_bs_opts opts; 1084 struct spdk_blob_store *bs; 1085 spdk_blob_id blobid[2]; 1086 struct spdk_blob *blob[2]; 1087 uint64_t i; 1088 char *value; 1089 int rc; 1090 1091 dev = init_dev(); 1092 1093 /* Initialize a new blobstore with very small clusters */ 1094 spdk_bs_opts_init(&opts); 1095 opts.cluster_sz = dev->blocklen * 8; 1096 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1097 CU_ASSERT(g_bserrno == 0); 1098 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1099 bs = g_bs; 1100 1101 /* Create and open two blobs */ 1102 for (i = 0; i < 2; i++) { 1103 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1104 CU_ASSERT(g_bserrno == 0); 1105 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1106 blobid[i] = g_blobid; 1107 1108 /* Open a blob */ 1109 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1110 CU_ASSERT(g_bserrno == 0); 1111 CU_ASSERT(g_blob != NULL); 1112 blob[i] = g_blob; 1113 1114 /* Set a fairly large xattr on both blobs to eat up 1115 * metadata space 1116 */ 1117 value = calloc(dev->blocklen - 64, sizeof(char)); 1118 SPDK_CU_ASSERT_FATAL(value != NULL); 1119 memset(value, i, dev->blocklen / 2); 1120 rc = spdk_blob_md_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1121 CU_ASSERT(rc == 0); 1122 free(value); 1123 } 1124 1125 /* Resize the blobs, alternating 1 cluster at a time. 1126 * This thwarts run length encoding and will cause spill 1127 * over of the extents. 1128 */ 1129 for (i = 0; i < 6; i++) { 1130 rc = spdk_bs_md_resize_blob(blob[i % 2], (i / 2) + 1); 1131 CU_ASSERT(rc == 0); 1132 } 1133 1134 for (i = 0; i < 2; i++) { 1135 spdk_bs_md_sync_blob(blob[i], blob_op_complete, NULL); 1136 CU_ASSERT(g_bserrno == 0); 1137 } 1138 1139 /* Close the blobs */ 1140 for (i = 0; i < 2; i++) { 1141 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1142 CU_ASSERT(g_bserrno == 0); 1143 } 1144 1145 /* Unload the blobstore */ 1146 spdk_bs_unload(bs, bs_op_complete, NULL); 1147 CU_ASSERT(g_bserrno == 0); 1148 g_bs = NULL; 1149 g_blob = NULL; 1150 g_blobid = 0; 1151 bs = NULL; 1152 1153 dev = init_dev(); 1154 /* Load an existing blob store */ 1155 spdk_bs_load(dev, bs_op_with_handle_complete, NULL); 1156 CU_ASSERT(g_bserrno == 0); 1157 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1158 bs = g_bs; 1159 1160 for (i = 0; i < 2; i++) { 1161 blob[i] = NULL; 1162 1163 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1164 CU_ASSERT(g_bserrno == 0); 1165 CU_ASSERT(g_blob != NULL); 1166 blob[i] = g_blob; 1167 1168 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1169 1170 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1171 CU_ASSERT(g_bserrno == 0); 1172 } 1173 1174 spdk_bs_unload(bs, bs_op_complete, NULL); 1175 CU_ASSERT(g_bserrno == 0); 1176 g_bs = NULL; 1177 } 1178 1179 int main(int argc, char **argv) 1180 { 1181 CU_pSuite suite = NULL; 1182 unsigned int num_failures; 1183 1184 if (CU_initialize_registry() != CUE_SUCCESS) { 1185 return CU_get_error(); 1186 } 1187 1188 suite = CU_add_suite("blob", NULL, NULL); 1189 if (suite == NULL) { 1190 CU_cleanup_registry(); 1191 return CU_get_error(); 1192 } 1193 1194 if ( 1195 CU_add_test(suite, "blob_init", blob_init) == NULL || 1196 CU_add_test(suite, "blob_open", blob_open) == NULL || 1197 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 1198 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 1199 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 1200 CU_add_test(suite, "blob_super", blob_super) == NULL || 1201 CU_add_test(suite, "blob_write", blob_write) == NULL || 1202 CU_add_test(suite, "blob_read", blob_read) == NULL || 1203 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 1204 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 1205 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 1206 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 1207 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 1208 CU_add_test(suite, "bs_load", bs_load) == NULL || 1209 CU_add_test(suite, "bs_unload_delayed", bs_unload_delayed) == NULL || 1210 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 1211 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 1212 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL 1213 ) { 1214 CU_cleanup_registry(); 1215 return CU_get_error(); 1216 } 1217 1218 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 1219 spdk_allocate_thread(_bs_send_msg, NULL); 1220 CU_basic_set_mode(CU_BRM_VERBOSE); 1221 CU_basic_run_tests(); 1222 num_failures = CU_get_number_of_failures(); 1223 CU_cleanup_registry(); 1224 spdk_free_thread(); 1225 free(g_dev_buffer); 1226 return num_failures; 1227 } 1228