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