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