blob: afadbd779c79b8bd20ad14d5914f7c700268c6a3 [file] [log] [blame]
subrata_modak56207ce2009-03-23 13:35:39 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
subrata_modak56207ce2009-03-23 13:35:39 +000018 *
19 */
mridgeb0a63b62004-03-03 21:36:28 +000020
21/******************************************************************************
22
23 File: epoll-ltp.c
24
25 Description:
26 Test the epoll_* system calls. This test program attempts to
subrata_modak4bb656a2009-02-26 12:02:09 +000027 be very thorough in exercising epoll_* system calls. Large
mridgeb0a63b62004-03-03 21:36:28 +000028 combinations of valid and invalid parameters are passed with
29 valid and invalid sequences. Due to the combinatorial nature
subrata_modak4bb656a2009-02-26 12:02:09 +000030 of this test program the test may take a "long" time to
mridgeb0a63b62004-03-03 21:36:28 +000031 execute.
32
33 Total Tests: 2 (2 system calls are being tested for)
34
35 Test Name: epoll_create, epoll_ctl
36
37 Test Assertion
38 & Strategy: Test a variety of incorrect parameters for epoll_create
39
40 Then run a reasonable epoll_create and get a fd for the epoll
41 set.
42
43 Next run epoll_ctl on that fd (epoll_fd) with a variety of
44 incorrect parameters and a couple correct ones.
45
46 Finally ?How to thoroughly test epoll_wait?
47
48 Author: Matt Helsley <matthltc@us.ibm.com>
49
50 History: Created - May 22 2003 - Matt Helsley <matthltc@us.ibm.com>
subrata_modak4bb656a2009-02-26 12:02:09 +000051 Added -
mridgeb0a63b62004-03-03 21:36:28 +000052
53 Notes: Currently we assume that the OS will never allocate an fd s.t.
54 fd == INT_MAX and that it will instead choose to allocate fds
55 from the "low" numbers. -MH
56
57 Currently pokes epoll_create several times in 2 + NUM_RAND_ATTEMPTS ways
58 pokes epoll_ctl 27648 - (2 + NUM_RAND_ATTEMPTS) ways
59 does not poke epoll_wait
60
61 TODO: change errno test code to build lists of possible errno values for
62 each erroneous parameter. Check that the errno value is in one
63 of the lists. Currently errno is not checked at all when multiple
64 erroneous parameters are passed in.
65
66 test epoll_ctl with a large number of file descriptor events in the
67 set
68
69 Link against epoll and ltp (-lepoll -lltp)
70
71*******************************************************************************/
vapier7f40cfd2006-08-21 06:47:15 +000072
73#ifndef _GNU_SOURCE
Wanlong Gao354ebb42012-12-07 10:10:04 +080074#define _GNU_SOURCE
vapier7f40cfd2006-08-21 06:47:15 +000075#endif
76
mridgeb0a63b62004-03-03 21:36:28 +000077#include <stdio.h>
78#include <stdlib.h>
79#include <unistd.h>
80#include <fcntl.h>
81#include <stdarg.h>
82#include <string.h>
83#include <signal.h>
84#include <assert.h>
85#include <limits.h>
86#include <ctype.h>
87#include <time.h>
88#include <errno.h>
89#include <signal.h>
90#include <sys/types.h>
91#include <sys/time.h>
92#include <sys/file.h>
93#include <sys/ioctl.h>
94#include <sys/mman.h>
95#include <sys/select.h>
96#include <sys/wait.h>
97
subrata_modakc81d7b92009-09-09 17:48:08 +000098#include "config.h"
mridgeb0a63b62004-03-03 21:36:28 +000099#include "test.h"
subrata_modakc81d7b92009-09-09 17:48:08 +0000100
czhang@redhat.comf8df4b52011-03-30 22:32:35 +0800101char *TCID = "epoll01";
102int TST_TOTAL = 1;
subrata_modakc81d7b92009-09-09 17:48:08 +0000103
104#ifdef HAVE_SYS_EPOLL_H
105
106#include <sys/epoll.h>
mridgeb0a63b62004-03-03 21:36:28 +0000107
108/* Local Defines */
109#if !defined(TRUE) && !defined(FALSE)
110#define TRUE 1
111#define FALSE 0
112#endif
113
114#define NUM_RAND_ATTEMPTS 16
115#define BACKING_STORE_SIZE_HINT 32
116
mridgeb0a63b62004-03-03 21:36:28 +0000117/*
118 Define the beginning of a "protected region".
119 This is a region where a wide variety of errors
subrata_modak4bb656a2009-02-26 12:02:09 +0000120 could occur or signals could arrive (including
121 SIGSEGV and SIGKILL).
subrata_modak56207ce2009-03-23 13:35:39 +0000122$
mridgeb0a63b62004-03-03 21:36:28 +0000123 The test program uses this to catch those
124 conditions as best it can and continue testing.
125
126 The region MUST be marked by a corresponding
subrata_modak4bb656a2009-02-26 12:02:09 +0000127 PROTECT_REGION_END.
mridgeb0a63b62004-03-03 21:36:28 +0000128
129 DO NOT nest protected regions! i.e. Do not build
130 code of the form:
131
subrata_modak56207ce2009-03-23 13:35:39 +0000132 PROTECT_REGION_START
mridgeb0a63b62004-03-03 21:36:28 +0000133 ...
subrata_modak56207ce2009-03-23 13:35:39 +0000134 PROTECT_REGION_START
mridgeb0a63b62004-03-03 21:36:28 +0000135 ...
subrata_modak56207ce2009-03-23 13:35:39 +0000136 PROTECT_REGION_END
mridgeb0a63b62004-03-03 21:36:28 +0000137 ...
subrata_modak56207ce2009-03-23 13:35:39 +0000138 PROTECT_REGION_END
mridgeb0a63b62004-03-03 21:36:28 +0000139 */
subrata_modak56207ce2009-03-23 13:35:39 +0000140#define PROTECT_REGION_START \
141do { \
142 pid_t kid_pid; \
143 int kid_status; \
144 \
145 tst_flush(); \
146 kid_pid = FORK_OR_VFORK(); \
147 if (kid_pid == 0) {
mridgeb0a63b62004-03-03 21:36:28 +0000148
149#define PROTECT_REGION_EXIT(errval) return (errval);
150
subrata_modak56207ce2009-03-23 13:35:39 +0000151#define PROTECT_REGION_END(result, errval) \
152 return 0; \
153 } else { \
154 waitpid(kid_pid, &kid_status, 0); \
155 if (WIFEXITED(kid_status)) { \
156 (result) = WEXITSTATUS(kid_status); \
157 } else { /* Must have been signaled */ \
158 (result) = (errval); \
159 if (WIFSIGNALED(kid_status)) \
160 tst_resm(TFAIL, "Protected function test exitted due to signal %d (%s)", \
161 WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \
162 } \
163 } \
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800164} while (0)
mridgeb0a63b62004-03-03 21:36:28 +0000165
166/*
subrata_modak56207ce2009-03-23 13:35:39 +0000167 * Call a function in a "protected" context.
168 * This protects the test program proper from segfaults
169 * and allows for the extraction of an integer return
170 * code.
171 *
172 * return only integer results.
mridgeb0a63b62004-03-03 21:36:28 +0000173 */
subrata_modak56207ce2009-03-23 13:35:39 +0000174#define PROTECT_FUNC(fn, errval, epoll_fd) ( \
175{ \
176 pid_t kid_pid; \
177 int kid_status; \
178 \
179 tst_flush(); \
180 kid_pid = FORK_OR_VFORK(); \
181 if (kid_pid == 0) { /* Run the function */ \
182 return fn(epoll_fd); \
183 } else { \
184 waitpid(kid_pid, &kid_status, 0); \
185 if (WIFEXITED(kid_status)) { \
186 kid_status = WEXITSTATUS(kid_status); \
187 } else { /* Must have been signaled */ \
188 kid_status = (errval); \
189 if (WIFSIGNALED(kid_status)) \
190 tst_resm(TFAIL, "Protected function test exitted due to signal %d (%s)", \
191 WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \
192 } \
193} \
194kid_status = kid_status;})
mridgeb0a63b62004-03-03 21:36:28 +0000195
mridgeb0a63b62004-03-03 21:36:28 +0000196/*
subrata_modak56207ce2009-03-23 13:35:39 +0000197 * Given the number of random size requests to test,
198 * test various boundary cases of epoll_create().
199 *
200 * Return the number of tests that failed. 0 indicates
201 * 100% passed.
mridgeb0a63b62004-03-03 21:36:28 +0000202 */
subrata_modak56207ce2009-03-23 13:35:39 +0000203int test_epoll_create(unsigned int num_rand_attempts)
mridgeb0a63b62004-03-03 21:36:28 +0000204{
subrata_modak56207ce2009-03-23 13:35:39 +0000205 int epoll_fd = -1;
206 int fd_set_size = -1;
207 unsigned int attempt_count;
208 unsigned int num_epoll_create_test_fails = 0;
209 unsigned int num_epoll_create_test_calls = 0;
mridge98988cb2004-08-11 19:06:57 +0000210
subrata_modak56207ce2009-03-23 13:35:39 +0000211 /* Negative set sizes */
mridgeb0a63b62004-03-03 21:36:28 +0000212 errno = 0;
subrata_modak56207ce2009-03-23 13:35:39 +0000213 fd_set_size = -1;
mridge98988cb2004-08-11 19:06:57 +0000214 num_epoll_create_test_calls++;
mridgeb0a63b62004-03-03 21:36:28 +0000215 epoll_fd = epoll_create(fd_set_size);
subrata_modak56207ce2009-03-23 13:35:39 +0000216 if (epoll_fd >= 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800217 tst_resm(TFAIL | TERRNO,
Garrett Cooper53740502010-12-16 00:04:01 -0800218 "epoll_create with negative set size succeeded unexpectedly");
mridge98988cb2004-08-11 19:06:57 +0000219 num_epoll_create_test_fails++;
subrata_modak56207ce2009-03-23 13:35:39 +0000220 close(epoll_fd);
mridgeb0a63b62004-03-03 21:36:28 +0000221 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000222 if (errno != EINVAL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800223 tst_resm(TFAIL | TERRNO,
Garrett Cooper53740502010-12-16 00:04:01 -0800224 "epoll_create with negative set size didn't set errno to EINVAL");
subrata_modak56207ce2009-03-23 13:35:39 +0000225 num_epoll_create_test_fails++;
226 } else {
227 tst_resm(TPASS, "epoll_create with negative set size");
228 }
mridgeb0a63b62004-03-03 21:36:28 +0000229 }
mridgeb0a63b62004-03-03 21:36:28 +0000230
subrata_modak56207ce2009-03-23 13:35:39 +0000231 /* Large set sizes -- try several less than or equal to INT_MAX by some
232 small amount (expect num_rand_attempts to be approximately the
233 amount we'd like to go below INT_MAX). */
234 fd_set_size = INT_MAX;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800235 for (attempt_count = num_rand_attempts; attempt_count > 0;
236 attempt_count--, fd_set_size--) {
subrata_modak56207ce2009-03-23 13:35:39 +0000237 num_epoll_create_test_calls++;
238 epoll_fd = epoll_create(fd_set_size);
239 if (epoll_fd == -1) {
240 if (errno != ENOMEM) {
241 tst_resm(TFAIL,
242 "epoll_create with large set size (size = %d)",
243 fd_set_size);
244 num_epoll_create_test_fails++;
245 } else {
246 tst_resm(TPASS,
247 "epoll_create with large set size (size = %d)",
248 fd_set_size);
249 }
250 } else {
251 tst_resm(TPASS,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800252 "epoll_create with large set size (size = %d)",
253 fd_set_size);
subrata_modak56207ce2009-03-23 13:35:39 +0000254 close(epoll_fd);
255 }
256 }
mridge98988cb2004-08-11 19:06:57 +0000257
subrata_modak56207ce2009-03-23 13:35:39 +0000258 /* Random large set sizes */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800259 for (attempt_count = num_rand_attempts; attempt_count > 0;
260 attempt_count--) {
subrata_modak56207ce2009-03-23 13:35:39 +0000261 fd_set_size = abs(rand() + SHRT_MAX) % INT_MAX;
262 errno = 0;
263 num_epoll_create_test_calls++;
264 epoll_fd = epoll_create(fd_set_size);
265 if (epoll_fd < 0) {
266 if (errno != ENOMEM) {
267 tst_resm(TFAIL,
268 "epoll_create with random random large set size (size = %d)",
269 fd_set_size);
270 num_epoll_create_test_fails++;
271 } else {
272 tst_resm(TPASS,
273 "epoll_create with random random large set size (size = %d)",
274 fd_set_size);
275 }
276 } else {
277 tst_resm(TPASS,
278 "epoll_create with random large set size (size = %d)",
279 fd_set_size);
280 close(epoll_fd);
281 }
282 }
283
284 tst_resm(TINFO,
285 "Summary: Of %d tests, epoll_create failed %d (%3.0f%% passed).",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800286 num_epoll_create_test_calls, num_epoll_create_test_fails,
287 ((float)
288 (num_epoll_create_test_calls - num_epoll_create_test_fails)
289 * 100.0f / (float)
290 num_epoll_create_test_calls));
subrata_modak56207ce2009-03-23 13:35:39 +0000291 /* Return 0 on success. */
292
293 return num_epoll_create_test_fails;
mridgeb0a63b62004-03-03 21:36:28 +0000294}
295
subrata_modak56207ce2009-03-23 13:35:39 +0000296/* RES_PASS indicates a PASS result */
mridgeb0a63b62004-03-03 21:36:28 +0000297#define RES_PASS 0
298
subrata_modak56207ce2009-03-23 13:35:39 +0000299/*
300 * RES_FAIL_* indicates a FAIL result
301 * In brief, there are two things that can go wrong in a
302 * failiure. The return value (result = epoll_ctl(...)) and
303 * the errno value may not match expectations. In this notation,
304 * MIS -> mismatch, MAT -> match, BAD -> bad, and IGN -> ignored.
305 *
306 * RETV_MIS_* indicates the return value was either 0 or 1, but did
307 * not match the expected return value
308 *
309 * _RETV_MAT_* indicates that the return value was 0 xor 1 and did
310 * match the expected value
311 *
312 *_RETV_BAD_* the return value was neither 0 nor 1.
313 *_ERRNO_MAT the error number matched the expected number
314 *_ERRNO_MIS the error number did not match the expected number
315 *_ERRNO_IGN no error number was expected and so errno was ignored
316 *
317 * Keep these values below 256 as only 1 byte gets passed as a
318 * return value for the process. Note that RES_PASS is 0 which
319 * LTP interprets as a PASS.
320 */
mridgeb0a63b62004-03-03 21:36:28 +0000321
subrata_modak56207ce2009-03-23 13:35:39 +0000322/* Did not get the expected return value, but errno value was expected */
323#define RES_FAIL_RETV_MIS_ERRNO_MAT 1
324/* Did not get the expected return value, but errno value was expected */
325#define RES_FAIL_RETV_BAD_ERRNO_MAT 2
326/* Did get the expected return value, and errno value was not expected */
327#define RES_FAIL_RETV_MAT_ERRNO_MIS 3
328/* Return value was neither 0 nor -1. Mismatch in value of errno */
329#define RES_FAIL_RETV_BAD_ERRNO_MIS 4
330/* Did not get the expected return value and errno is irrelevant */
331#define RES_FAIL_RETV_MIS_ERRNO_IGN 5
332/* Return value was neither 0 nor -1. value of errno is irrelevant */
333#define RES_FAIL_RETV_BAD_ERRNO_IGN 6
334/* We expected multiple errors so we were unable to check errno for conformance */
335#define RES_PASS_RETV_MAT_ERRNO_IGN 7
mridgeb0a63b62004-03-03 21:36:28 +0000336
subrata_modak56207ce2009-03-23 13:35:39 +0000337static const char *result_strings[] = {
338 "Passed",
339 "Return value mismatched yet errno matched.",
340 "Return value was bad yet errno matched.",
341 "Return value matched yet errno mismatched.",
342 "Return value was bad and errno mismatched.",
343 "Return value mismatched so errno ignored.",
344 "Return value was bad so errno ignored.",
345 "Return value matched but errno ignored. (multiple errors expected)"
mridgeb0a63b62004-03-03 21:36:28 +0000346};
347
348/****************************************************************************************/
349/* This macro helps keep the code below understandable. It prints out the
350 failiure message passed to it plus the parameters to the system call. */
351#define EPOLL_CTL_TEST_RESULTS_SHOW_PARAMS 1
352#if EPOLL_CTL_TEST_RESULTS_SHOW_PARAMS
353#define EPOLL_CTL_TEST_FAIL(msg , ...) \
subrata_modak56207ce2009-03-23 13:35:39 +0000354({ \
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800355 if (ev_ptr != NULL) { \
vapierdf909962009-08-28 12:19:26 +0000356 tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \
subrata_modak56207ce2009-03-23 13:35:39 +0000357 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
subrata_modakc81d7b92009-09-09 17:48:08 +0000358 epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \
subrata_modak56207ce2009-03-23 13:35:39 +0000359 strerror(errno)); \
360 } else { \
vapierdf909962009-08-28 12:19:26 +0000361 tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \
subrata_modak56207ce2009-03-23 13:35:39 +0000362 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
363 epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \
364 } \
365})
mridgeb0a63b62004-03-03 21:36:28 +0000366
367#define EPOLL_CTL_TEST_PASS(msg , ...) \
subrata_modak56207ce2009-03-23 13:35:39 +0000368({ \
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800369 if (ev_ptr != NULL) { \
vapierdf909962009-08-28 12:19:26 +0000370 tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \
subrata_modak56207ce2009-03-23 13:35:39 +0000371 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
subrata_modakc81d7b92009-09-09 17:48:08 +0000372 epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \
subrata_modak56207ce2009-03-23 13:35:39 +0000373 strerror(errno)); \
374 } else { \
vapierdf909962009-08-28 12:19:26 +0000375 tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \
subrata_modak56207ce2009-03-23 13:35:39 +0000376 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
377 epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \
378 } \
379})
mridgeb0a63b62004-03-03 21:36:28 +0000380#else
subrata_modakc81d7b92009-09-09 17:48:08 +0000381#define EPOLL_CTL_TEST_FAIL(msg , ...) tst_resm(TFAIL, msg , ##__VA_ARGS__)
382#define EPOLL_CTL_TEST_PASS(msg , ...) tst_resm(TPASS, msg , ##__VA_ARGS__)
mridgeb0a63b62004-03-03 21:36:28 +0000383#endif
384
385/****************************************************************************************/
mridge98988cb2004-08-11 19:06:57 +0000386
subrata_modak56207ce2009-03-23 13:35:39 +0000387int test_epoll_ctl(int epoll_fd)
mridgeb0a63b62004-03-03 21:36:28 +0000388{
subrata_modak56207ce2009-03-23 13:35:39 +0000389 int fds[] = { -1, INT_MAX };
390 int epoll_fds[] = { 0, -1, 0, INT_MAX };
391 int epoll_events[64];
392 /* The list of operations to try AND THE ORDER THEY ARE TRIED IN */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800393 int epoll_ctl_ops[] =
394 { EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLL_CTL_ADD, EPOLL_CTL_MOD,
subrata_modak56207ce2009-03-23 13:35:39 +0000395 EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLL_CTL_DEL, INT_MAX, -1
396 };
397 struct epoll_event event;
398 char event_mem[sizeof(struct epoll_event) * 2];
399 struct epoll_event *unaligned_event_ptr;
mridge98988cb2004-08-11 19:06:57 +0000400
subrata_modak56207ce2009-03-23 13:35:39 +0000401 /* Indices into lists */
402 int index = 0; /* multi-use index. First uses are to initialize
403 lists. Second use is to iterate over the implicit
404 list of structs to pass in */
405 unsigned int epfd_index; /* index into fd list for the epfd parameter */
406 unsigned int event_index; /* index into event list for the events field of the
407 struct epoll_event parameter */
408 unsigned int fd_index; /* index into fd list for the fd parameter */
409 unsigned int op_index; /* index into the list of operations for the op
410 parameter */
411 unsigned int num_epoll_ctl_test_fails = 0;
412 unsigned int num_epoll_ctl_test_calls = 0;
vapier7f40cfd2006-08-21 06:47:15 +0000413
subrata_modak56207ce2009-03-23 13:35:39 +0000414 /* Generate all possible combinations of events (2^6 == 64)
415 Assume we know nothing about the EPOLL event types _except_
416 that they describe bits in a set. */
417 for (index = 0; index < 64; index++) {
418 epoll_events[index] = ((EPOLLIN * ((index & 0x01) >> 0)) |
419 (EPOLLOUT * ((index & 0x02) >> 1)) |
420 (EPOLLPRI * ((index & 0x04) >> 2)) |
421 (EPOLLERR * ((index & 0x08) >> 3)) |
422 (EPOLLHUP * ((index & 0x10) >> 4)) |
423 (EPOLLET * ((index & 0x20) >> 5)));
mridgeb0a63b62004-03-03 21:36:28 +0000424 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000425
subrata_modak56207ce2009-03-23 13:35:39 +0000426 /* Get a pointer to an unaligned struct epoll_event */
427 {
428 char *unalign_ptr = event_mem;
subrata_modakbdbaec52009-02-26 12:14:51 +0000429
Wanlong Gao354ebb42012-12-07 10:10:04 +0800430 unalign_ptr =
431 unalign_ptr + (((unsigned long)unalign_ptr & 1) ? 0 : 1);
subrata_modak56207ce2009-03-23 13:35:39 +0000432 unaligned_event_ptr = (struct epoll_event *)unalign_ptr;
433 }
mridgeb0a63b62004-03-03 21:36:28 +0000434
subrata_modak56207ce2009-03-23 13:35:39 +0000435 /* One of the fds we want to test is the valid one */
436 epoll_fds[0] = epoll_fd;
mridgeb0a63b62004-03-03 21:36:28 +0000437
subrata_modak56207ce2009-03-23 13:35:39 +0000438 /* Test out all of the interesting combinations. This is going to
439 take a while (in compute cycles). It took less than 1 minute to
440 run on a PIII 500 without checking the results. */
441 for (index = 0; index < 3; index++) {
442 struct epoll_event *ev_ptr = NULL;
mridgeb0a63b62004-03-03 21:36:28 +0000443
subrata_modak56207ce2009-03-23 13:35:39 +0000444 switch (index) {
445 case 0: /* Pass aligned struct */
446 event.data.u64 = 0;
447 ev_ptr = &event;
448 break;
449 case 1: /* Pass unaligned struct */
450 unaligned_event_ptr->data.u64 = 0;
451 ev_ptr = unaligned_event_ptr;
452 break;
453 case 2:
454 default: /* Pass NULL ptr */
455 ev_ptr = NULL;
456 break;
457 }
mridgeb0a63b62004-03-03 21:36:28 +0000458
Wanlong Gao354ebb42012-12-07 10:10:04 +0800459 for (epfd_index = 0;
460 epfd_index < (sizeof(epoll_fds) / sizeof(int));
461 epfd_index++) {
462 for (event_index = 0;
463 event_index < (sizeof(epoll_events) / sizeof(int));
464 event_index++) {
465 for (fd_index = 0;
466 fd_index < (sizeof(fds) / sizeof(int));
467 fd_index++) {
subrata_modak56207ce2009-03-23 13:35:39 +0000468 /* Now epoll_fd is a descriptor that references the set of
469 file descriptors we are interested in. Next we test epoll_ctl */
470 for (op_index = 0;
471 op_index <
Wanlong Gao354ebb42012-12-07 10:10:04 +0800472 (sizeof(epoll_ctl_ops) /
473 sizeof(int)); op_index++) {
subrata_modak56207ce2009-03-23 13:35:39 +0000474 int result;
475 int expected_errno = 0;
476 int num_errors_expected = 0;
mridgeb0a63b62004-03-03 21:36:28 +0000477
subrata_modak56207ce2009-03-23 13:35:39 +0000478 if (ev_ptr != NULL)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800479 ev_ptr->events =
480 epoll_events
481 [event_index];
mridgeb0a63b62004-03-03 21:36:28 +0000482
subrata_modak56207ce2009-03-23 13:35:39 +0000483 /* Perform the call itself. Put it in a protected region which
484 returns -1 in the variable result if a protection violation
485 occurs (see PROTECT_REGION_END for the result) */
486 PROTECT_REGION_START errno = 0;
mridgeb0a63b62004-03-03 21:36:28 +0000487
subrata_modak56207ce2009-03-23 13:35:39 +0000488 /* NOTE that we are assuming that epoll will operate across
489 a fork() call such that a subsequent fork() in the parent
490 will also manipulate the same set */
491 result =
492 epoll_ctl(epoll_fds
493 [epfd_index],
494 epoll_ctl_ops
Wanlong Gao354ebb42012-12-07 10:10:04 +0800495 [op_index],
496 fds[fd_index],
497 ev_ptr);
mridgeb0a63b62004-03-03 21:36:28 +0000498
subrata_modak56207ce2009-03-23 13:35:39 +0000499 /* We can't test errno resulting from the epoll_ctl call outside of
500 the PROTECT_REGION hence we do not have a PROTECT_REGION_END
501 here */
mridgeb0a63b62004-03-03 21:36:28 +0000502
subrata_modak56207ce2009-03-23 13:35:39 +0000503 /*
504 Test the results. Look for appropriate error conditions
505 */
mridgeb0a63b62004-03-03 21:36:28 +0000506
subrata_modak56207ce2009-03-23 13:35:39 +0000507 /* Check the epfd */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800508 if (epoll_fds[epfd_index] !=
509 epoll_fd) {
subrata_modak56207ce2009-03-23 13:35:39 +0000510 /* Expect an error */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800511 if (epoll_fds
512 [epfd_index] == 0)
513 expected_errno =
514 EINVAL;
subrata_modak56207ce2009-03-23 13:35:39 +0000515 else /* epfd is not a valid file descriptor since it is
516 neither epoll_fd nor stdin */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800517 expected_errno =
518 EBADF;
subrata_modak56207ce2009-03-23 13:35:39 +0000519 num_errors_expected++;
520 }
mridgeb0a63b62004-03-03 21:36:28 +0000521
subrata_modak56207ce2009-03-23 13:35:39 +0000522 switch (epoll_ctl_ops[op_index]) {
523 case EPOLL_CTL_ADD:
524 case EPOLL_CTL_MOD:
525 case EPOLL_CTL_DEL:
526 break;
527 default: /* Expect an error */
528 expected_errno = EINVAL;
529 num_errors_expected++;
530 break;
531 }
mridgeb0a63b62004-03-03 21:36:28 +0000532
subrata_modak56207ce2009-03-23 13:35:39 +0000533 expected_errno = EPERM;
534 num_errors_expected++;
mridgeb0a63b62004-03-03 21:36:28 +0000535
subrata_modak56207ce2009-03-23 13:35:39 +0000536 if (ev_ptr == NULL) {
537 expected_errno = EINVAL;
538 num_errors_expected++;
539 } else if ((ev_ptr == &event)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800540 || (ev_ptr ==
541 unaligned_event_ptr))
542 {
subrata_modak56207ce2009-03-23 13:35:39 +0000543 if (ev_ptr->events == 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800544 expected_errno =
545 EINVAL;
subrata_modak56207ce2009-03-23 13:35:39 +0000546 num_errors_expected++;
547 }
548
Wanlong Gao354ebb42012-12-07 10:10:04 +0800549 for (index = 1;
550 index < 64;
551 index++) {
552 if (ev_ptr->events != epoll_events[index]) {
553 expected_errno
554 =
555 EINVAL;
subrata_modak56207ce2009-03-23 13:35:39 +0000556 num_errors_expected++;
557 }
558 }
559 } else {
560 /* Do not expect an error */
561 }
562
563 if (num_errors_expected == 0) {
564 /* We did not expect an error */
565 if (result == 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800566 /* We didn't get an error. Think of this as RES_PASS_RETV_MAT_ERRNO_IGN */
subrata_modak56207ce2009-03-23 13:35:39 +0000567 return RES_PASS;
568 } else if (result == -1) { /* The return value is -1, so it's not bad */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800569 return
570 RES_FAIL_RETV_MIS_ERRNO_IGN;
subrata_modak56207ce2009-03-23 13:35:39 +0000571 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800572 return
573 RES_FAIL_RETV_BAD_ERRNO_IGN;
subrata_modak56207ce2009-03-23 13:35:39 +0000574 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800575 } else if (num_errors_expected
576 == 1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000577 /* We expected an error */
578 if (result == 0) {
579 return RES_FAIL_RETV_MIS_ERRNO_IGN; /* Unexpected success */
580 } else if (result == -1) {
581 /* We got an error. Check errno */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800582 if (errno ==
583 expected_errno)
584 {
subrata_modak56207ce2009-03-23 13:35:39 +0000585 return RES_PASS; /* think of this as RETV_MAT_ERRNO_MAT */
586 } else {
587 return
588 RES_FAIL_RETV_MAT_ERRNO_MIS;
589 }
590 } else {
591 /* We got a bad return code! Interpret this as
592 getting an error and check errno. */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800593 if (errno ==
594 expected_errno)
subrata_modak56207ce2009-03-23 13:35:39 +0000595 return
596 RES_FAIL_RETV_BAD_ERRNO_MAT;
597 else
598 return
599 RES_FAIL_RETV_BAD_ERRNO_MIS;
600 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800601 } else if (num_errors_expected >
602 1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000603 /* We expected multiple errors */
604 if (result == 0) {
605 return RES_FAIL_RETV_MIS_ERRNO_IGN; /* Unexpected success */
606 } else if (result == -1) {
607 /* We got an error. Check errno */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800608 if (errno ==
609 expected_errno)
610 {
subrata_modak56207ce2009-03-23 13:35:39 +0000611 return RES_PASS; /* think of this as RETV_MAT_ERRNO_MAT */
612 } else {
613 /* Ignore errno because the desired value is unknowable
614 without looking at the structure of the code. */
615 return
616 RES_PASS_RETV_MAT_ERRNO_IGN;
617 }
618 } else {
619 /* We got a bad return code! Interpret this as
620 getting an error and check errno. */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800621 if (errno ==
622 expected_errno)
subrata_modak56207ce2009-03-23 13:35:39 +0000623 /* Don't Ignore errno because the desired value
624 happened to match what we expected. */
625 return
626 RES_FAIL_RETV_BAD_ERRNO_MAT;
627 else
628 /* Ignore errno because the desired value is unknowable
629 without looking at the structure of the code. */
630 return
631 RES_FAIL_RETV_BAD_ERRNO_IGN;
632 }
633 }
634
635 /* All "return"s between PROTECT_REGION_BEGIN
636 and PROTECT_REGION_END place their value in
637 the result parameter. If the region caused
638 a protection violation (segfault or otherwise)
639 then the result is set to the second parameter's
640 value (-1 in this case). */
641 PROTECT_REGION_END(result, -1);
642
643 /* Count the number of tests run */
644 num_epoll_ctl_test_calls++;
645
646 /* Now test the result */
647 if (!((result == RES_PASS)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800648 || (result ==
649 RES_PASS_RETV_MAT_ERRNO_IGN)))
650 {
651 if (result >
652 (sizeof
653 (result_strings) /
654 sizeof(const char
655 *))) {
656 /* Returned a result which has no corresponding text description */
subrata_modak56207ce2009-03-23 13:35:39 +0000657 EPOLL_CTL_TEST_FAIL
658 ("FIXME FIX ME BUG in Test Program itself!");
659 } else {
660 if (result == -1) /* Segfault during epoll_ctl call */
661 EPOLL_CTL_TEST_FAIL
662 ("Test arguments caused abnormal exit.");
663 else /* The 'normal' failiure */
664 EPOLL_CTL_TEST_FAIL
Wanlong Gao354ebb42012-12-07 10:10:04 +0800665 ((result_strings[result]));
subrata_modak56207ce2009-03-23 13:35:39 +0000666 }
667 num_epoll_ctl_test_fails++;
czhang@redhat.comf8df4b52011-03-30 22:32:35 +0800668#ifdef DEBUG
subrata_modak56207ce2009-03-23 13:35:39 +0000669 } else /* The call of epoll_ctl behaved as expected */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800670 EPOLL_CTL_TEST_PASS((result_strings[result]));
czhang@redhat.comf8df4b52011-03-30 22:32:35 +0800671#else
672 }
673#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000674 }
675 }
676 }
mridgeb0a63b62004-03-03 21:36:28 +0000677 }
subrata_modak56207ce2009-03-23 13:35:39 +0000678 close(epoll_fd);
mridgeb0a63b62004-03-03 21:36:28 +0000679 }
mridgeb0a63b62004-03-03 21:36:28 +0000680
subrata_modak56207ce2009-03-23 13:35:39 +0000681 tst_resm(TINFO,
682 "Summary: Of %d tests, epoll_ctl failed %d (%3.0f%% passed).",
683 num_epoll_ctl_test_calls, num_epoll_ctl_test_fails,
684 ((float)(num_epoll_ctl_test_calls - num_epoll_ctl_test_fails) *
685 100.0f / (float)num_epoll_ctl_test_calls));
686 return (num_epoll_ctl_test_fails / num_epoll_ctl_test_calls);
mridgeb0a63b62004-03-03 21:36:28 +0000687}
688
subrata_modak56207ce2009-03-23 13:35:39 +0000689int main(int argc, char **argv)
mridgeb0a63b62004-03-03 21:36:28 +0000690{
subrata_modak56207ce2009-03-23 13:35:39 +0000691 int epoll_fd;
692 struct timeval tv;
693 int last_result;
mridgeb0a63b62004-03-03 21:36:28 +0000694
subrata_modak56207ce2009-03-23 13:35:39 +0000695 tst_resm(TINFO, "testing if epoll() system call works");
mridgeb0a63b62004-03-03 21:36:28 +0000696
subrata_modak56207ce2009-03-23 13:35:39 +0000697 /* Get the current time */
698 if (gettimeofday(&tv, NULL) != 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800699 tst_brkm(TBROK | TERRNO, NULL, "gettimeofday failed");
subrata_modak56207ce2009-03-23 13:35:39 +0000700 } else {
701 tst_resm(TINFO, "gettimeofday() works");
702 }
mridgeb0a63b62004-03-03 21:36:28 +0000703
subrata_modak56207ce2009-03-23 13:35:39 +0000704 /* Set up RNG */
705 srand(tv.tv_usec);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800706 tst_resm(TINFO,
707 "random number seeded with gettimeofday() [seed = %ld] works",
708 tv.tv_usec);
mridgeb0a63b62004-03-03 21:36:28 +0000709
subrata_modak56207ce2009-03-23 13:35:39 +0000710 tst_resm(TINFO, "Testing epoll_create");
711 /* Testing epoll_create with some different sizes */
712 last_result = PROTECT_FUNC(test_epoll_create, -1, NUM_RAND_ATTEMPTS);
713 if (last_result != 0) {
714 /* create test(s) failed */
715 }
mridgeb0a63b62004-03-03 21:36:28 +0000716
subrata_modak56207ce2009-03-23 13:35:39 +0000717 /* Create an epoll_fd for testing epoll_ctl */
718 epoll_fd = epoll_create(BACKING_STORE_SIZE_HINT);
719 if (epoll_fd < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800720 tst_brkm(TFAIL | TERRNO, NULL, "epoll_create failed");
subrata_modak56207ce2009-03-23 13:35:39 +0000721 }
722
723 tst_resm(TINFO, "Testing epoll_ctl");
724 last_result = PROTECT_FUNC(test_epoll_ctl, -1, epoll_fd);
725 if (last_result != 0) {
726 /* ctl test(s) failed */
727 }
728
Garrett Cooper53740502010-12-16 00:04:01 -0800729 tst_exit();
mridgeb0a63b62004-03-03 21:36:28 +0000730}
subrata_modakc81d7b92009-09-09 17:48:08 +0000731
732#else
733
734int main(void)
735{
Garrett Cooper53740502010-12-16 00:04:01 -0800736 tst_brkm(TCONF, NULL, "No epoll support found.");
subrata_modakc81d7b92009-09-09 17:48:08 +0000737}
738
czhang@redhat.comf8df4b52011-03-30 22:32:35 +0800739#endif