1 /*
2 *
3 * Copyright (c) Crackerjack Project., 2007
4 * Copyright (c) 2011 Cyril Hrubis <chrubis@suse.cz>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /* Porting from Crackerjack to LTP is done
22 by Masatake YAMATO <yamato@redhat.com> */
23
24 #include "config.h"
25 #include "test.h"
26
27 char *TCID = "io_submit01";
28
29 int TST_TOTAL = 3;
30
31 #ifdef HAVE_LIBAIO_H
32 #include <libaio.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <fcntl.h>
36
37 #define TESTFILE "testfile"
38
cleanup(void)39 static void cleanup(void)
40 {
41 tst_rmdir();
42 }
43
setup(void)44 static void setup(void)
45 {
46 int fd;
47
48 tst_sig(NOFORK, DEF_HANDLER, cleanup);
49
50 TEST_PAUSE;
51
52 tst_tmpdir();
53
54 fd = open(TESTFILE, O_CREAT | O_RDWR, 0755);
55 if (fd == -1)
56 tst_brkm(TBROK | TERRNO, cleanup, "open");
57 if (close(fd) == -1)
58 tst_brkm(TBROK | TERRNO, cleanup, "close");
59 }
60
check_result(long exp,long act)61 static void check_result(long exp, long act)
62 {
63 if (exp >= 0) {
64 if (act == exp)
65 tst_resm(TPASS, "expected success - "
66 "returned value = %ld", act);
67 else
68 tst_resm(TFAIL, "unexpected failure - "
69 "returned value = %ld : %s",
70 act, strerror(-1 * act));
71 return;
72 }
73
74 /* if return value is expected to be < 0 */
75 if (act == exp)
76 tst_resm(TPASS, "expected failure - "
77 "returned value = %ld : %s", act, strerror(-1 * act));
78 else if (act == 0)
79 tst_resm(TFAIL, "call succeeded unexpectedly");
80 else
81 tst_resm(TFAIL, "unexpected failure - "
82 "returned value = %ld : %s, "
83 "expected value = %ld : %s",
84 act, strerror(-1 * act), exp, strerror(-1 * exp));
85 }
86
main(int argc,char * argv[])87 int main(int argc, char *argv[])
88 {
89 int lc;
90
91 int rval, fd;
92 char buf[256];
93 struct iocb iocb;
94 struct iocb *iocbs[1];
95 io_context_t ctx;
96
97 tst_parse_opts(argc, argv, NULL, NULL);
98
99 setup();
100
101 for (lc = 0; TEST_LOOPING(lc); lc++) {
102 tst_count = 0;
103
104 /* 1 - EINVAL */
105 /* 1.1 - EINVAL: invalid ctx */
106 memset(&ctx, 0, sizeof(ctx));
107 TEST(io_submit(ctx, 0, NULL));
108 check_result(-EINVAL, TEST_RETURN);
109
110 /* 1.2 - EINVAL: invalid nr */
111 rval = io_setup(1, &ctx);
112 if (rval != 0)
113 tst_brkm(TBROK, cleanup, "io_setup failed: %d", rval);
114 TEST(io_submit(ctx, -1, NULL));
115 check_result(-EINVAL, TEST_RETURN);
116
117 /* 1.3 - EINVAL: uninitialized iocb */
118 iocbs[0] = &iocb;
119
120 /* There are multiple checks we can hit with uninitialized
121 * iocb, but with "random" data it's not 100%. Make sure we
122 * fail eventually in opcode check. */
123 iocb.aio_lio_opcode = -1;
124
125 TEST(io_submit(ctx, 1, iocbs));
126 switch (TEST_RETURN) {
127 case -EINVAL:
128 case -EBADF:
129 case -EFAULT:
130 tst_resm(TPASS, "expected failure - "
131 "returned value = %ld : %s",
132 TEST_RETURN, strerror(-1 * TEST_RETURN));
133 break;
134 default:
135 tst_resm(TFAIL, "unexpected failure - "
136 "returned value = %ld : %s, "
137 "expected one of -EINVAL, -EBADF, -EFAULT",
138 TEST_RETURN, strerror(-1 * TEST_RETURN));
139 }
140
141 /* 2 - EFAULT: iocb points to invalid data */
142 TEST(io_submit(ctx, 1, (struct iocb **)-1));
143 check_result(-EFAULT, TEST_RETURN);
144
145 /*
146 * 3 - Special case EFAULT or EINVAL (indetermination)
147 *
148 * The errno depends on the per architecture implementation
149 * of io_submit. On the architecture using compat_sys_io_submit
150 * as its implementation, errno is set to -EINVAL.
151 */
152 TEST(io_submit(ctx, -1, (struct iocb **)-1));
153 if (TEST_RETURN == 0)
154 tst_resm(TFAIL, "call succeeded unexpectedly");
155 else if (TEST_RETURN == -EFAULT || TEST_RETURN == -EINVAL)
156 tst_resm(TPASS, "expected failure - "
157 "returned value = %ld : %s",
158 TEST_RETURN, strerror(-1 * TEST_RETURN));
159 else
160 tst_resm(TFAIL, "unexpected failure - "
161 "returned value = %ld : %s, "
162 "expected = %d : %s or %d : %s",
163 TEST_RETURN, strerror(-1 * TEST_RETURN),
164 -EFAULT, strerror(EFAULT),
165 -EINVAL, strerror(EINVAL));
166
167 /*
168 * 4 - EBADF: fd in iocb is invalid
169 */
170 io_prep_pread(&iocb, -1, buf, sizeof(buf), 0);
171 iocbs[0] = &iocb;
172 TEST(io_submit(ctx, 1, iocbs));
173 check_result(-EBADF, TEST_RETURN);
174
175 /* 5 - Positive test: nr == 0 */
176 TEST(io_submit(ctx, 0, NULL));
177 check_result(0, TEST_RETURN);
178
179 /* 6 - Positive test: valid fd */
180 fd = open(TESTFILE, O_RDONLY);
181 if (fd == -1)
182 tst_resm(TBROK | TERRNO, "open");
183 io_prep_pread(&iocb, fd, buf, sizeof(buf), 0);
184 iocbs[0] = &iocb;
185 TEST(io_submit(ctx, 1, iocbs));
186 check_result(1, TEST_RETURN);
187 if (close(fd) == -1)
188 tst_resm(TBROK | TERRNO, "close");
189
190 }
191 cleanup();
192
193 tst_exit();
194 }
195 #else
main(int argc,char * argv[])196 int main(int argc, char *argv[])
197 {
198 tst_brkm(TCONF, NULL, "System doesn't support execution of the test");
199 }
200 #endif
201