Home | History | Annotate | Download | only in io_submit
      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