lio_test.c revision 322892
1/*-
2 * Copyright (c) 2017 Spectra Logic Corp
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/lio_test.c 322892 2017-08-25 14:42:11Z asomers $
27 */
28
29#include <sys/param.h>
30#include <sys/event.h>
31
32#include <aio.h>
33#include <semaphore.h>
34
35#include <atf-c.h>
36
37#include "freebsd_test_suite/macros.h"
38
39static sem_t completions;
40
41
42static void
43handler(int sig __unused)
44{
45	ATF_REQUIRE_EQ(0, sem_post(&completions));
46}
47
48static void
49thr_handler(union sigval sv __unused)
50{
51	ATF_REQUIRE_EQ(0, sem_post(&completions));
52}
53
54/* With LIO_WAIT, an empty lio_listio should return immediately */
55ATF_TC_WITHOUT_HEAD(lio_listio_empty_wait);
56ATF_TC_BODY(lio_listio_empty_wait, tc)
57{
58	struct aiocb *list = NULL;
59
60	ATF_REQUIRE_EQ(0, lio_listio(LIO_WAIT, &list, 0, NULL));
61}
62
63/*
64 * With LIO_NOWAIT, an empty lio_listio should send completion notification
65 * immediately
66 */
67ATF_TC_WITHOUT_HEAD(lio_listio_empty_nowait_kevent);
68ATF_TC_BODY(lio_listio_empty_nowait_kevent, tc)
69{
70	struct aiocb *list = NULL;
71	struct sigevent sev;
72	struct kevent kq_returned;
73	int kq, result;
74	void *udata = (void*)0xdeadbeefdeadbeef;
75
76	atf_tc_expect_timeout("Bug 220398 - lio_listio(2) never sends"
77			" asynchronous notification if nent==0");
78	kq = kqueue();
79	ATF_REQUIRE(kq > 0);
80	sev.sigev_notify = SIGEV_KEVENT;
81	sev.sigev_notify_kqueue = kq;
82	sev.sigev_value.sival_ptr = udata;
83	ATF_REQUIRE_EQ(0, lio_listio(LIO_NOWAIT, &list, 0, &sev));
84	result = kevent(kq, NULL, 0, &kq_returned, 1, NULL);
85	ATF_REQUIRE_MSG(result == 1, "Never got completion notification");
86	ATF_REQUIRE_EQ((uintptr_t)list, kq_returned.ident);
87	ATF_REQUIRE_EQ(EVFILT_LIO, kq_returned.filter);
88	ATF_REQUIRE_EQ(udata, kq_returned.udata);
89}
90
91/*
92 * With LIO_NOWAIT, an empty lio_listio should send completion notification
93 * immediately
94 */
95ATF_TC_WITHOUT_HEAD(lio_listio_empty_nowait_signal);
96ATF_TC_BODY(lio_listio_empty_nowait_signal, tc)
97{
98	struct aiocb *list = NULL;
99	struct sigevent sev;
100
101	atf_tc_expect_timeout("Bug 220398 - lio_listio(2) never sends"
102	    "asynchronous notification if nent==0");
103	ATF_REQUIRE_EQ(0, sem_init(&completions, false, 0));
104	sev.sigev_notify = SIGEV_SIGNAL;
105	sev.sigev_signo = SIGUSR1;
106	ATF_REQUIRE(SIG_ERR != signal(SIGUSR1, handler));
107	ATF_REQUIRE_EQ(0, lio_listio(LIO_NOWAIT, &list, 0, &sev));
108	ATF_REQUIRE_EQ(0, sem_wait(&completions));
109	ATF_REQUIRE_EQ(0, sem_destroy(&completions));
110}
111
112/*
113 * With LIO_NOWAIT, an empty lio_listio should send completion notification
114 * immediately
115 */
116ATF_TC_WITHOUT_HEAD(lio_listio_empty_nowait_thread);
117ATF_TC_BODY(lio_listio_empty_nowait_thread, tc)
118{
119	struct aiocb *list = NULL;
120	struct sigevent sev;
121
122	atf_tc_expect_timeout("Bug 220398 - lio_listio(2) never sends"
123	    "asynchronous notification if nent==0");
124	ATF_REQUIRE_EQ(0, sem_init(&completions, false, 0));
125	bzero(&sev, sizeof(sev));
126	sev.sigev_notify = SIGEV_THREAD;
127	sev.sigev_notify_function = thr_handler;
128	sev.sigev_notify_attributes = NULL;
129	ATF_REQUIRE_MSG(0 == lio_listio(LIO_NOWAIT, &list, 0, &sev),
130	    "lio_listio: %s", strerror(errno));
131	ATF_REQUIRE_EQ(0, sem_wait(&completions));
132	ATF_REQUIRE_EQ(0, sem_destroy(&completions));
133}
134
135
136ATF_TP_ADD_TCS(tp)
137{
138
139	ATF_TP_ADD_TC(tp, lio_listio_empty_nowait_kevent);
140	ATF_TP_ADD_TC(tp, lio_listio_empty_nowait_signal);
141	ATF_TP_ADD_TC(tp, lio_listio_empty_nowait_thread);
142	ATF_TP_ADD_TC(tp, lio_listio_empty_wait);
143
144	return (atf_no_error());
145}
146