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