xref: /freebsd/tests/sys/aio/aio_test.c (revision d600f474c65ab237c28ee585fe95e6bdf8003446)
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