Home | History | Annotate | Download | only in aio01
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2003
      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
     17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     18  */
     19 
     20 /*
     21  * NAME
     22  *      aiotest1.c
     23  *
     24  * DESCRIPTION
     25  *      Perform aio read, write operations for given number of requests.
     26  *      Submit i/o for each request individually.
     27  *      Repeat the test for each of the following cases and measure time.
     28  *              Testblock1: Write one request at a time.
     29  *              Testblock2: Read one request at a time.
     30  *              Testblock3: Prepare, Write one request at a time.
     31  *              Testblock4: Prepare, Read one request at a time.
     32  *              Testblock5: Prepare, Write/Read one request at a time.
     33  *              Testblock6: Prepare, Write/Read/Verify one request at a time.
     34  *
     35  * Author
     36  * 08/24/2002   Narasimha Sharoff       nsharoff (at) us.ibm.com
     37 */
     38 
     39 /*
     40  * History
     41  *      04/18/2003      nsharoff (at) us.ibm.com
     42  *      		Updated
     43  *      05/21/2003      Paul Larson	plars (at) linuxtestproject.org
     44  *      		Rewrote the test under LTP, using LTP test harness
     45  *      		and other minor improvements and fixes
     46 */
     47 
     48 #define _XOPEN_SOURCE 600
     49 
     50 #include <stdio.h>
     51 #include <stdlib.h>
     52 #include <unistd.h>
     53 #include <fcntl.h>
     54 #include <time.h>
     55 #include <errno.h>
     56 #include <sys/types.h>
     57 #include <sys/stat.h>
     58 #include <sys/time.h>
     59 #include <sys/resource.h>
     60 
     61 #include "test.h"
     62 #include "config.h"
     63 
     64 char *TCID = "aio01";
     65 int TST_TOTAL = 6;
     66 
     67 #ifdef HAVE_LIBAIO
     68 #include <libaio.h>
     69 
     70 static void help(void);
     71 static void setup(void);
     72 static void cleanup(void);
     73 
     74 #define mapsize (1 << 14)
     75 
     76 int fd;
     77 char *maddr;
     78 
     79 size_t bufsize;			/* Size of I/O, 8k default */
     80 io_context_t io_ctx;		/* I/O Context */
     81 struct iocb **iocbs;		/* I/O Control Blocks */
     82 char *srcbuf, *dstbuf;
     83 char fname[128];
     84 char tbuf[80];
     85 int pos, nr;
     86 struct stat s;
     87 
     88 struct test_case_t {
     89 	off_t newsize;
     90 	char *desc;
     91 } TC[] = {
     92 	{
     93 	mapsize - 8192, "ftruncate mmaped file to a smaller size"}, {
     94 	mapsize + 1024, "ftruncate mmaped file to a larger size"}, {
     95 0, "ftruncate mmaped file to 0 size"},};
     96 
     97 int main(int argc, char **argv)
     98 {
     99 	int i, j, sec, usec;
    100 	int failflag = 0;
    101 	int bflag = 0, nflag = 0, Fflag = 0;
    102 	char *optb, *optn, *optF;
    103 	struct io_event event;
    104 	static struct timespec ts;
    105 	struct timeval stv, etv;
    106 
    107 	option_t options[] = {
    108 		{"b:", &bflag, &optb},
    109 		{"n:", &nflag, &optn},
    110 		{"F:", &Fflag, &optF},
    111 		{NULL, NULL, NULL}
    112 	};
    113 
    114 	tst_parse_opts(argc, argv, options, &help);
    115 
    116 	bufsize = (bflag ? atoi(optb) : 8192);
    117 	nr = (nflag ? atoi(optn) : 10);
    118 	if (Fflag) {
    119 		sprintf(fname, "%s", optF);
    120 	} else {
    121 		sprintf(fname, "aiofile");
    122 	}
    123 
    124 	setup();
    125 
    126 /* TEST 1 */
    127 	pos = 0;
    128 	gettimeofday(&stv, NULL);
    129 	io_prep_pwrite(iocbs[0], fd, srcbuf, bufsize, pos);
    130 	for (i = 0; i < nr; i++) {
    131 		ts.tv_sec = 30;
    132 		ts.tv_nsec = 0;
    133 		do {
    134 			TEST(io_submit(io_ctx, 1, iocbs));
    135 		} while (TEST_RETURN == -EAGAIN);
    136 		if (TEST_RETURN < 0) {
    137 			tst_resm(TFAIL, "Test 1: io_submit failed - retval=%ld"
    138 				 ", errno=%d", TEST_RETURN, TEST_ERRNO);
    139 			failflag = 1;
    140 			continue;
    141 		}
    142 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    143 		gettimeofday(&etv, NULL);
    144 	}
    145 	if (!failflag) {
    146 		sec = etv.tv_sec - stv.tv_sec;
    147 		usec = etv.tv_usec - stv.tv_usec;
    148 		if (usec < 0) {
    149 			usec += 1000000;
    150 			sec--;
    151 		}
    152 		tst_resm(TPASS, "Test 1: %d writes in %3d.%06d sec",
    153 			 nr, sec, usec);
    154 	}
    155 
    156 /* TEST 2 */
    157 	pos = 0;
    158 	failflag = 0;
    159 	gettimeofday(&stv, NULL);
    160 	io_prep_pread(iocbs[0], fd, dstbuf, bufsize, pos);
    161 	for (i = 0; i < nr; i++) {
    162 		ts.tv_sec = 30;
    163 		ts.tv_nsec = 0;
    164 		do {
    165 			TEST(io_submit(io_ctx, 1, iocbs));
    166 		} while (TEST_RETURN == -EAGAIN);
    167 		if (TEST_RETURN < 0) {
    168 			tst_resm(TFAIL, "Test 2: io_submit failed - retval=%ld"
    169 				 ", errno=%d", TEST_RETURN, TEST_ERRNO);
    170 			failflag = 1;
    171 			continue;
    172 		}
    173 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    174 		gettimeofday(&etv, NULL);
    175 	}
    176 	if (!failflag) {
    177 		sec = etv.tv_sec - stv.tv_sec;
    178 		usec = etv.tv_usec - stv.tv_usec;
    179 		if (usec < 0) {
    180 			usec += 1000000;
    181 			sec--;
    182 		}
    183 		tst_resm(TPASS, "Test 2: %d reads in %3d.%06d sec",
    184 			 nr, sec, usec);
    185 	}
    186 
    187 /* TEST 3 */
    188 	pos = 0;
    189 	failflag = 0;
    190 	gettimeofday(&stv, NULL);
    191 	for (i = 0; i < nr; i++) {
    192 		io_prep_pwrite(iocbs[0], fd, srcbuf, bufsize, pos);
    193 		ts.tv_sec = 30;
    194 		ts.tv_nsec = 0;
    195 		do {
    196 			TEST(io_submit(io_ctx, 1, iocbs));
    197 		} while (TEST_RETURN == -EAGAIN);
    198 		if (TEST_RETURN < 0) {
    199 			tst_resm(TFAIL, "Test 3: io_submit failed - retval=%ld"
    200 				 ", errno=%d", TEST_RETURN, TEST_ERRNO);
    201 			failflag = 1;
    202 			continue;
    203 		}
    204 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    205 		gettimeofday(&etv, NULL);
    206 	}
    207 	if (!failflag) {
    208 		sec = etv.tv_sec - stv.tv_sec;
    209 		usec = etv.tv_usec - stv.tv_usec;
    210 		if (usec < 0) {
    211 			usec += 1000000;
    212 			sec--;
    213 		}
    214 		tst_resm(TPASS, "Test 3: %d prep,writes in %3d.%06d sec",
    215 			 nr, sec, usec);
    216 	}
    217 
    218 /* TEST 4 */
    219 	pos = 0;
    220 	failflag = 0;
    221 	gettimeofday(&stv, NULL);
    222 	for (i = 0; i < nr; i++) {
    223 		io_prep_pread(iocbs[0], fd, dstbuf, bufsize, pos);
    224 		ts.tv_sec = 30;
    225 		ts.tv_nsec = 0;
    226 		do {
    227 			TEST(io_submit(io_ctx, 1, iocbs));
    228 		} while (TEST_RETURN == -EAGAIN);
    229 		if (TEST_RETURN < 0) {
    230 			tst_resm(TFAIL, "Test 4: io_submit failed - retval=%ld"
    231 				 ", errno=%d", TEST_RETURN, TEST_ERRNO);
    232 			failflag = 1;
    233 			continue;
    234 		}
    235 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    236 		gettimeofday(&etv, NULL);
    237 	}
    238 	if (!failflag) {
    239 		sec = etv.tv_sec - stv.tv_sec;
    240 		usec = etv.tv_usec - stv.tv_usec;
    241 		if (usec < 0) {
    242 			usec += 1000000;
    243 			sec--;
    244 		}
    245 		tst_resm(TPASS, "Test 4: %d prep,reads in %3d.%06d sec",
    246 			 nr, sec, usec);
    247 	}
    248 
    249 /* TEST 5 */
    250 	pos = 0;
    251 	failflag = 0;
    252 	gettimeofday(&stv, NULL);
    253 	for (i = 0; i < nr; i++) {
    254 		io_prep_pwrite(iocbs[0], fd, srcbuf, bufsize, pos);
    255 		ts.tv_sec = 30;
    256 		ts.tv_nsec = 0;
    257 		do {
    258 			TEST(io_submit(io_ctx, 1, iocbs));
    259 		} while (TEST_RETURN == -EAGAIN);
    260 		if (TEST_RETURN < 0) {
    261 			tst_resm(TFAIL, "Test 5: write io_submit failed - "
    262 				 "retval=%ld, errno=%d", TEST_RETURN,
    263 				 TEST_ERRNO);
    264 			failflag = 1;
    265 			continue;
    266 		}
    267 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    268 		io_prep_pread(iocbs[0], fd, dstbuf, bufsize, pos);
    269 		ts.tv_sec = 30;
    270 		ts.tv_nsec = 0;
    271 		do {
    272 			TEST(io_submit(io_ctx, 1, iocbs));
    273 		} while (TEST_RETURN == -EAGAIN);
    274 		if (TEST_RETURN < 0) {
    275 			tst_resm(TFAIL, "Test 5: read io_submit failed - "
    276 				 "retval=%ld, errno=%d", TEST_RETURN,
    277 				 TEST_ERRNO);
    278 			failflag = 1;
    279 			continue;
    280 		}
    281 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    282 		gettimeofday(&etv, NULL);
    283 	}
    284 	if (!failflag) {
    285 		sec = etv.tv_sec - stv.tv_sec;
    286 		usec = etv.tv_usec - stv.tv_usec;
    287 		if (usec < 0) {
    288 			usec += 1000000;
    289 			sec--;
    290 		}
    291 		tst_resm(TPASS, "Test 5: %d reads and writes in %3d.%06d sec",
    292 			 nr, sec, usec);
    293 	}
    294 
    295 /* TEST 6 */
    296 	pos = 0;
    297 	failflag = 0;
    298 	gettimeofday(&stv, NULL);
    299 	for (i = 0; i < nr; i++) {
    300 		io_prep_pwrite(iocbs[0], fd, srcbuf, bufsize, pos);
    301 		ts.tv_sec = 30;
    302 		ts.tv_nsec = 0;
    303 		do {
    304 			TEST(io_submit(io_ctx, 1, iocbs));
    305 		} while (TEST_RETURN == -EAGAIN);
    306 		if (TEST_RETURN < 0) {
    307 			tst_resm(TFAIL, "Test 6: write io_submit failed - "
    308 				 "retval=%ld, errno=%d", TEST_RETURN,
    309 				 TEST_ERRNO);
    310 			failflag = 1;
    311 			continue;
    312 		}
    313 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    314 		io_prep_pread(iocbs[0], fd, dstbuf, bufsize, pos);
    315 		ts.tv_sec = 30;
    316 		ts.tv_nsec = 0;
    317 		do {
    318 			TEST(io_submit(io_ctx, 1, iocbs));
    319 		} while (TEST_RETURN == -EAGAIN);
    320 		if (TEST_RETURN < 0) {
    321 			tst_resm(TFAIL, "Test 6: read io_submit failed - "
    322 				 "retval=%ld, errno=%d", TEST_RETURN,
    323 				 TEST_ERRNO);
    324 			failflag = 1;
    325 			continue;
    326 		}
    327 		while (io_getevents(io_ctx, 1, 1, &event, &ts) != 1) ;
    328 		for (j = 0; j < bufsize; j++) {
    329 			if (srcbuf[j] != dstbuf[j]) {
    330 				tst_resm(TFAIL, "Test 6: compare failed - "
    331 					 "read: %c, " "actual: %c",
    332 					 dstbuf[j], srcbuf[j]);
    333 				break;
    334 			}
    335 		}
    336 		gettimeofday(&etv, NULL);
    337 	}
    338 	if (!failflag) {
    339 		sec = etv.tv_sec - stv.tv_sec;
    340 		usec = etv.tv_usec - stv.tv_usec;
    341 		if (usec < 0) {
    342 			usec += 1000000;
    343 			sec--;
    344 		}
    345 		tst_resm(TPASS, "Test 6: %d read,write,verify in %d.%06d sec",
    346 			 i, sec, usec);
    347 	}
    348 
    349 	cleanup();
    350 
    351 	tst_exit();
    352 }
    353 
    354 static void help(void)
    355 {
    356 	printf("  -b n    Buffersize\n");
    357 	printf("  -n n    Number of requests\n");
    358 	printf("  -F s    Filename to run the tests against\n");
    359 }
    360 
    361 static void setup(void)
    362 {
    363 	int ret;
    364 
    365 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    366 
    367 	/* Pause if option was specified */
    368 	TEST_PAUSE;
    369 
    370 	tst_tmpdir();
    371 
    372 	if ((fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0)
    373 		tst_brkm(TFAIL, cleanup, "failed to open %s "
    374 			 "file, errno: %d", fname, errno);
    375 	stat(fname, &s);
    376 	if ((iocbs = malloc(sizeof(int) * nr)) == NULL)
    377 		tst_brkm(TFAIL, cleanup, "malloc for iocbs failed - "
    378 			 "errno: %d", errno);
    379 	if ((iocbs[0] = malloc(sizeof(struct iocb))) == NULL)
    380 		tst_brkm(TFAIL, cleanup, "malloc for iocbs elements failed - "
    381 			 "errno: %d", errno);
    382 	if (S_ISCHR(s.st_mode)) {
    383 		if ((ret =
    384 		     posix_memalign((void **)&srcbuf, bufsize, bufsize)) != 0)
    385 			tst_brkm(TFAIL, cleanup,
    386 				 "posix_memalign for srcbuf "
    387 				 "failed - errno: %d", errno);
    388 		if ((ret =
    389 		     posix_memalign((void **)&dstbuf, bufsize, bufsize)) != 0)
    390 			tst_brkm(TFAIL, cleanup,
    391 				 "posix_memalign for dstbuf "
    392 				 "failed - errno: %d", errno);
    393 	} else {
    394 		if ((srcbuf = malloc(sizeof(char) * bufsize)) == NULL)
    395 			tst_brkm(TFAIL, cleanup, "malloc for srcbuf "
    396 				 "failed - errno: %d", errno);
    397 		if ((dstbuf = malloc(sizeof(char) * bufsize)) == NULL)
    398 			tst_brkm(TFAIL, cleanup, "malloc for dstbuf "
    399 				 "failed - errno: %d", errno);
    400 	}
    401 	memset((void *)srcbuf, 65, bufsize);
    402 	if ((ret = io_queue_init(1, &io_ctx)) != 0)
    403 		tst_brkm(TFAIL, cleanup, "io_queue_init failed: %s",
    404 			 strerror(ret));
    405 }
    406 
    407 static void cleanup(void)
    408 {
    409 	free(dstbuf);
    410 	free(srcbuf);
    411 	free(iocbs[0]);
    412 	free(iocbs);
    413 	close(fd);
    414 	io_queue_release(io_ctx);
    415 	tst_rmdir();
    416 }
    417 
    418 #else
    419 int main(void)
    420 {
    421 	tst_brkm(TCONF, NULL, "test requires libaio and it's development packages");
    422 }
    423 #endif
    424