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