aio_test.c revision 321095
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: stable/11/tests/sys/aio/aio_test.c 321095 2017-07-17 21:17:03Z ngie $ 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 */ 80typedef ssize_t (*completion)(struct aiocb*); 81 82struct 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 92static 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 */ 98static void 99aio_timeout_signal(int sig __unused) 100{ 101 102 aio_timedout = 1; 103} 104 105static void 106aio_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 115static void 116aio_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 */ 128static void 129aio_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 */ 145static int 146aio_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 */ 164static void 165aio_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 187static ssize_t 188poll(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 205static ssize_t 206suspend(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 218static ssize_t 219waitcomplete(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 */ 234static void 235aio_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 */ 250static void 251aio_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 */ 299static void 300aio_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 364struct aio_file_arg { 365 int afa_fd; 366}; 367 368static void 369aio_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 378static void 379aio_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 401ATF_TC_WITHOUT_HEAD(file_poll); 402ATF_TC_BODY(file_poll, tc) 403{ 404 aio_file_test(poll); 405} 406 407ATF_TC_WITHOUT_HEAD(file_suspend); 408ATF_TC_BODY(file_suspend, tc) 409{ 410 aio_file_test(suspend); 411} 412 413ATF_TC_WITHOUT_HEAD(file_waitcomplete); 414ATF_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 422struct aio_fifo_arg { 423 int afa_read_fd; 424 int afa_write_fd; 425}; 426 427static void 428aio_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 440static void 441aio_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 483ATF_TC_WITHOUT_HEAD(fifo_poll); 484ATF_TC_BODY(fifo_poll, tc) 485{ 486 aio_fifo_test(poll); 487} 488 489ATF_TC_WITHOUT_HEAD(fifo_suspend); 490ATF_TC_BODY(fifo_suspend, tc) 491{ 492 aio_fifo_test(waitcomplete); 493} 494 495ATF_TC_WITHOUT_HEAD(fifo_waitcomplete); 496ATF_TC_BODY(fifo_waitcomplete, tc) 497{ 498 aio_fifo_test(waitcomplete); 499} 500 501struct aio_unix_socketpair_arg { 502 int asa_sockets[2]; 503}; 504 505static void 506aio_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 517static void 518aio_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 550ATF_TC_WITHOUT_HEAD(socket_poll); 551ATF_TC_BODY(socket_poll, tc) 552{ 553 aio_unix_socketpair_test(poll); 554} 555 556ATF_TC_WITHOUT_HEAD(socket_suspend); 557ATF_TC_BODY(socket_suspend, tc) 558{ 559 aio_unix_socketpair_test(suspend); 560} 561 562ATF_TC_WITHOUT_HEAD(socket_waitcomplete); 563ATF_TC_BODY(socket_waitcomplete, tc) 564{ 565 aio_unix_socketpair_test(waitcomplete); 566} 567 568struct aio_pty_arg { 569 int apa_read_fd; 570 int apa_write_fd; 571}; 572 573static void 574aio_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 585static void 586aio_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 625ATF_TC_WITHOUT_HEAD(pty_poll); 626ATF_TC_BODY(pty_poll, tc) 627{ 628 aio_pty_test(poll); 629} 630 631ATF_TC_WITHOUT_HEAD(pty_suspend); 632ATF_TC_BODY(pty_suspend, tc) 633{ 634 aio_pty_test(suspend); 635} 636 637ATF_TC_WITHOUT_HEAD(pty_waitcomplete); 638ATF_TC_BODY(pty_waitcomplete, tc) 639{ 640 aio_pty_test(waitcomplete); 641} 642 643static void 644aio_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 654static void 655aio_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 674ATF_TC_WITHOUT_HEAD(pipe_poll); 675ATF_TC_BODY(pipe_poll, tc) 676{ 677 aio_pipe_test(poll); 678} 679 680ATF_TC_WITHOUT_HEAD(pipe_suspend); 681ATF_TC_BODY(pipe_suspend, tc) 682{ 683 aio_pipe_test(suspend); 684} 685 686ATF_TC_WITHOUT_HEAD(pipe_waitcomplete); 687ATF_TC_BODY(pipe_waitcomplete, tc) 688{ 689 aio_pipe_test(waitcomplete); 690} 691 692struct aio_md_arg { 693 int ama_mdctl_fd; 694 int ama_unit; 695 int ama_fd; 696}; 697 698static void 699aio_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 728static void 729aio_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 776ATF_TC(md_poll); 777ATF_TC_HEAD(md_poll, tc) 778{ 779 780 atf_tc_set_md_var(tc, "require.user", "root"); 781} 782ATF_TC_BODY(md_poll, tc) 783{ 784 aio_md_test(poll); 785} 786 787ATF_TC(md_suspend); 788ATF_TC_HEAD(md_suspend, tc) 789{ 790 791 atf_tc_set_md_var(tc, "require.user", "root"); 792} 793ATF_TC_BODY(md_suspend, tc) 794{ 795 aio_md_test(suspend); 796} 797 798ATF_TC(md_waitcomplete); 799ATF_TC_HEAD(md_waitcomplete, tc) 800{ 801 802 atf_tc_set_md_var(tc, "require.user", "root"); 803} 804ATF_TC_BODY(md_waitcomplete, tc) 805{ 806 aio_md_test(waitcomplete); 807} 808 809ATF_TC_WITHOUT_HEAD(aio_large_read_test); 810ATF_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 876finished: 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 */ 884ATF_TC_WITHOUT_HEAD(aio_socket_two_reads); 885ATF_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 */ 943ATF_TC_WITHOUT_HEAD(aio_socket_blocking_short_write); 944ATF_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 */ 1007ATF_TC_WITHOUT_HEAD(aio_socket_short_write_cancel); 1008ATF_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 */ 1074ATF_TC_WITHOUT_HEAD(aio_fsync_test); 1075ATF_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 1151ATF_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