xref: /src/tests/sys/aio/aio_test.c (revision dc9a8d300ba5c4c319589d78231e9d0e76576cbf)
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 
27 /*
28  * Regression test to do some very basic AIO exercising on several types of
29  * file descriptors.  Currently, the tests consist of initializing a fixed
30  * size buffer with pseudo-random data, writing it to one fd using AIO, then
31  * reading it from a second descriptor using AIO.  For some targets, the same
32  * fd is used for write and read (i.e., file, md device), but for others the
33  * operation is performed on a peer (pty, socket, fifo, etc).  For each file
34  * descriptor type, several completion methods are tested.  This test program
35  * does not attempt to exercise error cases or more subtle asynchronous
36  * behavior, just make sure that the basic operations work on some basic object
37  * types.
38  */
39 
40 #include <sys/param.h>
41 #include <sys/event.h>
42 #include <sys/mman.h>
43 #include <sys/mdioctl.h>
44 #include <sys/module.h>
45 #include <sys/resource.h>
46 #include <sys/socket.h>
47 #include <sys/stat.h>
48 #include <sys/un.h>
49 
50 #include <aio.h>
51 #include <err.h>
52 #include <errno.h>
53 #include <fcntl.h>
54 #include <libutil.h>
55 #include <limits.h>
56 #include <semaphore.h>
57 #include <signal.h>
58 #include <stdint.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <termios.h>
63 #include <unistd.h>
64 
65 #include <atf-c.h>
66 
67 #include "local.h"
68 
69 /*
70  * GLOBAL_MAX sets the largest usable buffer size to be read and written, as
71  * it sizes ac_buffer in the aio_context structure.  It is also the default
72  * size for file I/O.  For other types, we use smaller blocks or we risk
73  * blocking (and we run in a single process/thread so that would be bad).
74  */
75 #define	GLOBAL_MAX	16384
76 
77 #define	BUFFER_MAX	GLOBAL_MAX
78 
79 /*
80  * A completion function will block until the aio has completed, then return
81  * the result of the aio.  errno will be set appropriately.
82  */
83 typedef ssize_t (*completion)(struct aiocb*);
84 
85 struct aio_context {
86 	int		 ac_read_fd, ac_write_fd;
87 	long		 ac_seed;
88 	char		 ac_buffer[GLOBAL_MAX];
89 	int		 ac_buflen;
90 	int		 ac_seconds;
91 };
92 
93 static sem_t		completions;
94 
95 /*
96  * Fill a buffer given a seed that can be fed into srandom() to initialize
97  * the PRNG in a repeatable manner.
98  */
99 static void
aio_fill_buffer(char * buffer,int len,long seed)100 aio_fill_buffer(char *buffer, int len, long seed)
101 {
102 	char ch;
103 	int i;
104 
105 	srandom(seed);
106 	for (i = 0; i < len; i++) {
107 		ch = random() & 0xff;
108 		buffer[i] = ch;
109 	}
110 }
111 
112 /*
113  * Test that a buffer matches a given seed.  See aio_fill_buffer().  Return
114  * (1) on a match, (0) on a mismatch.
115  */
116 static int
aio_test_buffer(char * buffer,int len,long seed)117 aio_test_buffer(char *buffer, int len, long seed)
118 {
119 	char ch;
120 	int i;
121 
122 	srandom(seed);
123 	for (i = 0; i < len; i++) {
124 		ch = random() & 0xff;
125 		if (buffer[i] != ch)
126 			return (0);
127 	}
128 	return (1);
129 }
130 
131 /*
132  * Initialize a testing context given the file descriptors provided by the
133  * test setup.
134  */
135 static void
aio_context_init(struct aio_context * ac,int read_fd,int write_fd,int buflen)136 aio_context_init(struct aio_context *ac, int read_fd,
137     int write_fd, int buflen)
138 {
139 
140 	ATF_REQUIRE_MSG(buflen <= BUFFER_MAX,
141 	    "aio_context_init: buffer too large (%d > %d)",
142 	    buflen, BUFFER_MAX);
143 	bzero(ac, sizeof(*ac));
144 	ac->ac_read_fd = read_fd;
145 	ac->ac_write_fd = write_fd;
146 	ac->ac_buflen = buflen;
147 	srandomdev();
148 	ac->ac_seed = random();
149 	aio_fill_buffer(ac->ac_buffer, buflen, ac->ac_seed);
150 	ATF_REQUIRE_MSG(aio_test_buffer(ac->ac_buffer, buflen,
151 	    ac->ac_seed) != 0, "aio_test_buffer: internal error");
152 }
153 
154 static ssize_t
poll(struct aiocb * aio)155 poll(struct aiocb *aio)
156 {
157 	int error;
158 
159 	while ((error = aio_error(aio)) == EINPROGRESS)
160 		usleep(25000);
161 	if (error)
162 		return (error);
163 	else
164 		return (aio_return(aio));
165 }
166 
167 static void
sigusr1_handler(int sig __unused)168 sigusr1_handler(int sig __unused)
169 {
170 	ATF_REQUIRE_EQ(0, sem_post(&completions));
171 }
172 
173 static void
thr_handler(union sigval sv __unused)174 thr_handler(union sigval sv __unused)
175 {
176 	ATF_REQUIRE_EQ(0, sem_post(&completions));
177 }
178 
179 static ssize_t
poll_signaled(struct aiocb * aio)180 poll_signaled(struct aiocb *aio)
181 {
182 	int error;
183 
184 	ATF_REQUIRE_EQ(0, sem_wait(&completions));
185 	error = aio_error(aio);
186 	switch (error) {
187 		case EINPROGRESS:
188 			errno = EINTR;
189 			return (-1);
190 		case 0:
191 			return (aio_return(aio));
192 		default:
193 			return (error);
194 	}
195 }
196 
197 /*
198  * Setup a signal handler for signal delivery tests
199  * This isn't thread safe, but it's ok since ATF runs each testcase in a
200  * separate process
201  */
202 static struct sigevent*
setup_signal(void)203 setup_signal(void)
204 {
205 	static struct sigevent sev;
206 
207 	ATF_REQUIRE_EQ(0, sem_init(&completions, false, 0));
208 	sev.sigev_notify = SIGEV_SIGNAL;
209 	sev.sigev_signo = SIGUSR1;
210 	ATF_REQUIRE(SIG_ERR != signal(SIGUSR1, sigusr1_handler));
211 	return (&sev);
212 }
213 
214 /*
215  * Setup a thread for thread delivery tests
216  * This isn't thread safe, but it's ok since ATF runs each testcase in a
217  * separate process
218  */
219 static struct sigevent*
setup_thread(void)220 setup_thread(void)
221 {
222 	static struct sigevent sev;
223 
224 	ATF_REQUIRE_EQ(0, sem_init(&completions, false, 0));
225 	sev.sigev_notify = SIGEV_THREAD;
226 	sev.sigev_notify_function = thr_handler;
227 	sev.sigev_notify_attributes = NULL;
228 	return (&sev);
229 }
230 
231 static ssize_t
suspend(struct aiocb * aio)232 suspend(struct aiocb *aio)
233 {
234 	const struct aiocb *const iocbs[] = {aio};
235 	int error;
236 
237 	error = aio_suspend(iocbs, 1, NULL);
238 	if (error == 0)
239 		return (aio_return(aio));
240 	else
241 		return (error);
242 }
243 
244 static ssize_t
waitcomplete(struct aiocb * aio)245 waitcomplete(struct aiocb *aio)
246 {
247 	struct aiocb *aiop;
248 	ssize_t ret;
249 
250 	ret = aio_waitcomplete(&aiop, NULL);
251 	ATF_REQUIRE_EQ(aio, aiop);
252 	return (ret);
253 }
254 
255 /*
256  * Setup an iocb for kqueue notification.  This isn't thread
257  * safe, but it's ok because ATF runs every test case in a separate process.
258  */
259 static struct sigevent*
setup_kqueue(void)260 setup_kqueue(void)
261 {
262 	static struct sigevent sev;
263 	static int kq;
264 
265 	kq = kqueue();
266 	ATF_REQUIRE(kq >= 0);
267 
268 	memset(&sev, 0, sizeof(sev));
269 	sev.sigev_notify_kqueue = kq;
270 	sev.sigev_value.sival_ptr = (void*)0xdeadbeef;
271 	sev.sigev_notify = SIGEV_KEVENT;
272 
273 	return (&sev);
274 }
275 
276 static ssize_t
poll_kqueue(struct aiocb * aio)277 poll_kqueue(struct aiocb *aio)
278 {
279 	int kq, nevents;
280 	struct kevent events[1];
281 
282 	kq = aio->aio_sigevent.sigev_notify_kqueue;
283 
284 	nevents = kevent(kq, NULL, 0, events, 1, NULL);
285 	ATF_CHECK_EQ(1, nevents);
286 	ATF_CHECK_EQ(events[0].ident, (uintptr_t) aio);
287 	ATF_CHECK_EQ(events[0].filter, EVFILT_AIO);
288 	ATF_CHECK_EQ(events[0].flags, EV_EOF);
289 	ATF_CHECK_EQ(events[0].fflags, 0);
290 	ATF_CHECK_EQ(events[0].data, 0);
291 	ATF_CHECK_EQ((uintptr_t)events[0].udata, 0xdeadbeef);
292 
293 	return (aio_return(aio));
294 }
295 
296 /*
297  * Perform a simple write test of our initialized data buffer to the provided
298  * file descriptor.
299  */
300 static void
aio_write_test(struct aio_context * ac,completion comp,struct sigevent * sev)301 aio_write_test(struct aio_context *ac, completion comp, struct sigevent *sev)
302 {
303 	struct aiocb aio;
304 	ssize_t len;
305 
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_write_fd;
310 	aio.aio_offset = 0;
311 	if (sev)
312 		aio.aio_sigevent = *sev;
313 
314 	if (aio_write(&aio) < 0)
315 		atf_tc_fail("aio_write failed: %s", strerror(errno));
316 
317 	len = comp(&aio);
318 	if (len < 0)
319 		atf_tc_fail("aio failed: %s", strerror(errno));
320 
321 	if (len != ac->ac_buflen)
322 		atf_tc_fail("aio short write (%jd)", (intmax_t)len);
323 }
324 
325 /*
326  * Perform a vectored I/O test of our initialized data buffer to the provided
327  * file descriptor.
328  *
329  * To vectorize the linear buffer, chop it up into two pieces of dissimilar
330  * size, and swap their offsets.
331  */
332 static void
aio_writev_test(struct aio_context * ac,completion comp,struct sigevent * sev)333 aio_writev_test(struct aio_context *ac, completion comp, struct sigevent *sev)
334 {
335 	struct aiocb aio;
336 	struct iovec iov[2];
337 	size_t len0, len1;
338 	ssize_t len;
339 
340 	bzero(&aio, sizeof(aio));
341 
342 	aio.aio_fildes = ac->ac_write_fd;
343 	aio.aio_offset = 0;
344 	len0 = ac->ac_buflen * 3 / 4;
345 	len1 = ac->ac_buflen / 4;
346 	iov[0].iov_base = ac->ac_buffer + len1;
347 	iov[0].iov_len = len0;
348 	iov[1].iov_base = ac->ac_buffer;
349 	iov[1].iov_len = len1;
350 	aio.aio_iov = iov;
351 	aio.aio_iovcnt = 2;
352 	if (sev)
353 		aio.aio_sigevent = *sev;
354 
355 	if (aio_writev(&aio) < 0)
356 		atf_tc_fail("aio_writev failed: %s", strerror(errno));
357 
358 	len = comp(&aio);
359 	if (len < 0)
360 		atf_tc_fail("aio failed: %s", strerror(errno));
361 
362 	if (len != ac->ac_buflen)
363 		atf_tc_fail("aio short write (%jd)", (intmax_t)len);
364 }
365 
366 /*
367  * Perform a simple read test of our initialized data buffer from the
368  * provided file descriptor.
369  */
370 static void
aio_read_test(struct aio_context * ac,completion comp,struct sigevent * sev)371 aio_read_test(struct aio_context *ac, completion comp, struct sigevent *sev)
372 {
373 	struct aiocb aio;
374 	ssize_t len;
375 
376 	bzero(ac->ac_buffer, ac->ac_buflen);
377 	bzero(&aio, sizeof(aio));
378 	aio.aio_buf = ac->ac_buffer;
379 	aio.aio_nbytes = ac->ac_buflen;
380 	aio.aio_fildes = ac->ac_read_fd;
381 	aio.aio_offset = 0;
382 	if (sev)
383 		aio.aio_sigevent = *sev;
384 
385 	if (aio_read(&aio) < 0)
386 		atf_tc_fail("aio_read failed: %s", strerror(errno));
387 
388 	len = comp(&aio);
389 	if (len < 0)
390 		atf_tc_fail("aio failed: %s", strerror(errno));
391 
392 	ATF_REQUIRE_EQ_MSG(len, ac->ac_buflen,
393 	    "aio short read (%jd)", (intmax_t)len);
394 
395 	if (aio_test_buffer(ac->ac_buffer, ac->ac_buflen, ac->ac_seed) == 0)
396 		atf_tc_fail("buffer mismatched");
397 }
398 
399 static void
aio_readv_test(struct aio_context * ac,completion comp,struct sigevent * sev)400 aio_readv_test(struct aio_context *ac, completion comp, struct sigevent *sev)
401 {
402 	struct aiocb aio;
403 	struct iovec iov[2];
404 	size_t len0, len1;
405 	ssize_t len;
406 
407 	bzero(ac->ac_buffer, ac->ac_buflen);
408 	bzero(&aio, sizeof(aio));
409 	aio.aio_fildes = ac->ac_read_fd;
410 	aio.aio_offset = 0;
411 	len0 = ac->ac_buflen * 3 / 4;
412 	len1 = ac->ac_buflen / 4;
413 	iov[0].iov_base = ac->ac_buffer + len1;
414 	iov[0].iov_len = len0;
415 	iov[1].iov_base = ac->ac_buffer;
416 	iov[1].iov_len = len1;
417 	aio.aio_iov = iov;
418 	aio.aio_iovcnt = 2;
419 	if (sev)
420 		aio.aio_sigevent = *sev;
421 
422 	if (aio_readv(&aio) < 0)
423 		atf_tc_fail("aio_read failed: %s", strerror(errno));
424 
425 	len = comp(&aio);
426 	if (len < 0)
427 		atf_tc_fail("aio failed: %s", strerror(errno));
428 
429 	ATF_REQUIRE_EQ_MSG(len, ac->ac_buflen,
430 	    "aio short read (%jd)", (intmax_t)len);
431 
432 	if (aio_test_buffer(ac->ac_buffer, ac->ac_buflen, ac->ac_seed) == 0)
433 		atf_tc_fail("buffer mismatched");
434 }
435 
436 /*
437  * Series of type-specific tests for AIO.  For now, we just make sure we can
438  * issue a write and then a read to each type.  We assume that once a write
439  * is issued, a read can follow.
440  */
441 
442 /*
443  * Test with a classic file.  Assumes we can create a moderate size temporary
444  * file.
445  */
446 #define	FILE_LEN	GLOBAL_MAX
447 #define	FILE_PATHNAME	"testfile"
448 
449 static void
aio_file_test(completion comp,struct sigevent * sev,bool vectored)450 aio_file_test(completion comp, struct sigevent *sev, bool vectored)
451 {
452 	struct aio_context ac;
453 	int fd;
454 
455 	ATF_REQUIRE_UNSAFE_AIO();
456 
457 	fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600);
458 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
459 
460 	aio_context_init(&ac, fd, fd, FILE_LEN);
461 	if (vectored) {
462 		aio_writev_test(&ac, comp, sev);
463 		aio_readv_test(&ac, comp, sev);
464 	} else {
465 		aio_write_test(&ac, comp, sev);
466 		aio_read_test(&ac, comp, sev);
467 	}
468 	close(fd);
469 }
470 
471 ATF_TC_WITHOUT_HEAD(file_kq);
ATF_TC_BODY(file_kq,tc)472 ATF_TC_BODY(file_kq, tc)
473 {
474 	aio_file_test(poll_kqueue, setup_kqueue(), false);
475 }
476 
477 ATF_TC_WITHOUT_HEAD(file_poll);
ATF_TC_BODY(file_poll,tc)478 ATF_TC_BODY(file_poll, tc)
479 {
480 	aio_file_test(poll, NULL, false);
481 }
482 
483 ATF_TC_WITHOUT_HEAD(file_signal);
ATF_TC_BODY(file_signal,tc)484 ATF_TC_BODY(file_signal, tc)
485 {
486 	aio_file_test(poll_signaled, setup_signal(), false);
487 }
488 
489 ATF_TC_WITHOUT_HEAD(file_suspend);
ATF_TC_BODY(file_suspend,tc)490 ATF_TC_BODY(file_suspend, tc)
491 {
492 	aio_file_test(suspend, NULL, false);
493 }
494 
495 ATF_TC_WITHOUT_HEAD(file_thread);
ATF_TC_BODY(file_thread,tc)496 ATF_TC_BODY(file_thread, tc)
497 {
498 	aio_file_test(poll_signaled, setup_thread(), false);
499 }
500 
501 ATF_TC_WITHOUT_HEAD(file_waitcomplete);
ATF_TC_BODY(file_waitcomplete,tc)502 ATF_TC_BODY(file_waitcomplete, tc)
503 {
504 	aio_file_test(waitcomplete, NULL, false);
505 }
506 
507 #define	FIFO_LEN	256
508 #define	FIFO_PATHNAME	"testfifo"
509 
510 static void
aio_fifo_test(completion comp,struct sigevent * sev)511 aio_fifo_test(completion comp, struct sigevent *sev)
512 {
513 	int error, read_fd = -1, write_fd = -1;
514 	struct aio_context ac;
515 
516 	ATF_REQUIRE_UNSAFE_AIO();
517 
518 	ATF_REQUIRE_MSG(mkfifo(FIFO_PATHNAME, 0600) != -1,
519 	    "mkfifo failed: %s", strerror(errno));
520 
521 	read_fd = open(FIFO_PATHNAME, O_RDONLY | O_NONBLOCK);
522 	if (read_fd == -1) {
523 		error = errno;
524 		errno = error;
525 		atf_tc_fail("read_fd open failed: %s",
526 		    strerror(errno));
527 	}
528 
529 	write_fd = open(FIFO_PATHNAME, O_WRONLY);
530 	if (write_fd == -1) {
531 		error = errno;
532 		errno = error;
533 		atf_tc_fail("write_fd open failed: %s",
534 		    strerror(errno));
535 	}
536 
537 	aio_context_init(&ac, read_fd, write_fd, FIFO_LEN);
538 	aio_write_test(&ac, comp, sev);
539 	aio_read_test(&ac, comp, sev);
540 
541 	close(read_fd);
542 	close(write_fd);
543 }
544 
545 ATF_TC_WITHOUT_HEAD(fifo_kq);
ATF_TC_BODY(fifo_kq,tc)546 ATF_TC_BODY(fifo_kq, tc)
547 {
548 	aio_fifo_test(poll_kqueue, setup_kqueue());
549 }
550 
551 ATF_TC_WITHOUT_HEAD(fifo_poll);
ATF_TC_BODY(fifo_poll,tc)552 ATF_TC_BODY(fifo_poll, tc)
553 {
554 	aio_fifo_test(poll, NULL);
555 }
556 
557 ATF_TC_WITHOUT_HEAD(fifo_signal);
ATF_TC_BODY(fifo_signal,tc)558 ATF_TC_BODY(fifo_signal, tc)
559 {
560 	aio_fifo_test(poll_signaled, setup_signal());
561 }
562 
563 ATF_TC_WITHOUT_HEAD(fifo_suspend);
ATF_TC_BODY(fifo_suspend,tc)564 ATF_TC_BODY(fifo_suspend, tc)
565 {
566 	aio_fifo_test(suspend, NULL);
567 }
568 
569 ATF_TC_WITHOUT_HEAD(fifo_thread);
ATF_TC_BODY(fifo_thread,tc)570 ATF_TC_BODY(fifo_thread, tc)
571 {
572 	aio_fifo_test(poll_signaled, setup_thread());
573 }
574 
575 ATF_TC_WITHOUT_HEAD(fifo_waitcomplete);
ATF_TC_BODY(fifo_waitcomplete,tc)576 ATF_TC_BODY(fifo_waitcomplete, tc)
577 {
578 	aio_fifo_test(waitcomplete, NULL);
579 }
580 
581 #define	UNIX_SOCKETPAIR_LEN	256
582 static void
aio_unix_socketpair_test(completion comp,struct sigevent * sev,bool vectored)583 aio_unix_socketpair_test(completion comp, struct sigevent *sev, bool vectored)
584 {
585 	struct aio_context ac;
586 	struct rusage ru_before, ru_after;
587 	int sockets[2];
588 
589 	ATF_REQUIRE_MSG(socketpair(PF_UNIX, SOCK_STREAM, 0, sockets) != -1,
590 	    "socketpair failed: %s", strerror(errno));
591 
592 	aio_context_init(&ac, sockets[0], sockets[1], UNIX_SOCKETPAIR_LEN);
593 	ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_before) != -1,
594 	    "getrusage failed: %s", strerror(errno));
595 	if (vectored) {
596 		aio_writev_test(&ac, comp, sev);
597 		aio_readv_test(&ac, comp, sev);
598 	} else {
599 		aio_write_test(&ac, comp, sev);
600 		aio_read_test(&ac, comp, sev);
601 	}
602 	ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1,
603 	    "getrusage failed: %s", strerror(errno));
604 	ATF_REQUIRE(ru_after.ru_msgsnd == ru_before.ru_msgsnd + 1);
605 	ATF_REQUIRE(ru_after.ru_msgrcv == ru_before.ru_msgrcv + 1);
606 
607 	close(sockets[0]);
608 	close(sockets[1]);
609 }
610 
611 ATF_TC_WITHOUT_HEAD(socket_kq);
ATF_TC_BODY(socket_kq,tc)612 ATF_TC_BODY(socket_kq, tc)
613 {
614 	aio_unix_socketpair_test(poll_kqueue, setup_kqueue(), false);
615 }
616 
617 ATF_TC_WITHOUT_HEAD(socket_poll);
ATF_TC_BODY(socket_poll,tc)618 ATF_TC_BODY(socket_poll, tc)
619 {
620 	aio_unix_socketpair_test(poll, NULL, false);
621 }
622 
623 ATF_TC_WITHOUT_HEAD(socket_signal);
ATF_TC_BODY(socket_signal,tc)624 ATF_TC_BODY(socket_signal, tc)
625 {
626 	aio_unix_socketpair_test(poll_signaled, setup_signal(), false);
627 }
628 
629 ATF_TC_WITHOUT_HEAD(socket_suspend);
ATF_TC_BODY(socket_suspend,tc)630 ATF_TC_BODY(socket_suspend, tc)
631 {
632 	aio_unix_socketpair_test(suspend, NULL, false);
633 }
634 
635 ATF_TC_WITHOUT_HEAD(socket_thread);
ATF_TC_BODY(socket_thread,tc)636 ATF_TC_BODY(socket_thread, tc)
637 {
638 	aio_unix_socketpair_test(poll_signaled, setup_thread(), false);
639 }
640 
641 ATF_TC_WITHOUT_HEAD(socket_waitcomplete);
ATF_TC_BODY(socket_waitcomplete,tc)642 ATF_TC_BODY(socket_waitcomplete, tc)
643 {
644 	aio_unix_socketpair_test(waitcomplete, NULL, false);
645 }
646 
647 struct aio_pty_arg {
648 	int	apa_read_fd;
649 	int	apa_write_fd;
650 };
651 
652 #define	PTY_LEN		256
653 static void
aio_pty_test(completion comp,struct sigevent * sev)654 aio_pty_test(completion comp, struct sigevent *sev)
655 {
656 	struct aio_context ac;
657 	int read_fd, write_fd;
658 	struct termios ts;
659 	int error;
660 
661 	ATF_REQUIRE_UNSAFE_AIO();
662 
663 	ATF_REQUIRE_MSG(openpty(&read_fd, &write_fd, NULL, NULL, NULL) == 0,
664 	    "openpty failed: %s", strerror(errno));
665 
666 
667 	if (tcgetattr(write_fd, &ts) < 0) {
668 		error = errno;
669 		errno = error;
670 		atf_tc_fail("tcgetattr failed: %s", strerror(errno));
671 	}
672 	cfmakeraw(&ts);
673 	if (tcsetattr(write_fd, TCSANOW, &ts) < 0) {
674 		error = errno;
675 		errno = error;
676 		atf_tc_fail("tcsetattr failed: %s", strerror(errno));
677 	}
678 	aio_context_init(&ac, read_fd, write_fd, PTY_LEN);
679 
680 	aio_write_test(&ac, comp, sev);
681 	aio_read_test(&ac, comp, sev);
682 
683 	close(read_fd);
684 	close(write_fd);
685 }
686 
687 ATF_TC_WITHOUT_HEAD(pty_kq);
ATF_TC_BODY(pty_kq,tc)688 ATF_TC_BODY(pty_kq, tc)
689 {
690 	aio_pty_test(poll_kqueue, setup_kqueue());
691 }
692 
693 ATF_TC_WITHOUT_HEAD(pty_poll);
ATF_TC_BODY(pty_poll,tc)694 ATF_TC_BODY(pty_poll, tc)
695 {
696 	aio_pty_test(poll, NULL);
697 }
698 
699 ATF_TC_WITHOUT_HEAD(pty_signal);
ATF_TC_BODY(pty_signal,tc)700 ATF_TC_BODY(pty_signal, tc)
701 {
702 	aio_pty_test(poll_signaled, setup_signal());
703 }
704 
705 ATF_TC_WITHOUT_HEAD(pty_suspend);
ATF_TC_BODY(pty_suspend,tc)706 ATF_TC_BODY(pty_suspend, tc)
707 {
708 	aio_pty_test(suspend, NULL);
709 }
710 
711 ATF_TC_WITHOUT_HEAD(pty_thread);
ATF_TC_BODY(pty_thread,tc)712 ATF_TC_BODY(pty_thread, tc)
713 {
714 	aio_pty_test(poll_signaled, setup_thread());
715 }
716 
717 ATF_TC_WITHOUT_HEAD(pty_waitcomplete);
ATF_TC_BODY(pty_waitcomplete,tc)718 ATF_TC_BODY(pty_waitcomplete, tc)
719 {
720 	aio_pty_test(waitcomplete, NULL);
721 }
722 
723 #define	PIPE_LEN	256
724 static void
aio_pipe_test(completion comp,struct sigevent * sev)725 aio_pipe_test(completion comp, struct sigevent *sev)
726 {
727 	struct aio_context ac;
728 	int pipes[2];
729 
730 	ATF_REQUIRE_UNSAFE_AIO();
731 
732 	ATF_REQUIRE_MSG(pipe(pipes) != -1,
733 	    "pipe failed: %s", strerror(errno));
734 
735 	aio_context_init(&ac, pipes[0], pipes[1], PIPE_LEN);
736 	aio_write_test(&ac, comp, sev);
737 	aio_read_test(&ac, comp, sev);
738 
739 	close(pipes[0]);
740 	close(pipes[1]);
741 }
742 
743 ATF_TC_WITHOUT_HEAD(pipe_kq);
ATF_TC_BODY(pipe_kq,tc)744 ATF_TC_BODY(pipe_kq, tc)
745 {
746 	aio_pipe_test(poll_kqueue, setup_kqueue());
747 }
748 
749 ATF_TC_WITHOUT_HEAD(pipe_poll);
ATF_TC_BODY(pipe_poll,tc)750 ATF_TC_BODY(pipe_poll, tc)
751 {
752 	aio_pipe_test(poll, NULL);
753 }
754 
755 ATF_TC_WITHOUT_HEAD(pipe_signal);
ATF_TC_BODY(pipe_signal,tc)756 ATF_TC_BODY(pipe_signal, tc)
757 {
758 	aio_pipe_test(poll_signaled, setup_signal());
759 }
760 
761 ATF_TC_WITHOUT_HEAD(pipe_suspend);
ATF_TC_BODY(pipe_suspend,tc)762 ATF_TC_BODY(pipe_suspend, tc)
763 {
764 	aio_pipe_test(suspend, NULL);
765 }
766 
767 ATF_TC_WITHOUT_HEAD(pipe_thread);
ATF_TC_BODY(pipe_thread,tc)768 ATF_TC_BODY(pipe_thread, tc)
769 {
770 	aio_pipe_test(poll_signaled, setup_thread());
771 }
772 
773 ATF_TC_WITHOUT_HEAD(pipe_waitcomplete);
ATF_TC_BODY(pipe_waitcomplete,tc)774 ATF_TC_BODY(pipe_waitcomplete, tc)
775 {
776 	aio_pipe_test(waitcomplete, NULL);
777 }
778 
779 #define	DEVICE_IO_LEN	GLOBAL_MAX
780 #define	MDUNIT_LINK	"mdunit_link"
781 
782 static int
aio_md_setup(void)783 aio_md_setup(void)
784 {
785 	int error, fd, mdctl_fd, unit;
786 	char pathname[PATH_MAX];
787 	struct md_ioctl mdio;
788 	char buf[80];
789 
790 	mdctl_fd = open("/dev/" MDCTL_NAME, O_RDWR, 0);
791 	ATF_REQUIRE_MSG(mdctl_fd != -1,
792 	    "opening /dev/%s failed: %s", MDCTL_NAME, strerror(errno));
793 
794 	bzero(&mdio, sizeof(mdio));
795 	mdio.md_version = MDIOVERSION;
796 	mdio.md_type = MD_MALLOC;
797 	mdio.md_options = MD_AUTOUNIT | MD_COMPRESS;
798 	mdio.md_mediasize = 1024 * 1024;  /* 1 MB, enough for max_buf_aio up to 2047 */
799 	mdio.md_sectorsize = 512;
800 	strlcpy(buf, __func__, sizeof(buf));
801 	mdio.md_label = buf;
802 
803 	if (ioctl(mdctl_fd, MDIOCATTACH, &mdio) < 0) {
804 		error = errno;
805 		errno = error;
806 		atf_tc_fail("ioctl MDIOCATTACH failed: %s", strerror(errno));
807 	}
808 	close(mdctl_fd);
809 
810 	/* Store the md unit number in a symlink for future cleanup */
811 	unit = mdio.md_unit;
812 	snprintf(buf, sizeof(buf), "%d", unit);
813 	ATF_REQUIRE_EQ(0, symlink(buf, MDUNIT_LINK));
814 	snprintf(pathname, PATH_MAX, "/dev/md%d", unit);
815 	fd = open(pathname, O_RDWR);
816 	ATF_REQUIRE_MSG(fd != -1,
817 	    "opening %s failed: %s", pathname, strerror(errno));
818 
819 	return (fd);
820 }
821 
822 static void
aio_md_cleanup(void)823 aio_md_cleanup(void)
824 {
825 	struct md_ioctl mdio;
826 	int mdctl_fd, n, unit;
827 	char buf[80];
828 
829 	mdctl_fd = open("/dev/" MDCTL_NAME, O_RDWR, 0);
830 	if (mdctl_fd < 0) {
831 		fprintf(stderr, "opening /dev/%s failed: %s\n", MDCTL_NAME,
832 		    strerror(errno));
833 		return;
834 	}
835 	n = readlink(MDUNIT_LINK, buf, sizeof(buf) - 1);
836 	if (n > 0) {
837 		buf[n] = '\0';
838 		if (sscanf(buf, "%d", &unit) == 1 && unit >= 0) {
839 			bzero(&mdio, sizeof(mdio));
840 			mdio.md_version = MDIOVERSION;
841 			mdio.md_unit = unit;
842 			if (ioctl(mdctl_fd, MDIOCDETACH, &mdio) == -1) {
843 				fprintf(stderr,
844 				    "ioctl MDIOCDETACH unit %d failed: %s\n",
845 				    unit, strerror(errno));
846 			}
847 		}
848 	}
849 
850 	close(mdctl_fd);
851 }
852 
853 static void
aio_md_test(completion comp,struct sigevent * sev,bool vectored)854 aio_md_test(completion comp, struct sigevent *sev, bool vectored)
855 {
856 	struct aio_context ac;
857 	int fd;
858 
859 	fd = aio_md_setup();
860 	aio_context_init(&ac, fd, fd, DEVICE_IO_LEN);
861 	if (vectored) {
862 		aio_writev_test(&ac, comp, sev);
863 		aio_readv_test(&ac, comp, sev);
864 	} else {
865 		aio_write_test(&ac, comp, sev);
866 		aio_read_test(&ac, comp, sev);
867 	}
868 
869 	close(fd);
870 }
871 
872 ATF_TC_WITH_CLEANUP(md_kq);
ATF_TC_HEAD(md_kq,tc)873 ATF_TC_HEAD(md_kq, tc)
874 {
875 
876 	atf_tc_set_md_var(tc, "require.user", "root");
877 }
ATF_TC_BODY(md_kq,tc)878 ATF_TC_BODY(md_kq, tc)
879 {
880 	aio_md_test(poll_kqueue, setup_kqueue(), false);
881 }
ATF_TC_CLEANUP(md_kq,tc)882 ATF_TC_CLEANUP(md_kq, tc)
883 {
884 	aio_md_cleanup();
885 }
886 
887 ATF_TC_WITH_CLEANUP(md_poll);
ATF_TC_HEAD(md_poll,tc)888 ATF_TC_HEAD(md_poll, tc)
889 {
890 
891 	atf_tc_set_md_var(tc, "require.user", "root");
892 }
ATF_TC_BODY(md_poll,tc)893 ATF_TC_BODY(md_poll, tc)
894 {
895 	aio_md_test(poll, NULL, false);
896 }
ATF_TC_CLEANUP(md_poll,tc)897 ATF_TC_CLEANUP(md_poll, tc)
898 {
899 	aio_md_cleanup();
900 }
901 
902 ATF_TC_WITH_CLEANUP(md_signal);
ATF_TC_HEAD(md_signal,tc)903 ATF_TC_HEAD(md_signal, tc)
904 {
905 
906 	atf_tc_set_md_var(tc, "require.user", "root");
907 }
ATF_TC_BODY(md_signal,tc)908 ATF_TC_BODY(md_signal, tc)
909 {
910 	aio_md_test(poll_signaled, setup_signal(), false);
911 }
ATF_TC_CLEANUP(md_signal,tc)912 ATF_TC_CLEANUP(md_signal, tc)
913 {
914 	aio_md_cleanup();
915 }
916 
917 ATF_TC_WITH_CLEANUP(md_suspend);
ATF_TC_HEAD(md_suspend,tc)918 ATF_TC_HEAD(md_suspend, tc)
919 {
920 
921 	atf_tc_set_md_var(tc, "require.user", "root");
922 }
ATF_TC_BODY(md_suspend,tc)923 ATF_TC_BODY(md_suspend, tc)
924 {
925 	aio_md_test(suspend, NULL, false);
926 }
ATF_TC_CLEANUP(md_suspend,tc)927 ATF_TC_CLEANUP(md_suspend, tc)
928 {
929 	aio_md_cleanup();
930 }
931 
932 ATF_TC_WITH_CLEANUP(md_thread);
ATF_TC_HEAD(md_thread,tc)933 ATF_TC_HEAD(md_thread, tc)
934 {
935 
936 	atf_tc_set_md_var(tc, "require.user", "root");
937 }
ATF_TC_BODY(md_thread,tc)938 ATF_TC_BODY(md_thread, tc)
939 {
940 	aio_md_test(poll_signaled, setup_thread(), false);
941 }
ATF_TC_CLEANUP(md_thread,tc)942 ATF_TC_CLEANUP(md_thread, tc)
943 {
944 	aio_md_cleanup();
945 }
946 
947 ATF_TC_WITH_CLEANUP(md_waitcomplete);
ATF_TC_HEAD(md_waitcomplete,tc)948 ATF_TC_HEAD(md_waitcomplete, tc)
949 {
950 
951 	atf_tc_set_md_var(tc, "require.user", "root");
952 }
ATF_TC_BODY(md_waitcomplete,tc)953 ATF_TC_BODY(md_waitcomplete, tc)
954 {
955 	aio_md_test(waitcomplete, NULL, false);
956 }
ATF_TC_CLEANUP(md_waitcomplete,tc)957 ATF_TC_CLEANUP(md_waitcomplete, tc)
958 {
959 	aio_md_cleanup();
960 }
961 
962 #define	ZVOL_VDEV_PATHNAME	"test_vdev"
963 #define POOL_SIZE		(1 << 28)	/* 256 MB */
964 #define ZVOL_SIZE		"64m"
965 #define POOL_NAME		"aio_testpool"
966 #define ZVOL_NAME		"aio_testvol"
967 
968 static int
aio_zvol_setup(const char * unique)969 aio_zvol_setup(const char *unique)
970 {
971 	FILE *pidfile;
972 	int fd;
973 	pid_t pid;
974 	char vdev_name[160];
975 	char pool_name[80];
976 	char cmd[160];
977 	char zvol_name[160];
978 	char devname[160];
979 
980 	pid = getpid();
981 	snprintf(vdev_name, sizeof(vdev_name), "%s", ZVOL_VDEV_PATHNAME);
982 	snprintf(pool_name, sizeof(pool_name), "%s_%s.%d", POOL_NAME, unique,
983 	    pid);
984 	snprintf(zvol_name, sizeof(zvol_name), "%s/%s_%s", pool_name, ZVOL_NAME,
985 	    unique);
986 
987 	fd = open(vdev_name, O_RDWR | O_CREAT, 0600);
988 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
989 	ATF_REQUIRE_EQ_MSG(0,
990 	    ftruncate(fd, POOL_SIZE), "ftruncate failed: %s", strerror(errno));
991 	close(fd);
992 
993 	pidfile = fopen("pidfile", "w");
994 	ATF_REQUIRE_MSG(NULL != pidfile, "fopen: %s", strerror(errno));
995 	fprintf(pidfile, "%d", pid);
996 	fclose(pidfile);
997 
998 	snprintf(cmd, sizeof(cmd), "zpool create %s $PWD/%s", pool_name,
999 	    vdev_name);
1000 	ATF_REQUIRE_EQ_MSG(0, system(cmd),
1001 	    "zpool create failed: %s", strerror(errno));
1002 	snprintf(cmd, sizeof(cmd),
1003 	    "zfs create -o volblocksize=8192 -o volmode=dev -V %s %s",
1004 	    ZVOL_SIZE, zvol_name);
1005 	ATF_REQUIRE_EQ_MSG(0, system(cmd),
1006 	    "zfs create failed: %s", strerror(errno));
1007 
1008 	snprintf(devname, sizeof(devname), "/dev/zvol/%s", zvol_name);
1009 	do {
1010 		fd = open(devname, O_RDWR);
1011 	} while (fd == -1 && errno == EINTR);
1012 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1013 	return (fd);
1014 }
1015 
1016 static void
aio_zvol_cleanup(const char * unique)1017 aio_zvol_cleanup(const char *unique)
1018 {
1019 	FILE *pidfile;
1020 	pid_t testpid;
1021 	char cmd[160];
1022 
1023 	pidfile = fopen("pidfile", "r");
1024 	if (pidfile == NULL && errno == ENOENT) {
1025 		/* Setup probably failed */
1026 		return;
1027 	}
1028 	ATF_REQUIRE_MSG(NULL != pidfile, "fopen: %s", strerror(errno));
1029 	ATF_REQUIRE_EQ(1, fscanf(pidfile, "%d", &testpid));
1030 	fclose(pidfile);
1031 
1032 	snprintf(cmd, sizeof(cmd), "zpool destroy %s_%s.%d", POOL_NAME, unique,
1033 	    testpid);
1034 	system(cmd);
1035 }
1036 
1037 
1038 ATF_TC_WITHOUT_HEAD(aio_large_read_test);
ATF_TC_BODY(aio_large_read_test,tc)1039 ATF_TC_BODY(aio_large_read_test, tc)
1040 {
1041 	struct aiocb cb, *cbp;
1042 	ssize_t nread;
1043 	size_t len;
1044 	int fd;
1045 #ifdef __LP64__
1046 	int clamped;
1047 #endif
1048 
1049 	ATF_REQUIRE_UNSAFE_AIO();
1050 
1051 #ifdef __LP64__
1052 	len = sizeof(clamped);
1053 	if (sysctlbyname("debug.iosize_max_clamp", &clamped, &len, NULL, 0) ==
1054 	    -1)
1055 		atf_libc_error(errno, "Failed to read debug.iosize_max_clamp");
1056 #endif
1057 
1058 	/* Determine the maximum supported read(2) size. */
1059 	len = SSIZE_MAX;
1060 #ifdef __LP64__
1061 	if (clamped)
1062 		len = INT_MAX;
1063 #endif
1064 
1065 	fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600);
1066 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1067 
1068 	unlink(FILE_PATHNAME);
1069 
1070 	memset(&cb, 0, sizeof(cb));
1071 	cb.aio_nbytes = len;
1072 	cb.aio_fildes = fd;
1073 	cb.aio_buf = NULL;
1074 	if (aio_read(&cb) == -1)
1075 		atf_tc_fail("aio_read() of maximum read size failed: %s",
1076 		    strerror(errno));
1077 
1078 	nread = aio_waitcomplete(&cbp, NULL);
1079 	if (nread == -1)
1080 		atf_tc_fail("aio_waitcomplete() failed: %s", strerror(errno));
1081 	if (nread != 0)
1082 		atf_tc_fail("aio_read() from empty file returned data: %zd",
1083 		    nread);
1084 
1085 	memset(&cb, 0, sizeof(cb));
1086 	cb.aio_nbytes = len + 1;
1087 	cb.aio_fildes = fd;
1088 	cb.aio_buf = NULL;
1089 	if (aio_read(&cb) == -1) {
1090 		if (errno == EINVAL)
1091 			goto finished;
1092 		atf_tc_fail("aio_read() of too large read size failed: %s",
1093 		    strerror(errno));
1094 	}
1095 
1096 	nread = aio_waitcomplete(&cbp, NULL);
1097 	if (nread == -1) {
1098 		if (errno == EINVAL)
1099 			goto finished;
1100 		atf_tc_fail("aio_waitcomplete() failed: %s", strerror(errno));
1101 	}
1102 	atf_tc_fail("aio_read() of too large read size returned: %zd", nread);
1103 
1104 finished:
1105 	close(fd);
1106 }
1107 
1108 /*
1109  * This tests for a bug where arriving socket data can wakeup multiple
1110  * AIO read requests resulting in an uncancellable request.
1111  */
1112 ATF_TC_WITHOUT_HEAD(aio_socket_two_reads);
ATF_TC_BODY(aio_socket_two_reads,tc)1113 ATF_TC_BODY(aio_socket_two_reads, tc)
1114 {
1115 	struct ioreq {
1116 		struct aiocb iocb;
1117 		char buffer[1024];
1118 	} ioreq[2];
1119 	struct aiocb *iocb;
1120 	unsigned i;
1121 	int s[2];
1122 	char c;
1123 
1124 #if __FreeBSD_version < 1100101
1125 	aft_tc_skip("kernel version %d is too old (%d required)",
1126 	    __FreeBSD_version, 1100101);
1127 #endif
1128 
1129 	ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1);
1130 
1131 	/* Queue two read requests. */
1132 	memset(&ioreq, 0, sizeof(ioreq));
1133 	for (i = 0; i < nitems(ioreq); i++) {
1134 		ioreq[i].iocb.aio_nbytes = sizeof(ioreq[i].buffer);
1135 		ioreq[i].iocb.aio_fildes = s[0];
1136 		ioreq[i].iocb.aio_buf = ioreq[i].buffer;
1137 		ATF_REQUIRE(aio_read(&ioreq[i].iocb) == 0);
1138 	}
1139 
1140 	/* Send a single byte.  This should complete one request. */
1141 	c = 0xc3;
1142 	ATF_REQUIRE(write(s[1], &c, sizeof(c)) == 1);
1143 
1144 	ATF_REQUIRE(aio_waitcomplete(&iocb, NULL) == 1);
1145 
1146 	/* Determine which request completed and verify the data was read. */
1147 	if (iocb == &ioreq[0].iocb)
1148 		i = 0;
1149 	else
1150 		i = 1;
1151 	ATF_REQUIRE(ioreq[i].buffer[0] == c);
1152 
1153 	i ^= 1;
1154 
1155 	/*
1156 	 * Try to cancel the other request.  On broken systems this
1157 	 * will fail and the process will hang on exit.
1158 	 */
1159 	ATF_REQUIRE(aio_error(&ioreq[i].iocb) == EINPROGRESS);
1160 	ATF_REQUIRE(aio_cancel(s[0], &ioreq[i].iocb) == AIO_CANCELED);
1161 
1162 	close(s[1]);
1163 	close(s[0]);
1164 }
1165 
1166 static void
aio_socket_blocking_short_write_test(bool vectored)1167 aio_socket_blocking_short_write_test(bool vectored)
1168 {
1169 	struct aiocb iocb, *iocbp;
1170 	struct iovec iov[2];
1171 	char *buffer[2];
1172 	ssize_t done, r;
1173 	int buffer_size, sb_size;
1174 	socklen_t len;
1175 	int s[2];
1176 
1177 	ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1);
1178 
1179 	len = sizeof(sb_size);
1180 	ATF_REQUIRE(getsockopt(s[0], SOL_SOCKET, SO_RCVBUF, &sb_size, &len) !=
1181 	    -1);
1182 	ATF_REQUIRE(len == sizeof(sb_size));
1183 	buffer_size = sb_size;
1184 
1185 	ATF_REQUIRE(getsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &sb_size, &len) !=
1186 	    -1);
1187 	ATF_REQUIRE(len == sizeof(sb_size));
1188 	if (sb_size > buffer_size)
1189 		buffer_size = sb_size;
1190 
1191 	/*
1192 	 * Use twice the size of the MAX(receive buffer, send buffer)
1193 	 * to ensure that the write is split up into multiple writes
1194 	 * internally.
1195 	 */
1196 	buffer_size *= 2;
1197 
1198 	buffer[0] = malloc(buffer_size);
1199 	ATF_REQUIRE(buffer[0] != NULL);
1200 	buffer[1] = malloc(buffer_size);
1201 	ATF_REQUIRE(buffer[1] != NULL);
1202 
1203 	srandomdev();
1204 	aio_fill_buffer(buffer[1], buffer_size, random());
1205 
1206 	memset(&iocb, 0, sizeof(iocb));
1207 	iocb.aio_fildes = s[1];
1208 	if (vectored) {
1209 		iov[0].iov_base = buffer[1];
1210 		iov[0].iov_len = buffer_size / 2 + 1;
1211 		iov[1].iov_base = buffer[1] + buffer_size / 2 + 1;
1212 		iov[1].iov_len = buffer_size / 2 - 1;
1213 		iocb.aio_iov = iov;
1214 		iocb.aio_iovcnt = 2;
1215 		r = aio_writev(&iocb);
1216 		ATF_CHECK_EQ_MSG(0, r, "aio_writev returned %zd", r);
1217 	} else {
1218 		iocb.aio_buf = buffer[1];
1219 		iocb.aio_nbytes = buffer_size;
1220 		r = aio_write(&iocb);
1221 		ATF_CHECK_EQ_MSG(0, r, "aio_writev returned %zd", r);
1222 	}
1223 
1224 	done = recv(s[0], buffer[0], buffer_size, MSG_WAITALL);
1225 	ATF_REQUIRE(done == buffer_size);
1226 
1227 	done = aio_waitcomplete(&iocbp, NULL);
1228 	ATF_REQUIRE(iocbp == &iocb);
1229 	ATF_REQUIRE(done == buffer_size);
1230 
1231 	ATF_REQUIRE(memcmp(buffer[0], buffer[1], buffer_size) == 0);
1232 
1233 	close(s[1]);
1234 	close(s[0]);
1235 }
1236 
1237 /*
1238  * This test ensures that aio_write() on a blocking socket of a "large"
1239  * buffer does not return a short completion.
1240  */
1241 ATF_TC_WITHOUT_HEAD(aio_socket_blocking_short_write);
ATF_TC_BODY(aio_socket_blocking_short_write,tc)1242 ATF_TC_BODY(aio_socket_blocking_short_write, tc)
1243 {
1244 	aio_socket_blocking_short_write_test(false);
1245 }
1246 
1247 /*
1248  * Like aio_socket_blocking_short_write, but also tests that partially
1249  * completed vectored sends can be retried correctly.
1250  */
1251 ATF_TC_WITHOUT_HEAD(aio_socket_blocking_short_write_vectored);
ATF_TC_BODY(aio_socket_blocking_short_write_vectored,tc)1252 ATF_TC_BODY(aio_socket_blocking_short_write_vectored, tc)
1253 {
1254 	aio_socket_blocking_short_write_test(true);
1255 }
1256 
1257 /*
1258  * Verify that AIO requests fail when applied to a listening socket.
1259  */
1260 ATF_TC_WITHOUT_HEAD(aio_socket_listen_fail);
ATF_TC_BODY(aio_socket_listen_fail,tc)1261 ATF_TC_BODY(aio_socket_listen_fail, tc)
1262 {
1263 	struct aiocb iocb;
1264 	struct sockaddr_un sun;
1265 	char buf[16];
1266 	int s;
1267 
1268 	s = socket(AF_LOCAL, SOCK_STREAM, 0);
1269 	ATF_REQUIRE(s != -1);
1270 
1271 	memset(&sun, 0, sizeof(sun));
1272 	snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", "listen.XXXXXX");
1273 	mktemp(sun.sun_path);
1274 	sun.sun_family = AF_LOCAL;
1275 	sun.sun_len = SUN_LEN(&sun);
1276 
1277 	ATF_REQUIRE(bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) == 0);
1278 	ATF_REQUIRE(listen(s, 5) == 0);
1279 
1280 	memset(buf, 0, sizeof(buf));
1281 	memset(&iocb, 0, sizeof(iocb));
1282 	iocb.aio_fildes = s;
1283 	iocb.aio_buf = buf;
1284 	iocb.aio_nbytes = sizeof(buf);
1285 
1286 	ATF_REQUIRE_ERRNO(EINVAL, aio_read(&iocb) == -1);
1287 	ATF_REQUIRE_ERRNO(EINVAL, aio_write(&iocb) == -1);
1288 
1289 	ATF_REQUIRE(unlink(sun.sun_path) == 0);
1290 	close(s);
1291 }
1292 
1293 /*
1294  * Verify that listen(2) fails if a socket has pending AIO requests.
1295  */
1296 ATF_TC_WITHOUT_HEAD(aio_socket_listen_pending);
ATF_TC_BODY(aio_socket_listen_pending,tc)1297 ATF_TC_BODY(aio_socket_listen_pending, tc)
1298 {
1299 	struct aiocb iocb;
1300 	struct sockaddr_un sun;
1301 	char buf[16];
1302 	int s;
1303 
1304 	s = socket(AF_LOCAL, SOCK_STREAM, 0);
1305 	ATF_REQUIRE(s != -1);
1306 
1307 	memset(&sun, 0, sizeof(sun));
1308 	snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", "listen.XXXXXX");
1309 	mktemp(sun.sun_path);
1310 	sun.sun_family = AF_LOCAL;
1311 	sun.sun_len = SUN_LEN(&sun);
1312 
1313 	ATF_REQUIRE(bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) == 0);
1314 
1315 	memset(buf, 0, sizeof(buf));
1316 	memset(&iocb, 0, sizeof(iocb));
1317 	iocb.aio_fildes = s;
1318 	iocb.aio_buf = buf;
1319 	iocb.aio_nbytes = sizeof(buf);
1320 	ATF_REQUIRE(aio_read(&iocb) == 0);
1321 
1322 	ATF_REQUIRE_ERRNO(EINVAL, listen(s, 5) == -1);
1323 
1324 	ATF_REQUIRE(aio_cancel(s, &iocb) != -1);
1325 
1326 	ATF_REQUIRE(unlink(sun.sun_path) == 0);
1327 	close(s);
1328 }
1329 
1330 /*
1331  * This test verifies that cancelling a partially completed socket write
1332  * returns a short write rather than ECANCELED.
1333  */
1334 ATF_TC_WITHOUT_HEAD(aio_socket_short_write_cancel);
ATF_TC_BODY(aio_socket_short_write_cancel,tc)1335 ATF_TC_BODY(aio_socket_short_write_cancel, tc)
1336 {
1337 	struct aiocb iocb, *iocbp;
1338 	char *buffer[2];
1339 	ssize_t done;
1340 	int buffer_size, sb_size;
1341 	socklen_t len;
1342 	int s[2];
1343 
1344 	ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1);
1345 
1346 	len = sizeof(sb_size);
1347 	ATF_REQUIRE(getsockopt(s[0], SOL_SOCKET, SO_RCVBUF, &sb_size, &len) !=
1348 	    -1);
1349 	ATF_REQUIRE(len == sizeof(sb_size));
1350 	buffer_size = sb_size;
1351 
1352 	ATF_REQUIRE(getsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &sb_size, &len) !=
1353 	    -1);
1354 	ATF_REQUIRE(len == sizeof(sb_size));
1355 	if (sb_size > buffer_size)
1356 		buffer_size = sb_size;
1357 
1358 	/*
1359 	 * Use three times the size of the MAX(receive buffer, send
1360 	 * buffer) for the write to ensure that the write is split up
1361 	 * into multiple writes internally.  The recv() ensures that
1362 	 * the write has partially completed, but a remaining size of
1363 	 * two buffers should ensure that the write has not completed
1364 	 * fully when it is cancelled.
1365 	 */
1366 	buffer[0] = malloc(buffer_size);
1367 	ATF_REQUIRE(buffer[0] != NULL);
1368 	buffer[1] = malloc(buffer_size * 3);
1369 	ATF_REQUIRE(buffer[1] != NULL);
1370 
1371 	srandomdev();
1372 	aio_fill_buffer(buffer[1], buffer_size * 3, random());
1373 
1374 	memset(&iocb, 0, sizeof(iocb));
1375 	iocb.aio_fildes = s[1];
1376 	iocb.aio_buf = buffer[1];
1377 	iocb.aio_nbytes = buffer_size * 3;
1378 	ATF_REQUIRE(aio_write(&iocb) == 0);
1379 
1380 	done = recv(s[0], buffer[0], buffer_size, MSG_WAITALL);
1381 	ATF_REQUIRE(done == buffer_size);
1382 
1383 	ATF_REQUIRE(aio_error(&iocb) == EINPROGRESS);
1384 	ATF_REQUIRE(aio_cancel(s[1], &iocb) == AIO_NOTCANCELED);
1385 
1386 	done = aio_waitcomplete(&iocbp, NULL);
1387 	ATF_REQUIRE(iocbp == &iocb);
1388 	ATF_REQUIRE(done >= buffer_size && done <= buffer_size * 2);
1389 
1390 	ATF_REQUIRE(memcmp(buffer[0], buffer[1], buffer_size) == 0);
1391 
1392 	close(s[1]);
1393 	close(s[0]);
1394 }
1395 
1396 /*
1397  * Test handling of aio_read() and aio_write() on shut-down sockets.
1398  */
1399 ATF_TC_WITHOUT_HEAD(aio_socket_shutdown);
ATF_TC_BODY(aio_socket_shutdown,tc)1400 ATF_TC_BODY(aio_socket_shutdown, tc)
1401 {
1402 	struct aiocb iocb;
1403 	sigset_t set;
1404 	char *buffer;
1405 	ssize_t len;
1406 	size_t bsz;
1407 	int error, s[2];
1408 
1409 	ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1);
1410 
1411 	bsz = 1024;
1412 	buffer = malloc(bsz);
1413 	memset(buffer, 0, bsz);
1414 
1415 	/* Put some data in s[0]'s recv buffer. */
1416 	ATF_REQUIRE(send(s[1], buffer, bsz, 0) == (ssize_t)bsz);
1417 
1418 	/* No more reading from s[0]. */
1419 	ATF_REQUIRE(shutdown(s[0], SHUT_RD) != -1);
1420 
1421 	ATF_REQUIRE(buffer != NULL);
1422 
1423 	memset(&iocb, 0, sizeof(iocb));
1424 	iocb.aio_fildes = s[0];
1425 	iocb.aio_buf = buffer;
1426 	iocb.aio_nbytes = bsz;
1427 	ATF_REQUIRE(aio_read(&iocb) == 0);
1428 
1429 	/* Expect to see zero bytes, analogous to recv(2). */
1430 	while ((error = aio_error(&iocb)) == EINPROGRESS)
1431 		usleep(25000);
1432 	ATF_REQUIRE_MSG(error == 0, "aio_error() returned %d", error);
1433 	len = aio_return(&iocb);
1434 	ATF_REQUIRE_MSG(len == 0, "read job returned %zd bytes", len);
1435 
1436 	/* No more writing to s[1]. */
1437 	ATF_REQUIRE(shutdown(s[1], SHUT_WR) != -1);
1438 
1439 	/* Block SIGPIPE so that we can detect the error in-band. */
1440 	sigemptyset(&set);
1441 	sigaddset(&set, SIGPIPE);
1442 	ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) == 0);
1443 
1444 	memset(&iocb, 0, sizeof(iocb));
1445 	iocb.aio_fildes = s[1];
1446 	iocb.aio_buf = buffer;
1447 	iocb.aio_nbytes = bsz;
1448 	ATF_REQUIRE(aio_write(&iocb) == 0);
1449 
1450 	/* Expect an error, analogous to send(2). */
1451 	while ((error = aio_error(&iocb)) == EINPROGRESS)
1452 		usleep(25000);
1453 	ATF_REQUIRE_MSG(error == EPIPE, "aio_error() returned %d", error);
1454 
1455 	ATF_REQUIRE(close(s[0]) != -1);
1456 	ATF_REQUIRE(close(s[1]) != -1);
1457 	free(buffer);
1458 }
1459 
1460 /*
1461  * test aio_fsync's behavior with bad inputs
1462  */
1463 ATF_TC_WITHOUT_HEAD(aio_fsync_errors);
ATF_TC_BODY(aio_fsync_errors,tc)1464 ATF_TC_BODY(aio_fsync_errors, tc)
1465 {
1466 	int fd;
1467 	struct aiocb iocb;
1468 
1469 	ATF_REQUIRE_UNSAFE_AIO();
1470 
1471 	fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600);
1472 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1473 	unlink(FILE_PATHNAME);
1474 
1475 	/* aio_fsync should return EINVAL unless op is O_SYNC or O_DSYNC */
1476 	memset(&iocb, 0, sizeof(iocb));
1477 	iocb.aio_fildes = fd;
1478 	ATF_CHECK_EQ(-1, aio_fsync(666, &iocb));
1479 	ATF_CHECK_EQ(EINVAL, errno);
1480 
1481 	/* aio_fsync should return EBADF if fd is not a valid descriptor */
1482 	memset(&iocb, 0, sizeof(iocb));
1483 	iocb.aio_fildes = 666;
1484 	ATF_CHECK_EQ(-1, aio_fsync(O_SYNC, &iocb));
1485 	ATF_CHECK_EQ(EBADF, errno);
1486 
1487 	/* aio_fsync should return EINVAL if sigev_notify is invalid */
1488 	memset(&iocb, 0, sizeof(iocb));
1489 	iocb.aio_fildes = fd;
1490 	iocb.aio_sigevent.sigev_notify = 666;
1491 	ATF_CHECK_EQ(-1, aio_fsync(666, &iocb));
1492 	ATF_CHECK_EQ(EINVAL, errno);
1493 }
1494 
1495 /*
1496  * This test just performs a basic test of aio_fsync().
1497  */
1498 static void
aio_fsync_test(int op)1499 aio_fsync_test(int op)
1500 {
1501 	struct aiocb synccb, *iocbp;
1502 	struct {
1503 		struct aiocb iocb;
1504 		bool done;
1505 		char *buffer;
1506 	} buffers[16];
1507 	struct stat sb;
1508 	ssize_t rval;
1509 	unsigned i;
1510 	int fd;
1511 
1512 	ATF_REQUIRE_UNSAFE_AIO();
1513 
1514 	fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600);
1515 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1516 	unlink(FILE_PATHNAME);
1517 
1518 	ATF_REQUIRE(fstat(fd, &sb) == 0);
1519 	ATF_REQUIRE(sb.st_blksize != 0);
1520 	ATF_REQUIRE(ftruncate(fd, sb.st_blksize * nitems(buffers)) == 0);
1521 
1522 	/*
1523 	 * Queue several asynchronous write requests.  Hopefully this
1524 	 * forces the aio_fsync() request to be deferred.  There is no
1525 	 * reliable way to guarantee that however.
1526 	 */
1527 	srandomdev();
1528 	for (i = 0; i < nitems(buffers); i++) {
1529 		buffers[i].done = false;
1530 		memset(&buffers[i].iocb, 0, sizeof(buffers[i].iocb));
1531 		buffers[i].buffer = malloc(sb.st_blksize);
1532 		aio_fill_buffer(buffers[i].buffer, sb.st_blksize, random());
1533 		buffers[i].iocb.aio_fildes = fd;
1534 		buffers[i].iocb.aio_buf = buffers[i].buffer;
1535 		buffers[i].iocb.aio_nbytes = sb.st_blksize;
1536 		buffers[i].iocb.aio_offset = sb.st_blksize * i;
1537 		ATF_REQUIRE(aio_write(&buffers[i].iocb) == 0);
1538 	}
1539 
1540 	/* Queue the aio_fsync request. */
1541 	memset(&synccb, 0, sizeof(synccb));
1542 	synccb.aio_fildes = fd;
1543 	ATF_REQUIRE(aio_fsync(op, &synccb) == 0);
1544 
1545 	/* Wait for requests to complete. */
1546 	for (;;) {
1547 	next:
1548 		rval = aio_waitcomplete(&iocbp, NULL);
1549 		ATF_REQUIRE(iocbp != NULL);
1550 		if (iocbp == &synccb) {
1551 			ATF_REQUIRE(rval == 0);
1552 			break;
1553 		}
1554 
1555 		for (i = 0; i < nitems(buffers); i++) {
1556 			if (iocbp == &buffers[i].iocb) {
1557 				ATF_REQUIRE(buffers[i].done == false);
1558 				ATF_REQUIRE(rval == sb.st_blksize);
1559 				buffers[i].done = true;
1560 				goto next;
1561 			}
1562 		}
1563 
1564 		ATF_REQUIRE_MSG(false, "unmatched AIO request");
1565 	}
1566 
1567 	for (i = 0; i < nitems(buffers); i++)
1568 		ATF_REQUIRE_MSG(buffers[i].done,
1569 		    "AIO request %u did not complete", i);
1570 
1571 	close(fd);
1572 }
1573 
1574 ATF_TC_WITHOUT_HEAD(aio_fsync_sync_test);
ATF_TC_BODY(aio_fsync_sync_test,tc)1575 ATF_TC_BODY(aio_fsync_sync_test, tc)
1576 {
1577 	aio_fsync_test(O_SYNC);
1578 }
1579 
1580 ATF_TC_WITHOUT_HEAD(aio_fsync_dsync_test);
ATF_TC_BODY(aio_fsync_dsync_test,tc)1581 ATF_TC_BODY(aio_fsync_dsync_test, tc)
1582 {
1583 	aio_fsync_test(O_DSYNC);
1584 }
1585 
1586 /*
1587  * We shouldn't be able to DoS the system by setting iov_len to an insane
1588  * value
1589  */
1590 ATF_TC_WITHOUT_HEAD(aio_writev_dos_iov_len);
ATF_TC_BODY(aio_writev_dos_iov_len,tc)1591 ATF_TC_BODY(aio_writev_dos_iov_len, tc)
1592 {
1593 	struct aiocb aio;
1594 	const struct aiocb *const iocbs[] = {&aio};
1595 	const char *wbuf = "Hello, world!";
1596 	struct iovec iov[1];
1597 	ssize_t r;
1598 	int fd;
1599 
1600 	ATF_REQUIRE_UNSAFE_AIO();
1601 
1602 	fd = open("testfile", O_RDWR | O_CREAT, 0600);
1603 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1604 
1605 	iov[0].iov_base = __DECONST(void*, wbuf);
1606 	iov[0].iov_len = 1 << 30;
1607 	bzero(&aio, sizeof(aio));
1608 	aio.aio_fildes = fd;
1609 	aio.aio_offset = 0;
1610 	aio.aio_iov = iov;
1611 	aio.aio_iovcnt = 1;
1612 
1613 	r = aio_writev(&aio);
1614 	ATF_CHECK_EQ_MSG(0, r, "aio_writev returned %zd", r);
1615 	ATF_REQUIRE_EQ(0, aio_suspend(iocbs, 1, NULL));
1616 	r = aio_return(&aio);
1617 	ATF_CHECK_EQ_MSG(-1, r, "aio_return returned %zd", r);
1618 	ATF_CHECK_MSG(errno == EFAULT || errno == EINVAL,
1619 	    "aio_writev: %s", strerror(errno));
1620 
1621 	close(fd);
1622 }
1623 
1624 /*
1625  * We shouldn't be able to DoS the system by setting aio_iovcnt to an insane
1626  * value
1627  */
1628 ATF_TC_WITHOUT_HEAD(aio_writev_dos_iovcnt);
ATF_TC_BODY(aio_writev_dos_iovcnt,tc)1629 ATF_TC_BODY(aio_writev_dos_iovcnt, tc)
1630 {
1631 	struct aiocb aio;
1632 	const char *wbuf = "Hello, world!";
1633 	struct iovec iov[1];
1634 	ssize_t len;
1635 	int fd;
1636 
1637 	ATF_REQUIRE_UNSAFE_AIO();
1638 
1639 	fd = open("testfile", O_RDWR | O_CREAT, 0600);
1640 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1641 
1642 	len = strlen(wbuf);
1643 	iov[0].iov_base = __DECONST(void*, wbuf);
1644 	iov[0].iov_len = len;
1645 	bzero(&aio, sizeof(aio));
1646 	aio.aio_fildes = fd;
1647 	aio.aio_offset = 0;
1648 	aio.aio_iov = iov;
1649 	aio.aio_iovcnt = 1 << 30;
1650 
1651 	ATF_REQUIRE_EQ(-1, aio_writev(&aio));
1652 	ATF_CHECK_EQ(EINVAL, errno);
1653 
1654 	close(fd);
1655 }
1656 
1657 ATF_TC_WITH_CLEANUP(aio_writev_efault);
ATF_TC_HEAD(aio_writev_efault,tc)1658 ATF_TC_HEAD(aio_writev_efault, tc)
1659 {
1660 	atf_tc_set_md_var(tc, "descr",
1661 	    "Vectored AIO should gracefully handle invalid addresses");
1662 	atf_tc_set_md_var(tc, "require.user", "root");
1663 }
ATF_TC_BODY(aio_writev_efault,tc)1664 ATF_TC_BODY(aio_writev_efault, tc)
1665 {
1666 	struct aiocb aio;
1667 	ssize_t buflen;
1668 	char *buffer;
1669 	void *unmapped;
1670 	struct iovec iov[2];
1671 	long seed;
1672 	int fd;
1673 
1674 	ATF_REQUIRE_UNSAFE_AIO();
1675 
1676 	fd = aio_md_setup();
1677 
1678 	unmapped = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_GUARD, -1, 0);
1679 	ATF_REQUIRE(unmapped != MAP_FAILED);
1680 
1681 	seed = random();
1682 	buflen = 4096;
1683 	buffer = malloc(buflen);
1684 	aio_fill_buffer(buffer, buflen, seed);
1685 	iov[0].iov_base = buffer;
1686 	iov[0].iov_len = buflen;
1687 	iov[1].iov_base = (void*)unmapped;	/* Invalid! */
1688 	iov[1].iov_len = buflen;
1689 	bzero(&aio, sizeof(aio));
1690 	aio.aio_fildes = fd;
1691 	aio.aio_offset = 0;
1692 	aio.aio_iov = iov;
1693 	aio.aio_iovcnt = nitems(iov);
1694 
1695 	ATF_REQUIRE_EQ(-1, aio_writev(&aio));
1696 	ATF_CHECK_EQ(EFAULT, errno);
1697 
1698 	close(fd);
1699 }
ATF_TC_CLEANUP(aio_writev_efault,tc)1700 ATF_TC_CLEANUP(aio_writev_efault, tc)
1701 {
1702 	aio_md_cleanup();
1703 }
1704 
1705 ATF_TC_WITHOUT_HEAD(aio_writev_empty_file_poll);
ATF_TC_BODY(aio_writev_empty_file_poll,tc)1706 ATF_TC_BODY(aio_writev_empty_file_poll, tc)
1707 {
1708 	struct aiocb aio;
1709 	int fd;
1710 
1711 	ATF_REQUIRE_UNSAFE_AIO();
1712 
1713 	fd = open("testfile", O_RDWR | O_CREAT, 0600);
1714 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1715 
1716 	bzero(&aio, sizeof(aio));
1717 	aio.aio_fildes = fd;
1718 	aio.aio_offset = 0;
1719 	aio.aio_iovcnt = 0;
1720 
1721 	ATF_REQUIRE_EQ(0, aio_writev(&aio));
1722 	ATF_REQUIRE_EQ(0, suspend(&aio));
1723 
1724 	close(fd);
1725 }
1726 
1727 ATF_TC_WITHOUT_HEAD(aio_writev_empty_file_signal);
ATF_TC_BODY(aio_writev_empty_file_signal,tc)1728 ATF_TC_BODY(aio_writev_empty_file_signal, tc)
1729 {
1730 	struct aiocb aio;
1731 	int fd;
1732 
1733 	ATF_REQUIRE_UNSAFE_AIO();
1734 
1735 	fd = open("testfile", O_RDWR | O_CREAT, 0600);
1736 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1737 
1738 	bzero(&aio, sizeof(aio));
1739 	aio.aio_fildes = fd;
1740 	aio.aio_offset = 0;
1741 	aio.aio_iovcnt = 0;
1742 	aio.aio_sigevent = *setup_signal();
1743 
1744 	ATF_REQUIRE_EQ(0, aio_writev(&aio));
1745 	ATF_REQUIRE_EQ(0, poll_signaled(&aio));
1746 
1747 	close(fd);
1748 }
1749 
1750 /*
1751  * Use an aiocb with kqueue and EV_ONESHOT.  kqueue should deliver the event
1752  * only once, even if the user doesn't promptly call aio_return.
1753  */
1754 ATF_TC_WITHOUT_HEAD(ev_oneshot);
ATF_TC_BODY(ev_oneshot,tc)1755 ATF_TC_BODY(ev_oneshot, tc)
1756 {
1757 	int fd, kq, nevents;
1758 	struct aiocb iocb;
1759 	struct kevent events[1];
1760 	struct timespec timeout;
1761 
1762 	kq = kqueue();
1763 	ATF_REQUIRE(kq >= 0);
1764 
1765 	fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600);
1766 	ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
1767 
1768 	memset(&iocb, 0, sizeof(iocb));
1769 	iocb.aio_fildes = fd;
1770 	iocb.aio_sigevent.sigev_notify_kqueue = kq;
1771 	iocb.aio_sigevent.sigev_value.sival_ptr = (void*)0xdeadbeef;
1772 	iocb.aio_sigevent.sigev_notify_kevent_flags = EV_ONESHOT;
1773 	iocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
1774 
1775 	ATF_CHECK_EQ(0, aio_fsync(O_SYNC, &iocb));
1776 
1777 	nevents = kevent(kq, NULL, 0, events, 1, NULL);
1778 	ATF_CHECK_EQ(1, nevents);
1779 	ATF_CHECK_EQ(events[0].ident, (uintptr_t) &iocb);
1780 	ATF_CHECK_EQ(events[0].filter, EVFILT_AIO);
1781 	ATF_CHECK_EQ(events[0].flags, EV_EOF | EV_ONESHOT);
1782 	ATF_CHECK_EQ(events[0].fflags, 0);
1783 	ATF_CHECK_EQ(events[0].data, 0);
1784 	ATF_CHECK_EQ((uintptr_t)events[0].udata, 0xdeadbeef);
1785 
1786 	/*
1787 	 * Even though we haven't called aio_return, kevent will not return the
1788 	 * event again due to EV_ONESHOT.
1789 	 */
1790 	timeout.tv_sec = 0;
1791 	timeout.tv_nsec = 100000000;
1792 	nevents = kevent(kq, NULL, 0, events, 1, &timeout);
1793 	ATF_CHECK_EQ(0, nevents);
1794 
1795 	ATF_CHECK_EQ(0, aio_return(&iocb));
1796 	close(fd);
1797 	close(kq);
1798 }
1799 
1800 
1801 // aio_writev and aio_readv should still work even if the iovcnt is greater
1802 // than the number of buffered AIO operations permitted per process.
1803 ATF_TC_WITH_CLEANUP(vectored_big_iovcnt);
ATF_TC_HEAD(vectored_big_iovcnt,tc)1804 ATF_TC_HEAD(vectored_big_iovcnt, tc)
1805 {
1806 	atf_tc_set_md_var(tc, "descr",
1807 	    "Vectored AIO should still work even if the iovcnt is greater than "
1808 	    "the number of buffered AIO operations permitted by the process");
1809 	atf_tc_set_md_var(tc, "require.user", "root");
1810 }
ATF_TC_BODY(vectored_big_iovcnt,tc)1811 ATF_TC_BODY(vectored_big_iovcnt, tc)
1812 {
1813 	struct aiocb aio;
1814 	struct iovec *iov;
1815 	ssize_t len, buflen;
1816 	char *buffer;
1817 	const char *oid = "vfs.aio.max_buf_aio";
1818 	long seed;
1819 	int max_buf_aio;
1820 	int fd, i;
1821 	ssize_t sysctl_len = sizeof(max_buf_aio);
1822 
1823 	ATF_REQUIRE_UNSAFE_AIO();
1824 
1825 	if (sysctlbyname(oid, &max_buf_aio, &sysctl_len, NULL, 0) == -1)
1826 		atf_libc_error(errno, "Failed to read %s", oid);
1827 
1828 	seed = random();
1829 	buflen = 512 * (max_buf_aio + 1);
1830 	buffer = malloc(buflen);
1831 	aio_fill_buffer(buffer, buflen, seed);
1832 	iov = calloc(max_buf_aio + 1, sizeof(struct iovec));
1833 
1834 	fd = aio_md_setup();
1835 
1836 	bzero(&aio, sizeof(aio));
1837 	aio.aio_fildes = fd;
1838 	aio.aio_offset = 0;
1839 	for (i = 0; i < max_buf_aio + 1; i++) {
1840 		iov[i].iov_base = &buffer[i * 512];
1841 		iov[i].iov_len = 512;
1842 	}
1843 	aio.aio_iov = iov;
1844 	aio.aio_iovcnt = max_buf_aio + 1;
1845 
1846 	if (aio_writev(&aio) < 0)
1847 		atf_tc_fail("aio_writev failed: %s", strerror(errno));
1848 
1849 	len = poll(&aio);
1850 	if (len < 0)
1851 		atf_tc_fail("aio failed: %s", strerror(errno));
1852 
1853 	if (len != buflen)
1854 		atf_tc_fail("aio short write: got %jd, expected: %jd "
1855 			"(max_buf_aio=%d, iovcnt=%zu)",
1856 			(intmax_t)len, (intmax_t)buflen, max_buf_aio, aio.aio_iovcnt);
1857 
1858 	bzero(&aio, sizeof(aio));
1859 	aio.aio_fildes = fd;
1860 	aio.aio_offset = 0;
1861 	aio.aio_iov = iov;
1862 	aio.aio_iovcnt = max_buf_aio + 1;
1863 
1864 	if (aio_readv(&aio) < 0)
1865 		atf_tc_fail("aio_readv failed: %s", strerror(errno));
1866 
1867 	len = poll(&aio);
1868 	if (len < 0)
1869 		atf_tc_fail("aio failed: %s", strerror(errno));
1870 
1871 	if (len != buflen)
1872 		atf_tc_fail("aio short read (%jd)", (intmax_t)len);
1873 
1874 	if (aio_test_buffer(buffer, buflen, seed) == 0)
1875 		atf_tc_fail("buffer mismatched");
1876 
1877 	close(fd);
1878 }
ATF_TC_CLEANUP(vectored_big_iovcnt,tc)1879 ATF_TC_CLEANUP(vectored_big_iovcnt, tc)
1880 {
1881 	aio_md_cleanup();
1882 }
1883 
1884 ATF_TC_WITHOUT_HEAD(vectored_file_poll);
ATF_TC_BODY(vectored_file_poll,tc)1885 ATF_TC_BODY(vectored_file_poll, tc)
1886 {
1887 	aio_file_test(poll, NULL, true);
1888 }
1889 
1890 ATF_TC_WITHOUT_HEAD(vectored_thread);
ATF_TC_BODY(vectored_thread,tc)1891 ATF_TC_BODY(vectored_thread, tc)
1892 {
1893 	aio_file_test(poll_signaled, setup_thread(), true);
1894 }
1895 
1896 ATF_TC_WITH_CLEANUP(vectored_md_poll);
ATF_TC_HEAD(vectored_md_poll,tc)1897 ATF_TC_HEAD(vectored_md_poll, tc)
1898 {
1899 	atf_tc_set_md_var(tc, "require.user", "root");
1900 }
ATF_TC_BODY(vectored_md_poll,tc)1901 ATF_TC_BODY(vectored_md_poll, tc)
1902 {
1903 	aio_md_test(poll, NULL, true);
1904 }
ATF_TC_CLEANUP(vectored_md_poll,tc)1905 ATF_TC_CLEANUP(vectored_md_poll, tc)
1906 {
1907 	aio_md_cleanup();
1908 }
1909 
1910 ATF_TC_WITHOUT_HEAD(vectored_socket_poll);
ATF_TC_BODY(vectored_socket_poll,tc)1911 ATF_TC_BODY(vectored_socket_poll, tc)
1912 {
1913 	aio_unix_socketpair_test(poll, NULL, true);
1914 }
1915 
1916 // aio_writev and aio_readv should still work even if the iov contains elements
1917 // that aren't a multiple of the device's sector size, and even if the total
1918 // amount if I/O _is_ a multiple of the device's sector size.
1919 ATF_TC_WITH_CLEANUP(vectored_unaligned);
ATF_TC_HEAD(vectored_unaligned,tc)1920 ATF_TC_HEAD(vectored_unaligned, tc)
1921 {
1922 	atf_tc_set_md_var(tc, "descr",
1923 	    "Vectored AIO should still work even if the iov contains elements "
1924 	    "that aren't a multiple of the sector size.");
1925 	atf_tc_set_md_var(tc, "require.user", "root");
1926 	atf_tc_set_md_var(tc, "require.kmods", "zfs");
1927 }
ATF_TC_BODY(vectored_unaligned,tc)1928 ATF_TC_BODY(vectored_unaligned, tc)
1929 {
1930 	struct aio_context ac;
1931 	struct aiocb aio;
1932 	struct iovec iov[3];
1933 	ssize_t len, total_len;
1934 	int fd;
1935 
1936 	if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
1937 		atf_tc_skip("https://bugs.freebsd.org/258766");
1938 
1939 	ATF_REQUIRE_UNSAFE_AIO();
1940 
1941 	/*
1942 	 * Use a zvol with volmode=dev, so it will allow .d_write with
1943 	 * unaligned uio.  geom devices use physio, which doesn't allow that.
1944 	 */
1945 	fd = aio_zvol_setup(atf_tc_get_ident(tc));
1946 	aio_context_init(&ac, fd, fd, FILE_LEN);
1947 
1948 	/* Break the buffer into 3 parts:
1949 	 * * A 4kB part, aligned to 4kB
1950 	 * * Two other parts that add up to 4kB:
1951 	 *   - 256B
1952 	 *   - 4kB - 256B
1953 	 */
1954 	iov[0].iov_base = ac.ac_buffer;
1955 	iov[0].iov_len = 4096;
1956 	iov[1].iov_base = (void*)((uintptr_t)iov[0].iov_base + iov[0].iov_len);
1957 	iov[1].iov_len = 256;
1958 	iov[2].iov_base = (void*)((uintptr_t)iov[1].iov_base + iov[1].iov_len);
1959 	iov[2].iov_len = 4096 - iov[1].iov_len;
1960 	total_len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len;
1961 	bzero(&aio, sizeof(aio));
1962 	aio.aio_fildes = ac.ac_write_fd;
1963 	aio.aio_offset = 0;
1964 	aio.aio_iov = iov;
1965 	aio.aio_iovcnt = 3;
1966 
1967 	if (aio_writev(&aio) < 0)
1968 		atf_tc_fail("aio_writev failed: %s", strerror(errno));
1969 
1970 	len = poll(&aio);
1971 	if (len < 0)
1972 		atf_tc_fail("aio failed: %s", strerror(errno));
1973 
1974 	if (len != total_len)
1975 		atf_tc_fail("aio short write (%jd)", (intmax_t)len);
1976 
1977 	bzero(&aio, sizeof(aio));
1978 	aio.aio_fildes = ac.ac_read_fd;
1979 	aio.aio_offset = 0;
1980 	aio.aio_iov = iov;
1981 	aio.aio_iovcnt = 3;
1982 
1983 	if (aio_readv(&aio) < 0)
1984 		atf_tc_fail("aio_readv failed: %s", strerror(errno));
1985 	len = poll(&aio);
1986 
1987 	ATF_REQUIRE_MSG(aio_test_buffer(ac.ac_buffer, total_len,
1988 	    ac.ac_seed) != 0, "aio_test_buffer: internal error");
1989 
1990 	close(fd);
1991 }
ATF_TC_CLEANUP(vectored_unaligned,tc)1992 ATF_TC_CLEANUP(vectored_unaligned, tc)
1993 {
1994 	aio_zvol_cleanup(atf_tc_get_ident(tc));
1995 }
1996 
1997 static void
aio_zvol_test(completion comp,struct sigevent * sev,bool vectored,const char * unique)1998 aio_zvol_test(completion comp, struct sigevent *sev, bool vectored,
1999     const char *unique)
2000 {
2001 	struct aio_context ac;
2002 	int fd;
2003 
2004 	fd = aio_zvol_setup(unique);
2005 	aio_context_init(&ac, fd, fd, DEVICE_IO_LEN);
2006 	if (vectored) {
2007 		aio_writev_test(&ac, comp, sev);
2008 		aio_readv_test(&ac, comp, sev);
2009 	} else {
2010 		aio_write_test(&ac, comp, sev);
2011 		aio_read_test(&ac, comp, sev);
2012 	}
2013 
2014 	close(fd);
2015 }
2016 
2017 /*
2018  * Note that unlike md, the zvol is not a geom device, does not allow unmapped
2019  * buffers, and does not use physio.
2020  */
2021 ATF_TC_WITH_CLEANUP(vectored_zvol_poll);
ATF_TC_HEAD(vectored_zvol_poll,tc)2022 ATF_TC_HEAD(vectored_zvol_poll, tc)
2023 {
2024 	atf_tc_set_md_var(tc, "require.user", "root");
2025 	atf_tc_set_md_var(tc, "require.kmods", "zfs");
2026 }
ATF_TC_BODY(vectored_zvol_poll,tc)2027 ATF_TC_BODY(vectored_zvol_poll, tc)
2028 {
2029 	if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
2030 		atf_tc_skip("https://bugs.freebsd.org/258766");
2031 	aio_zvol_test(poll, NULL, true, atf_tc_get_ident(tc));
2032 }
ATF_TC_CLEANUP(vectored_zvol_poll,tc)2033 ATF_TC_CLEANUP(vectored_zvol_poll, tc)
2034 {
2035 	aio_zvol_cleanup(atf_tc_get_ident(tc));
2036 }
2037 
ATF_TP_ADD_TCS(tp)2038 ATF_TP_ADD_TCS(tp)
2039 {
2040 
2041 	/* Test every file type with every completion method */
2042 	ATF_TP_ADD_TC(tp, file_kq);
2043 	ATF_TP_ADD_TC(tp, file_poll);
2044 	ATF_TP_ADD_TC(tp, file_signal);
2045 	ATF_TP_ADD_TC(tp, file_suspend);
2046 	ATF_TP_ADD_TC(tp, file_thread);
2047 	ATF_TP_ADD_TC(tp, file_waitcomplete);
2048 	ATF_TP_ADD_TC(tp, fifo_kq);
2049 	ATF_TP_ADD_TC(tp, fifo_poll);
2050 	ATF_TP_ADD_TC(tp, fifo_signal);
2051 	ATF_TP_ADD_TC(tp, fifo_suspend);
2052 	ATF_TP_ADD_TC(tp, fifo_thread);
2053 	ATF_TP_ADD_TC(tp, fifo_waitcomplete);
2054 	ATF_TP_ADD_TC(tp, socket_kq);
2055 	ATF_TP_ADD_TC(tp, socket_poll);
2056 	ATF_TP_ADD_TC(tp, socket_signal);
2057 	ATF_TP_ADD_TC(tp, socket_suspend);
2058 	ATF_TP_ADD_TC(tp, socket_thread);
2059 	ATF_TP_ADD_TC(tp, socket_waitcomplete);
2060 	ATF_TP_ADD_TC(tp, pty_kq);
2061 	ATF_TP_ADD_TC(tp, pty_poll);
2062 	ATF_TP_ADD_TC(tp, pty_signal);
2063 	ATF_TP_ADD_TC(tp, pty_suspend);
2064 	ATF_TP_ADD_TC(tp, pty_thread);
2065 	ATF_TP_ADD_TC(tp, pty_waitcomplete);
2066 	ATF_TP_ADD_TC(tp, pipe_kq);
2067 	ATF_TP_ADD_TC(tp, pipe_poll);
2068 	ATF_TP_ADD_TC(tp, pipe_signal);
2069 	ATF_TP_ADD_TC(tp, pipe_suspend);
2070 	ATF_TP_ADD_TC(tp, pipe_thread);
2071 	ATF_TP_ADD_TC(tp, pipe_waitcomplete);
2072 	ATF_TP_ADD_TC(tp, md_kq);
2073 	ATF_TP_ADD_TC(tp, md_poll);
2074 	ATF_TP_ADD_TC(tp, md_signal);
2075 	ATF_TP_ADD_TC(tp, md_suspend);
2076 	ATF_TP_ADD_TC(tp, md_thread);
2077 	ATF_TP_ADD_TC(tp, md_waitcomplete);
2078 
2079 	/* Various special cases */
2080 	ATF_TP_ADD_TC(tp, aio_fsync_errors);
2081 	ATF_TP_ADD_TC(tp, aio_fsync_sync_test);
2082 	ATF_TP_ADD_TC(tp, aio_fsync_dsync_test);
2083 	ATF_TP_ADD_TC(tp, aio_large_read_test);
2084 	ATF_TP_ADD_TC(tp, aio_socket_two_reads);
2085 	ATF_TP_ADD_TC(tp, aio_socket_blocking_short_write);
2086 	ATF_TP_ADD_TC(tp, aio_socket_blocking_short_write_vectored);
2087 	ATF_TP_ADD_TC(tp, aio_socket_listen_fail);
2088 	ATF_TP_ADD_TC(tp, aio_socket_listen_pending);
2089 	ATF_TP_ADD_TC(tp, aio_socket_short_write_cancel);
2090 	ATF_TP_ADD_TC(tp, aio_socket_shutdown);
2091 	ATF_TP_ADD_TC(tp, aio_writev_dos_iov_len);
2092 	ATF_TP_ADD_TC(tp, aio_writev_dos_iovcnt);
2093 	ATF_TP_ADD_TC(tp, aio_writev_efault);
2094 	ATF_TP_ADD_TC(tp, aio_writev_empty_file_poll);
2095 	ATF_TP_ADD_TC(tp, aio_writev_empty_file_signal);
2096 	ATF_TP_ADD_TC(tp, ev_oneshot);
2097 	ATF_TP_ADD_TC(tp, vectored_big_iovcnt);
2098 	ATF_TP_ADD_TC(tp, vectored_file_poll);
2099 	ATF_TP_ADD_TC(tp, vectored_md_poll);
2100 	ATF_TP_ADD_TC(tp, vectored_zvol_poll);
2101 	ATF_TP_ADD_TC(tp, vectored_unaligned);
2102 	ATF_TP_ADD_TC(tp, vectored_socket_poll);
2103 	ATF_TP_ADD_TC(tp, vectored_thread);
2104 
2105 	return (atf_no_error());
2106 }
2107