1 /* 2 * 3 * Copyright (c) Crackerjack Project., 2007 4 * Copyright (c) 2011 Cyril Hrubis <chrubis (at) 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 (at) 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 39 static void cleanup(void) 40 { 41 tst_rmdir(); 42 } 43 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 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 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 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