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