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