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