1 /*- 2 * Copyright (c) 2004 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 /* 30 * Regression test to do some very basic AIO exercising on several types of 31 * file descriptors. Currently, the tests consist of initializing a fixed 32 * size buffer with pseudo-random data, writing it to one fd using AIO, then 33 * reading it from a second descriptor using AIO. For some targets, the same 34 * fd is used for write and read (i.e., file, md device), but for others the 35 * operation is performed on a peer (pty, socket, fifo, etc). A timeout is 36 * initiated to detect undue blocking. This test does not attempt to exercise 37 * error cases or more subtle asynchronous behavior, just make sure that the 38 * basic operations work on some basic object types. 39 */ 40 41 #include <sys/param.h> 42 #include <sys/module.h> 43 #include <sys/resource.h> 44 #include <sys/socket.h> 45 #include <sys/stat.h> 46 #include <sys/mdioctl.h> 47 48 #include <aio.h> 49 #include <err.h> 50 #include <errno.h> 51 #include <fcntl.h> 52 #include <libutil.h> 53 #include <limits.h> 54 #include <stdint.h> 55 #include <stdio.h> 56 #include <stdlib.h> 57 #include <string.h> 58 #include <termios.h> 59 #include <unistd.h> 60 61 #include <atf-c.h> 62 63 #include "freebsd_test_suite/macros.h" 64 #include "local.h" 65 66 /* 67 * GLOBAL_MAX sets the largest usable buffer size to be read and written, as 68 * it sizes ac_buffer in the aio_context structure. It is also the default 69 * size for file I/O. For other types, we use smaller blocks or we risk 70 * blocking (and we run in a single process/thread so that would be bad). 71 */ 72 #define GLOBAL_MAX 16384 73 74 #define BUFFER_MAX GLOBAL_MAX 75 76 /* 77 * A completion function will block until the aio has completed, then return 78 * the result of the aio. errno will be set appropriately. 79 */ 80 typedef ssize_t (*completion)(struct aiocb*); 81 82 struct aio_context { 83 int ac_read_fd, ac_write_fd; 84 long ac_seed; 85 char ac_buffer[GLOBAL_MAX]; 86 int ac_buflen; 87 int ac_seconds; 88 void (*ac_cleanup)(void *arg); 89 void *ac_cleanup_arg; 90 }; 91 92 static int aio_timedout; 93 94 /* 95 * Each test run specifies a timeout in seconds. Use the somewhat obsoleted 96 * signal(3) and alarm(3) APIs to set this up. 97 */ 98 static void 99 aio_timeout_signal(int sig __unused) 100 { 101 102 aio_timedout = 1; 103 } 104 105 static void 106 aio_timeout_start(int seconds) 107 { 108 109 aio_timedout = 0; 110 ATF_REQUIRE_MSG(signal(SIGALRM, aio_timeout_signal) != SIG_ERR, 111 "failed to set SIGALRM handler: %s", strerror(errno)); 112 alarm(seconds); 113 } 114 115 static void 116 aio_timeout_stop(void) 117 { 118 119 ATF_REQUIRE_MSG(signal(SIGALRM, NULL) != SIG_ERR, 120 "failed to reset SIGALRM handler to default: %s", strerror(errno)); 121 alarm(0); 122 } 123 124 /* 125 * Fill a buffer given a seed that can be fed into srandom() to initialize 126 * the PRNG in a repeatable manner. 127 */ 128 static void 129 aio_fill_buffer(char *buffer, int len, long seed) 130 { 131 char ch; 132 int i; 133 134 srandom(seed); 135 for (i = 0; i < len; i++) { 136 ch = random() & 0xff; 137 buffer[i] = ch; 138 } 139 } 140 141 /* 142 * Test that a buffer matches a given seed. See aio_fill_buffer(). Return 143 * (1) on a match, (0) on a mismatch. 144 */ 145 static int 146 aio_test_buffer(char *buffer, int len, long seed) 147 { 148 char ch; 149 int i; 150 151 srandom(seed); 152 for (i = 0; i < len; i++) { 153 ch = random() & 0xff; 154 if (buffer[i] != ch) 155 return (0); 156 } 157 return (1); 158 } 159 160 /* 161 * Initialize a testing context given the file descriptors provided by the 162 * test setup. 163 */ 164 static void 165 aio_context_init(struct aio_context *ac, int read_fd, 166 int write_fd, int buflen, int seconds, void (*cleanup)(void *), 167 void *cleanup_arg) 168 { 169 170 ATF_REQUIRE_MSG(buflen <= BUFFER_MAX, 171 "aio_context_init: buffer too large (%d > %d)", 172 buflen, BUFFER_MAX); 173 bzero(ac, sizeof(*ac)); 174 ac->ac_read_fd = read_fd; 175 ac->ac_write_fd = write_fd; 176 ac->ac_buflen = buflen; 177 srandomdev(); 178 ac->ac_seed = random(); 179 aio_fill_buffer(ac->ac_buffer, buflen, ac->ac_seed); 180 ATF_REQUIRE_MSG(aio_test_buffer(ac->ac_buffer, buflen, 181 ac->ac_seed) != 0, "aio_test_buffer: internal error"); 182 ac->ac_seconds = seconds; 183 ac->ac_cleanup = cleanup; 184 ac->ac_cleanup_arg = cleanup_arg; 185 } 186 187 static ssize_t 188 poll(struct aiocb *aio) 189 { 190 int error; 191 192 while ((error = aio_error(aio)) == EINPROGRESS && !aio_timedout) 193 usleep(25000); 194 switch (error) { 195 case EINPROGRESS: 196 errno = EINTR; 197 return (-1); 198 case 0: 199 return (aio_return(aio)); 200 default: 201 return (error); 202 } 203 } 204 205 static ssize_t 206 suspend(struct aiocb *aio) 207 { 208 const struct aiocb *const iocbs[] = {aio}; 209 int error; 210 211 error = aio_suspend(iocbs, 1, NULL); 212 if (error == 0) 213 return (aio_return(aio)); 214 else 215 return (error); 216 } 217 218 static ssize_t 219 waitcomplete(struct aiocb *aio) 220 { 221 struct aiocb *aiop; 222 ssize_t ret; 223 224 ret = aio_waitcomplete(&aiop, NULL); 225 ATF_REQUIRE_EQ(aio, aiop); 226 return (ret); 227 } 228 229 /* 230 * Each tester can register a callback to clean up in the event the test 231 * fails. Preserve the value of errno so that subsequent calls to errx() 232 * work properly. 233 */ 234 static void 235 aio_cleanup(struct aio_context *ac) 236 { 237 int error; 238 239 if (ac->ac_cleanup == NULL) 240 return; 241 error = errno; 242 (ac->ac_cleanup)(ac->ac_cleanup_arg); 243 errno = error; 244 } 245 246 /* 247 * Perform a simple write test of our initialized data buffer to the provided 248 * file descriptor. 249 */ 250 static void 251 aio_write_test(struct aio_context *ac, completion comp) 252 { 253 struct aiocb aio; 254 ssize_t len; 255 256 bzero(&aio, sizeof(aio)); 257 aio.aio_buf = ac->ac_buffer; 258 aio.aio_nbytes = ac->ac_buflen; 259 aio.aio_fildes = ac->ac_write_fd; 260 aio.aio_offset = 0; 261 262 aio_timeout_start(ac->ac_seconds); 263 264 if (aio_write(&aio) < 0) { 265 if (errno == EINTR) { 266 if (aio_timedout) { 267 aio_cleanup(ac); 268 atf_tc_fail("aio_write timed out"); 269 } 270 } 271 aio_cleanup(ac); 272 atf_tc_fail("aio_write failed: %s", strerror(errno)); 273 } 274 275 len = comp(&aio); 276 if (len < 0) { 277 if (errno == EINTR) { 278 if (aio_timedout) { 279 aio_cleanup(ac); 280 atf_tc_fail("aio timed out"); 281 } 282 } 283 aio_cleanup(ac); 284 atf_tc_fail("aio failed: %s", strerror(errno)); 285 } 286 287 aio_timeout_stop(); 288 289 if (len != ac->ac_buflen) { 290 aio_cleanup(ac); 291 atf_tc_fail("aio short write (%jd)", (intmax_t)len); 292 } 293 } 294 295 /* 296 * Perform a simple read test of our initialized data buffer from the 297 * provided file descriptor. 298 */ 299 static void 300 aio_read_test(struct aio_context *ac, completion comp) 301 { 302 struct aiocb aio; 303 ssize_t len; 304 305 bzero(ac->ac_buffer, ac->ac_buflen); 306 bzero(&aio, sizeof(aio)); 307 aio.aio_buf = ac->ac_buffer; 308 aio.aio_nbytes = ac->ac_buflen; 309 aio.aio_fildes = ac->ac_read_fd; 310 aio.aio_offset = 0; 311 312 aio_timeout_start(ac->ac_seconds); 313 314 if (aio_read(&aio) < 0) { 315 if (errno == EINTR) { 316 if (aio_timedout) { 317 aio_cleanup(ac); 318 atf_tc_fail("aio_read timed out"); 319 } 320 } 321 aio_cleanup(ac); 322 atf_tc_fail("aio_read failed: %s", strerror(errno)); 323 } 324 325 len = comp(&aio); 326 if (len < 0) { 327 if (errno == EINTR) { 328 if (aio_timedout) { 329 aio_cleanup(ac); 330 atf_tc_fail("aio timed out"); 331 } 332 } 333 aio_cleanup(ac); 334 atf_tc_fail("aio failed: %s", strerror(errno)); 335 } 336 337 aio_timeout_stop(); 338 339 if (len != ac->ac_buflen) { 340 aio_cleanup(ac); 341 atf_tc_fail("aio short read (%jd)", 342 (intmax_t)len); 343 } 344 345 if (aio_test_buffer(ac->ac_buffer, ac->ac_buflen, ac->ac_seed) == 0) { 346 aio_cleanup(ac); 347 atf_tc_fail("buffer mismatched"); 348 } 349 } 350 351 /* 352 * Series of type-specific tests for AIO. For now, we just make sure we can 353 * issue a write and then a read to each type. We assume that once a write 354 * is issued, a read can follow. 355 */ 356 357 /* 358 * Test with a classic file. Assumes we can create a moderate size temporary 359 * file. 360 */ 361 #define FILE_LEN GLOBAL_MAX 362 #define FILE_PATHNAME "testfile" 363 #define FILE_TIMEOUT 30 364 struct aio_file_arg { 365 int afa_fd; 366 }; 367 368 static void 369 aio_file_cleanup(void *arg) 370 { 371 struct aio_file_arg *afa; 372 373 afa = arg; 374 close(afa->afa_fd); 375 unlink(FILE_PATHNAME); 376 } 377 378 static void 379 aio_file_test(completion comp) 380 { 381 struct aio_file_arg arg; 382 struct aio_context ac; 383 int fd; 384 385 ATF_REQUIRE_KERNEL_MODULE("aio"); 386 ATF_REQUIRE_UNSAFE_AIO(); 387 388 fd = open(FILE_PATHNAME, O_RDWR | O_CREAT); 389 ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 390 391 arg.afa_fd = fd; 392 393 aio_context_init(&ac, fd, fd, FILE_LEN, 394 FILE_TIMEOUT, aio_file_cleanup, &arg); 395 aio_write_test(&ac, comp); 396 aio_read_test(&ac, comp); 397 398 aio_file_cleanup(&arg); 399 } 400 401 ATF_TC_WITHOUT_HEAD(file_poll); 402 ATF_TC_BODY(file_poll, tc) 403 { 404 aio_file_test(poll); 405 } 406 407 ATF_TC_WITHOUT_HEAD(file_suspend); 408 ATF_TC_BODY(file_suspend, tc) 409 { 410 aio_file_test(suspend); 411 } 412 413 ATF_TC_WITHOUT_HEAD(file_waitcomplete); 414 ATF_TC_BODY(file_waitcomplete, tc) 415 { 416 aio_file_test(waitcomplete); 417 } 418 419 #define FIFO_LEN 256 420 #define FIFO_PATHNAME "testfifo" 421 #define FIFO_TIMEOUT 30 422 struct aio_fifo_arg { 423 int afa_read_fd; 424 int afa_write_fd; 425 }; 426 427 static void 428 aio_fifo_cleanup(void *arg) 429 { 430 struct aio_fifo_arg *afa; 431 432 afa = arg; 433 if (afa->afa_read_fd != -1) 434 close(afa->afa_read_fd); 435 if (afa->afa_write_fd != -1) 436 close(afa->afa_write_fd); 437 unlink(FIFO_PATHNAME); 438 } 439 440 static void 441 aio_fifo_test(completion comp) 442 { 443 int error, read_fd = -1, write_fd = -1; 444 struct aio_fifo_arg arg; 445 struct aio_context ac; 446 447 ATF_REQUIRE_KERNEL_MODULE("aio"); 448 ATF_REQUIRE_UNSAFE_AIO(); 449 450 ATF_REQUIRE_MSG(mkfifo(FIFO_PATHNAME, 0600) != -1, 451 "mkfifo failed: %s", strerror(errno)); 452 arg.afa_read_fd = -1; 453 arg.afa_write_fd = -1; 454 455 read_fd = open(FIFO_PATHNAME, O_RDONLY | O_NONBLOCK); 456 if (read_fd == -1) { 457 error = errno; 458 aio_fifo_cleanup(&arg); 459 errno = error; 460 atf_tc_fail("read_fd open failed: %s", 461 strerror(errno)); 462 } 463 arg.afa_read_fd = read_fd; 464 465 write_fd = open(FIFO_PATHNAME, O_WRONLY); 466 if (write_fd == -1) { 467 error = errno; 468 aio_fifo_cleanup(&arg); 469 errno = error; 470 atf_tc_fail("write_fd open failed: %s", 471 strerror(errno)); 472 } 473 arg.afa_write_fd = write_fd; 474 475 aio_context_init(&ac, read_fd, write_fd, FIFO_LEN, 476 FIFO_TIMEOUT, aio_fifo_cleanup, &arg); 477 aio_write_test(&ac, comp); 478 aio_read_test(&ac, comp); 479 480 aio_fifo_cleanup(&arg); 481 } 482 483 ATF_TC_WITHOUT_HEAD(fifo_poll); 484 ATF_TC_BODY(fifo_poll, tc) 485 { 486 aio_fifo_test(poll); 487 } 488 489 ATF_TC_WITHOUT_HEAD(fifo_suspend); 490 ATF_TC_BODY(fifo_suspend, tc) 491 { 492 aio_fifo_test(waitcomplete); 493 } 494 495 ATF_TC_WITHOUT_HEAD(fifo_waitcomplete); 496 ATF_TC_BODY(fifo_waitcomplete, tc) 497 { 498 aio_fifo_test(waitcomplete); 499 } 500 501 struct aio_unix_socketpair_arg { 502 int asa_sockets[2]; 503 }; 504 505 static void 506 aio_unix_socketpair_cleanup(void *arg) 507 { 508 struct aio_unix_socketpair_arg *asa; 509 510 asa = arg; 511 close(asa->asa_sockets[0]); 512 close(asa->asa_sockets[1]); 513 } 514 515 #define UNIX_SOCKETPAIR_LEN 256 516 #define UNIX_SOCKETPAIR_TIMEOUT 30 517 static void 518 aio_unix_socketpair_test(completion comp) 519 { 520 struct aio_unix_socketpair_arg arg; 521 struct aio_context ac; 522 struct rusage ru_before, ru_after; 523 int sockets[2]; 524 525 ATF_REQUIRE_KERNEL_MODULE("aio"); 526 527 ATF_REQUIRE_MSG(socketpair(PF_UNIX, SOCK_STREAM, 0, sockets) != -1, 528 "socketpair failed: %s", strerror(errno)); 529 530 arg.asa_sockets[0] = sockets[0]; 531 arg.asa_sockets[1] = sockets[1]; 532 aio_context_init(&ac, sockets[0], 533 sockets[1], UNIX_SOCKETPAIR_LEN, UNIX_SOCKETPAIR_TIMEOUT, 534 aio_unix_socketpair_cleanup, &arg); 535 ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_before) != -1, 536 "getrusage failed: %s", strerror(errno)); 537 aio_write_test(&ac, comp); 538 ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1, 539 "getrusage failed: %s", strerror(errno)); 540 ATF_REQUIRE(ru_after.ru_msgsnd == ru_before.ru_msgsnd + 1); 541 ru_before = ru_after; 542 aio_read_test(&ac, comp); 543 ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1, 544 "getrusage failed: %s", strerror(errno)); 545 ATF_REQUIRE(ru_after.ru_msgrcv == ru_before.ru_msgrcv + 1); 546 547 aio_unix_socketpair_cleanup(&arg); 548 } 549 550 ATF_TC_WITHOUT_HEAD(socket_poll); 551 ATF_TC_BODY(socket_poll, tc) 552 { 553 aio_unix_socketpair_test(poll); 554 } 555 556 ATF_TC_WITHOUT_HEAD(socket_suspend); 557 ATF_TC_BODY(socket_suspend, tc) 558 { 559 aio_unix_socketpair_test(suspend); 560 } 561 562 ATF_TC_WITHOUT_HEAD(socket_waitcomplete); 563 ATF_TC_BODY(socket_waitcomplete, tc) 564 { 565 aio_unix_socketpair_test(waitcomplete); 566 } 567 568 struct aio_pty_arg { 569 int apa_read_fd; 570 int apa_write_fd; 571 }; 572 573 static void 574 aio_pty_cleanup(void *arg) 575 { 576 struct aio_pty_arg *apa; 577 578 apa = arg; 579 close(apa->apa_read_fd); 580 close(apa->apa_write_fd); 581 }; 582 583 #define PTY_LEN 256 584 #define PTY_TIMEOUT 30 585 static void 586 aio_pty_test(completion comp) 587 { 588 struct aio_pty_arg arg; 589 struct aio_context ac; 590 int read_fd, write_fd; 591 struct termios ts; 592 int error; 593 594 ATF_REQUIRE_KERNEL_MODULE("aio"); 595 ATF_REQUIRE_UNSAFE_AIO(); 596 597 ATF_REQUIRE_MSG(openpty(&read_fd, &write_fd, NULL, NULL, NULL) == 0, 598 "openpty failed: %s", strerror(errno)); 599 600 arg.apa_read_fd = read_fd; 601 arg.apa_write_fd = write_fd; 602 603 if (tcgetattr(write_fd, &ts) < 0) { 604 error = errno; 605 aio_pty_cleanup(&arg); 606 errno = error; 607 atf_tc_fail("tcgetattr failed: %s", strerror(errno)); 608 } 609 cfmakeraw(&ts); 610 if (tcsetattr(write_fd, TCSANOW, &ts) < 0) { 611 error = errno; 612 aio_pty_cleanup(&arg); 613 errno = error; 614 atf_tc_fail("tcsetattr failed: %s", strerror(errno)); 615 } 616 aio_context_init(&ac, read_fd, write_fd, PTY_LEN, 617 PTY_TIMEOUT, aio_pty_cleanup, &arg); 618 619 aio_write_test(&ac, comp); 620 aio_read_test(&ac, comp); 621 622 aio_pty_cleanup(&arg); 623 } 624 625 ATF_TC_WITHOUT_HEAD(pty_poll); 626 ATF_TC_BODY(pty_poll, tc) 627 { 628 aio_pty_test(poll); 629 } 630 631 ATF_TC_WITHOUT_HEAD(pty_suspend); 632 ATF_TC_BODY(pty_suspend, tc) 633 { 634 aio_pty_test(suspend); 635 } 636 637 ATF_TC_WITHOUT_HEAD(pty_waitcomplete); 638 ATF_TC_BODY(pty_waitcomplete, tc) 639 { 640 aio_pty_test(waitcomplete); 641 } 642 643 static void 644 aio_pipe_cleanup(void *arg) 645 { 646 int *pipes = arg; 647 648 close(pipes[0]); 649 close(pipes[1]); 650 } 651 652 #define PIPE_LEN 256 653 #define PIPE_TIMEOUT 30 654 static void 655 aio_pipe_test(completion comp) 656 { 657 struct aio_context ac; 658 int pipes[2]; 659 660 ATF_REQUIRE_KERNEL_MODULE("aio"); 661 ATF_REQUIRE_UNSAFE_AIO(); 662 663 ATF_REQUIRE_MSG(pipe(pipes) != -1, 664 "pipe failed: %s", strerror(errno)); 665 666 aio_context_init(&ac, pipes[0], pipes[1], PIPE_LEN, 667 PIPE_TIMEOUT, aio_pipe_cleanup, pipes); 668 aio_write_test(&ac, comp); 669 aio_read_test(&ac, comp); 670 671 aio_pipe_cleanup(pipes); 672 } 673 674 ATF_TC_WITHOUT_HEAD(pipe_poll); 675 ATF_TC_BODY(pipe_poll, tc) 676 { 677 aio_pipe_test(poll); 678 } 679 680 ATF_TC_WITHOUT_HEAD(pipe_suspend); 681 ATF_TC_BODY(pipe_suspend, tc) 682 { 683 aio_pipe_test(suspend); 684 } 685 686 ATF_TC_WITHOUT_HEAD(pipe_waitcomplete); 687 ATF_TC_BODY(pipe_waitcomplete, tc) 688 { 689 aio_pipe_test(waitcomplete); 690 } 691 692 struct aio_md_arg { 693 int ama_mdctl_fd; 694 int ama_unit; 695 int ama_fd; 696 }; 697 698 static void 699 aio_md_cleanup(void *arg) 700 { 701 struct aio_md_arg *ama; 702 struct md_ioctl mdio; 703 int error; 704 705 ama = arg; 706 707 if (ama->ama_fd != -1) 708 close(ama->ama_fd); 709 710 if (ama->ama_unit != -1) { 711 bzero(&mdio, sizeof(mdio)); 712 mdio.md_version = MDIOVERSION; 713 mdio.md_unit = ama->ama_unit; 714 if (ioctl(ama->ama_mdctl_fd, MDIOCDETACH, &mdio) == -1) { 715 error = errno; 716 close(ama->ama_mdctl_fd); 717 errno = error; 718 atf_tc_fail("ioctl MDIOCDETACH failed: %s", 719 strerror(errno)); 720 } 721 } 722 723 close(ama->ama_mdctl_fd); 724 } 725 726 #define MD_LEN GLOBAL_MAX 727 #define MD_TIMEOUT 30 728 static void 729 aio_md_test(completion comp) 730 { 731 int error, fd, mdctl_fd, unit; 732 char pathname[PATH_MAX]; 733 struct aio_md_arg arg; 734 struct aio_context ac; 735 struct md_ioctl mdio; 736 737 ATF_REQUIRE_KERNEL_MODULE("aio"); 738 ATF_REQUIRE_UNSAFE_AIO(); 739 740 mdctl_fd = open("/dev/" MDCTL_NAME, O_RDWR, 0); 741 ATF_REQUIRE_MSG(mdctl_fd != -1, 742 "opening /dev/%s failed: %s", MDCTL_NAME, strerror(errno)); 743 744 bzero(&mdio, sizeof(mdio)); 745 mdio.md_version = MDIOVERSION; 746 mdio.md_type = MD_MALLOC; 747 mdio.md_options = MD_AUTOUNIT | MD_COMPRESS; 748 mdio.md_mediasize = GLOBAL_MAX; 749 mdio.md_sectorsize = 512; 750 751 arg.ama_mdctl_fd = mdctl_fd; 752 arg.ama_unit = -1; 753 arg.ama_fd = -1; 754 if (ioctl(mdctl_fd, MDIOCATTACH, &mdio) < 0) { 755 error = errno; 756 aio_md_cleanup(&arg); 757 errno = error; 758 atf_tc_fail("ioctl MDIOCATTACH failed: %s", strerror(errno)); 759 } 760 761 arg.ama_unit = unit = mdio.md_unit; 762 snprintf(pathname, PATH_MAX, "/dev/md%d", unit); 763 fd = open(pathname, O_RDWR); 764 ATF_REQUIRE_MSG(fd != -1, 765 "opening %s failed: %s", pathname, strerror(errno)); 766 arg.ama_fd = fd; 767 768 aio_context_init(&ac, fd, fd, MD_LEN, MD_TIMEOUT, 769 aio_md_cleanup, &arg); 770 aio_write_test(&ac, comp); 771 aio_read_test(&ac, comp); 772 773 aio_md_cleanup(&arg); 774 } 775 776 ATF_TC(md_poll); 777 ATF_TC_HEAD(md_poll, tc) 778 { 779 780 atf_tc_set_md_var(tc, "require.user", "root"); 781 } 782 ATF_TC_BODY(md_poll, tc) 783 { 784 aio_md_test(poll); 785 } 786 787 ATF_TC(md_suspend); 788 ATF_TC_HEAD(md_suspend, tc) 789 { 790 791 atf_tc_set_md_var(tc, "require.user", "root"); 792 } 793 ATF_TC_BODY(md_suspend, tc) 794 { 795 aio_md_test(suspend); 796 } 797 798 ATF_TC(md_waitcomplete); 799 ATF_TC_HEAD(md_waitcomplete, tc) 800 { 801 802 atf_tc_set_md_var(tc, "require.user", "root"); 803 } 804 ATF_TC_BODY(md_waitcomplete, tc) 805 { 806 aio_md_test(waitcomplete); 807 } 808 809 ATF_TC_WITHOUT_HEAD(aio_large_read_test); 810 ATF_TC_BODY(aio_large_read_test, tc) 811 { 812 struct aiocb cb, *cbp; 813 ssize_t nread; 814 size_t len; 815 int fd; 816 #ifdef __LP64__ 817 int clamped; 818 #endif 819 820 ATF_REQUIRE_KERNEL_MODULE("aio"); 821 ATF_REQUIRE_UNSAFE_AIO(); 822 823 #ifdef __LP64__ 824 len = sizeof(clamped); 825 if (sysctlbyname("debug.iosize_max_clamp", &clamped, &len, NULL, 0) == 826 -1) 827 atf_libc_error(errno, "Failed to read debug.iosize_max_clamp"); 828 #endif 829 830 /* Determine the maximum supported read(2) size. */ 831 len = SSIZE_MAX; 832 #ifdef __LP64__ 833 if (clamped) 834 len = INT_MAX; 835 #endif 836 837 fd = open(FILE_PATHNAME, O_RDWR | O_CREAT); 838 ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 839 840 unlink(FILE_PATHNAME); 841 842 memset(&cb, 0, sizeof(cb)); 843 cb.aio_nbytes = len; 844 cb.aio_fildes = fd; 845 cb.aio_buf = NULL; 846 if (aio_read(&cb) == -1) 847 atf_tc_fail("aio_read() of maximum read size failed: %s", 848 strerror(errno)); 849 850 nread = aio_waitcomplete(&cbp, NULL); 851 if (nread == -1) 852 atf_tc_fail("aio_waitcomplete() failed: %s", strerror(errno)); 853 if (nread != 0) 854 atf_tc_fail("aio_read() from empty file returned data: %zd", 855 nread); 856 857 memset(&cb, 0, sizeof(cb)); 858 cb.aio_nbytes = len + 1; 859 cb.aio_fildes = fd; 860 cb.aio_buf = NULL; 861 if (aio_read(&cb) == -1) { 862 if (errno == EINVAL) 863 goto finished; 864 atf_tc_fail("aio_read() of too large read size failed: %s", 865 strerror(errno)); 866 } 867 868 nread = aio_waitcomplete(&cbp, NULL); 869 if (nread == -1) { 870 if (errno == EINVAL) 871 goto finished; 872 atf_tc_fail("aio_waitcomplete() failed: %s", strerror(errno)); 873 } 874 atf_tc_fail("aio_read() of too large read size returned: %zd", nread); 875 876 finished: 877 close(fd); 878 } 879 880 /* 881 * This tests for a bug where arriving socket data can wakeup multiple 882 * AIO read requests resulting in an uncancellable request. 883 */ 884 ATF_TC_WITHOUT_HEAD(aio_socket_two_reads); 885 ATF_TC_BODY(aio_socket_two_reads, tc) 886 { 887 struct ioreq { 888 struct aiocb iocb; 889 char buffer[1024]; 890 } ioreq[2]; 891 struct aiocb *iocb; 892 unsigned i; 893 int s[2]; 894 char c; 895 896 ATF_REQUIRE_KERNEL_MODULE("aio"); 897 #if __FreeBSD_version < 1100101 898 aft_tc_skip("kernel version %d is too old (%d required)", 899 __FreeBSD_version, 1100101); 900 #endif 901 902 ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); 903 904 /* Queue two read requests. */ 905 memset(&ioreq, 0, sizeof(ioreq)); 906 for (i = 0; i < nitems(ioreq); i++) { 907 ioreq[i].iocb.aio_nbytes = sizeof(ioreq[i].buffer); 908 ioreq[i].iocb.aio_fildes = s[0]; 909 ioreq[i].iocb.aio_buf = ioreq[i].buffer; 910 ATF_REQUIRE(aio_read(&ioreq[i].iocb) == 0); 911 } 912 913 /* Send a single byte. This should complete one request. */ 914 c = 0xc3; 915 ATF_REQUIRE(write(s[1], &c, sizeof(c)) == 1); 916 917 ATF_REQUIRE(aio_waitcomplete(&iocb, NULL) == 1); 918 919 /* Determine which request completed and verify the data was read. */ 920 if (iocb == &ioreq[0].iocb) 921 i = 0; 922 else 923 i = 1; 924 ATF_REQUIRE(ioreq[i].buffer[0] == c); 925 926 i ^= 1; 927 928 /* 929 * Try to cancel the other request. On broken systems this 930 * will fail and the process will hang on exit. 931 */ 932 ATF_REQUIRE(aio_error(&ioreq[i].iocb) == EINPROGRESS); 933 ATF_REQUIRE(aio_cancel(s[0], &ioreq[i].iocb) == AIO_CANCELED); 934 935 close(s[1]); 936 close(s[0]); 937 } 938 939 /* 940 * This test ensures that aio_write() on a blocking socket of a "large" 941 * buffer does not return a short completion. 942 */ 943 ATF_TC_WITHOUT_HEAD(aio_socket_blocking_short_write); 944 ATF_TC_BODY(aio_socket_blocking_short_write, tc) 945 { 946 struct aiocb iocb, *iocbp; 947 char *buffer[2]; 948 ssize_t done; 949 int buffer_size, sb_size; 950 socklen_t len; 951 int s[2]; 952 953 ATF_REQUIRE_KERNEL_MODULE("aio"); 954 955 ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); 956 957 len = sizeof(sb_size); 958 ATF_REQUIRE(getsockopt(s[0], SOL_SOCKET, SO_RCVBUF, &sb_size, &len) != 959 -1); 960 ATF_REQUIRE(len == sizeof(sb_size)); 961 buffer_size = sb_size; 962 963 ATF_REQUIRE(getsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &sb_size, &len) != 964 -1); 965 ATF_REQUIRE(len == sizeof(sb_size)); 966 if (sb_size > buffer_size) 967 buffer_size = sb_size; 968 969 /* 970 * Use twice the size of the MAX(receive buffer, send buffer) 971 * to ensure that the write is split up into multiple writes 972 * internally. 973 */ 974 buffer_size *= 2; 975 976 buffer[0] = malloc(buffer_size); 977 ATF_REQUIRE(buffer[0] != NULL); 978 buffer[1] = malloc(buffer_size); 979 ATF_REQUIRE(buffer[1] != NULL); 980 981 srandomdev(); 982 aio_fill_buffer(buffer[1], buffer_size, random()); 983 984 memset(&iocb, 0, sizeof(iocb)); 985 iocb.aio_fildes = s[1]; 986 iocb.aio_buf = buffer[1]; 987 iocb.aio_nbytes = buffer_size; 988 ATF_REQUIRE(aio_write(&iocb) == 0); 989 990 done = recv(s[0], buffer[0], buffer_size, MSG_WAITALL); 991 ATF_REQUIRE(done == buffer_size); 992 993 done = aio_waitcomplete(&iocbp, NULL); 994 ATF_REQUIRE(iocbp == &iocb); 995 ATF_REQUIRE(done == buffer_size); 996 997 ATF_REQUIRE(memcmp(buffer[0], buffer[1], buffer_size) == 0); 998 999 close(s[1]); 1000 close(s[0]); 1001 } 1002 1003 /* 1004 * This test verifies that cancelling a partially completed socket write 1005 * returns a short write rather than ECANCELED. 1006 */ 1007 ATF_TC_WITHOUT_HEAD(aio_socket_short_write_cancel); 1008 ATF_TC_BODY(aio_socket_short_write_cancel, tc) 1009 { 1010 struct aiocb iocb, *iocbp; 1011 char *buffer[2]; 1012 ssize_t done; 1013 int buffer_size, sb_size; 1014 socklen_t len; 1015 int s[2]; 1016 1017 ATF_REQUIRE_KERNEL_MODULE("aio"); 1018 1019 ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); 1020 1021 len = sizeof(sb_size); 1022 ATF_REQUIRE(getsockopt(s[0], SOL_SOCKET, SO_RCVBUF, &sb_size, &len) != 1023 -1); 1024 ATF_REQUIRE(len == sizeof(sb_size)); 1025 buffer_size = sb_size; 1026 1027 ATF_REQUIRE(getsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &sb_size, &len) != 1028 -1); 1029 ATF_REQUIRE(len == sizeof(sb_size)); 1030 if (sb_size > buffer_size) 1031 buffer_size = sb_size; 1032 1033 /* 1034 * Use three times the size of the MAX(receive buffer, send 1035 * buffer) for the write to ensure that the write is split up 1036 * into multiple writes internally. The recv() ensures that 1037 * the write has partially completed, but a remaining size of 1038 * two buffers should ensure that the write has not completed 1039 * fully when it is cancelled. 1040 */ 1041 buffer[0] = malloc(buffer_size); 1042 ATF_REQUIRE(buffer[0] != NULL); 1043 buffer[1] = malloc(buffer_size * 3); 1044 ATF_REQUIRE(buffer[1] != NULL); 1045 1046 srandomdev(); 1047 aio_fill_buffer(buffer[1], buffer_size * 3, random()); 1048 1049 memset(&iocb, 0, sizeof(iocb)); 1050 iocb.aio_fildes = s[1]; 1051 iocb.aio_buf = buffer[1]; 1052 iocb.aio_nbytes = buffer_size * 3; 1053 ATF_REQUIRE(aio_write(&iocb) == 0); 1054 1055 done = recv(s[0], buffer[0], buffer_size, MSG_WAITALL); 1056 ATF_REQUIRE(done == buffer_size); 1057 1058 ATF_REQUIRE(aio_error(&iocb) == EINPROGRESS); 1059 ATF_REQUIRE(aio_cancel(s[1], &iocb) == AIO_NOTCANCELED); 1060 1061 done = aio_waitcomplete(&iocbp, NULL); 1062 ATF_REQUIRE(iocbp == &iocb); 1063 ATF_REQUIRE(done >= buffer_size && done <= buffer_size * 2); 1064 1065 ATF_REQUIRE(memcmp(buffer[0], buffer[1], buffer_size) == 0); 1066 1067 close(s[1]); 1068 close(s[0]); 1069 } 1070 1071 /* 1072 * This test just performs a basic test of aio_fsync(). 1073 */ 1074 ATF_TC_WITHOUT_HEAD(aio_fsync_test); 1075 ATF_TC_BODY(aio_fsync_test, tc) 1076 { 1077 struct aiocb synccb, *iocbp; 1078 struct { 1079 struct aiocb iocb; 1080 bool done; 1081 char *buffer; 1082 } buffers[16]; 1083 struct stat sb; 1084 ssize_t rval; 1085 unsigned i; 1086 int fd; 1087 1088 ATF_REQUIRE_KERNEL_MODULE("aio"); 1089 ATF_REQUIRE_UNSAFE_AIO(); 1090 1091 fd = open(FILE_PATHNAME, O_RDWR | O_CREAT); 1092 ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1093 unlink(FILE_PATHNAME); 1094 1095 ATF_REQUIRE(fstat(fd, &sb) == 0); 1096 ATF_REQUIRE(sb.st_blksize != 0); 1097 ATF_REQUIRE(ftruncate(fd, sb.st_blksize * nitems(buffers)) == 0); 1098 1099 /* 1100 * Queue several asynchronous write requests. Hopefully this 1101 * forces the aio_fsync() request to be deferred. There is no 1102 * reliable way to guarantee that however. 1103 */ 1104 srandomdev(); 1105 for (i = 0; i < nitems(buffers); i++) { 1106 buffers[i].done = false; 1107 memset(&buffers[i].iocb, 0, sizeof(buffers[i].iocb)); 1108 buffers[i].buffer = malloc(sb.st_blksize); 1109 aio_fill_buffer(buffers[i].buffer, sb.st_blksize, random()); 1110 buffers[i].iocb.aio_fildes = fd; 1111 buffers[i].iocb.aio_buf = buffers[i].buffer; 1112 buffers[i].iocb.aio_nbytes = sb.st_blksize; 1113 buffers[i].iocb.aio_offset = sb.st_blksize * i; 1114 ATF_REQUIRE(aio_write(&buffers[i].iocb) == 0); 1115 } 1116 1117 /* Queue the aio_fsync request. */ 1118 memset(&synccb, 0, sizeof(synccb)); 1119 synccb.aio_fildes = fd; 1120 ATF_REQUIRE(aio_fsync(O_SYNC, &synccb) == 0); 1121 1122 /* Wait for requests to complete. */ 1123 for (;;) { 1124 next: 1125 rval = aio_waitcomplete(&iocbp, NULL); 1126 ATF_REQUIRE(iocbp != NULL); 1127 if (iocbp == &synccb) { 1128 ATF_REQUIRE(rval == 0); 1129 break; 1130 } 1131 1132 for (i = 0; i < nitems(buffers); i++) { 1133 if (iocbp == &buffers[i].iocb) { 1134 ATF_REQUIRE(buffers[i].done == false); 1135 ATF_REQUIRE(rval == sb.st_blksize); 1136 buffers[i].done = true; 1137 goto next; 1138 } 1139 } 1140 1141 ATF_REQUIRE_MSG(false, "unmatched AIO request"); 1142 } 1143 1144 for (i = 0; i < nitems(buffers); i++) 1145 ATF_REQUIRE_MSG(buffers[i].done, 1146 "AIO request %u did not complete", i); 1147 1148 close(fd); 1149 } 1150 1151 ATF_TP_ADD_TCS(tp) 1152 { 1153 1154 ATF_TP_ADD_TC(tp, file_poll); 1155 ATF_TP_ADD_TC(tp, file_suspend); 1156 ATF_TP_ADD_TC(tp, file_waitcomplete); 1157 ATF_TP_ADD_TC(tp, fifo_poll); 1158 ATF_TP_ADD_TC(tp, fifo_suspend); 1159 ATF_TP_ADD_TC(tp, fifo_waitcomplete); 1160 ATF_TP_ADD_TC(tp, socket_poll); 1161 ATF_TP_ADD_TC(tp, socket_suspend); 1162 ATF_TP_ADD_TC(tp, socket_waitcomplete); 1163 ATF_TP_ADD_TC(tp, pty_poll); 1164 ATF_TP_ADD_TC(tp, pty_suspend); 1165 ATF_TP_ADD_TC(tp, pty_waitcomplete); 1166 ATF_TP_ADD_TC(tp, pipe_poll); 1167 ATF_TP_ADD_TC(tp, pipe_suspend); 1168 ATF_TP_ADD_TC(tp, pipe_waitcomplete); 1169 ATF_TP_ADD_TC(tp, md_poll); 1170 ATF_TP_ADD_TC(tp, md_suspend); 1171 ATF_TP_ADD_TC(tp, md_waitcomplete); 1172 ATF_TP_ADD_TC(tp, aio_large_read_test); 1173 ATF_TP_ADD_TC(tp, aio_socket_two_reads); 1174 ATF_TP_ADD_TC(tp, aio_socket_blocking_short_write); 1175 ATF_TP_ADD_TC(tp, aio_socket_short_write_cancel); 1176 ATF_TP_ADD_TC(tp, aio_fsync_test); 1177 1178 return (atf_no_error()); 1179 } 1180