1 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <string.h> 6 #include <ctype.h> 7 #include <errno.h> 8 #include <math.h> 9 #include <time.h> 10 #include <ftw.h> 11 #include <sys/types.h> 12 #include <sys/stat.h> 13 #include <fcntl.h> 14 #include <sys/ioctl.h> 15 #include <linux/kd.h> 16 #include <linux/errno.h> 17 18 #include "Ltpfs.h" 19 20 #define M_2PI (M_PI*2) 21 #define MAXN 4096 22 #define MAXFSIZE 1024 * 192 23 #define FILE_CREATE_COUNT 256 24 #define FAIL 0 25 #define SUCCESS 1 26 #define MAXNUM 5000 27 #define BUFFSIZE 8192 28 #define AVEFSIZE (MAXFSIZE/2) 29 #define POOLDISKSPACE (AVEFSIZE*128) 30 #define MAXERROR 1024 31 #define FILES_ONLY 0x01 32 #define ALL 0x00 33 34 // Globals 35 36 char wbuf[MAXFSIZE]; 37 int startc = 0; 38 int showchar[] = { 124, 47, 45, 92, 124, 47, 45, 92 }; 39 40 int nullFileHandle; 41 int openlog[2] = { 0, 0 }; 42 43 int cFileCount, dFileCount, errorCount; 44 static int disk_space_pool = 0; 45 char rootPath[BUFFSIZE]; 46 47 int LTP_fs_open_block_device(void); 48 int do_fs_thump_tests(char *path); 49 int do_create_file_test(char *path); 50 int makedir(char *dir1); 51 int changedir(char *dir); 52 int do_random_access_test(int maxNum); 53 int do_random_create_delete(int maxNum); 54 int create_file(char *filename); 55 int delete_file(char *filename); 56 int gen_random_file_size(int min, int max); 57 int open_read_close(char *fname); 58 int create_or_delete(char *fname); 59 int do_tree_cleanup(char *path, int flag); 60 int cleanup_files(char *file, struct stat *statBuff, int flag); 61 int cleanup_dirs(char *file, struct stat *statBuff, int flag); 62 63 int ltp_block_dev_handle = 0; /* handle to LTP Test block device */ 64 int ltp_fileHandle = 0; 65 char *fileBuf; 66 67 int main(int argc, char **argv) 68 { 69 70 ltpdev_cmd_t cmd = { 0, 0 }; 71 int rc, i, tmpHandle; 72 struct stat statBuf; 73 74 printf("[%s] - Running test program\n", argv[0]); 75 76 rc = LTP_fs_open_block_device(); 77 78 if (!rc) { 79 80 ltp_block_dev_handle = open(LTP_FS_DEVICE_NAME, O_RDWR); 81 82 if (ltp_block_dev_handle < 0) { 83 printf 84 ("ERROR: Open of device %s failed %d errno = %d\n", 85 LTP_FS_DEVICE_NAME, ltp_block_dev_handle, errno); 86 } else { 87 rc = ioctl(ltp_block_dev_handle, LTPAIODEV_CMD, &cmd); 88 89 printf("return from AIO ioctl %d \n", rc); 90 91 rc = ioctl(ltp_block_dev_handle, LTPBIODEV_CMD, &cmd); 92 93 printf("return from BIO ioctl %d \n", rc); 94 } 95 96 } else { 97 printf("ERROR: Create/open block device failed\n"); 98 } 99 100 ltp_fileHandle = 101 open("/tmp/testfile", O_CREAT | O_RDWR | O_SYNC | FASYNC, 102 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 103 104 if (ltp_fileHandle > 0) { 105 106 tmpHandle = open("/usr/include/ctype.h", O_RDONLY); 107 108 if (tmpHandle > 0) { 109 110 rc = fstat(tmpHandle, &statBuf); 111 112 if (!rc) { 113 fileBuf = malloc(statBuf.st_size); 114 115 if (fileBuf) { 116 117 read(tmpHandle, fileBuf, 118 statBuf.st_size); 119 close(tmpHandle); 120 write(ltp_fileHandle, fileBuf, 121 statBuf.st_size); 122 123 for (i = 0; i < 100; i++) { 124 read(ltp_fileHandle, fileBuf, 125 statBuf.st_size * i); 126 write(ltp_fileHandle, fileBuf, 127 statBuf.st_size * i); 128 } 129 } 130 131 } 132 133 } else { 134 printf("ERROR: Create/open file failed\n"); 135 } 136 } 137 138 printf("*** Starting FileSystem thump tests....****\n"); 139 printf("*** Please be patient, this may take a little while... ***\n"); 140 141 for (i = 1; i < argc; i++) { 142 printf("Running test %d of %d on FileSystem %s \n", i, argc - 1, 143 argv[i]); 144 if (strcmp(argv[i], "|") != 0) { 145 strcpy(rootPath, argv[i]); 146 rc = do_fs_thump_tests(argv[i]); 147 if (rc != 0 && rc != ENOSPC) { 148 printf 149 ("ERROR: Failed on FileSystem %s with errno %d \n", 150 argv[i], rc); 151 } 152 } else { 153 printf("Test Program complete..\n"); 154 break; 155 } 156 157 } 158 159 printf("Test Program complete..\n"); 160 161 return 0; 162 } 163 164 int do_fs_thump_tests(char *path) 165 { 166 int rc = 0; 167 168 printf("Changing to directory %s \n", path); 169 170 changedir(path); 171 172 cFileCount = 0; 173 dFileCount = 0; 174 175 rc |= do_create_file_test(path); 176 rc |= do_random_access_test(MAXNUM); 177 rc |= do_tree_cleanup(path, FILES_ONLY); 178 rc |= do_random_create_delete(MAXNUM); 179 rc |= do_tree_cleanup(path, ALL); 180 181 return rc; 182 183 } 184 185 int do_tree_cleanup(char *path, int flag) 186 { 187 188 if (flag == FILES_ONLY) { 189 printf("Cleaning up test files...\n"); 190 ftw(path, (void *)cleanup_files, MAXNUM); 191 } else { 192 printf("Cleaning up everything in the test directory...\n"); 193 ftw(path, (void *)cleanup_files, MAXNUM); 194 ftw(path, (void *)cleanup_dirs, MAXNUM); 195 } 196 197 return 0; 198 } 199 200 int cleanup_files(char *file, struct stat *statBuff, int flag) 201 { 202 int rc = 0; 203 204 if (flag == FTW_F) { 205 if (unlink(file)) { 206 printf("ERROR:%d removing file %s\n", errno, file); 207 } 208 } 209 210 return rc; 211 } 212 213 int cleanup_dirs(char *file, struct stat *statBuff, int flag) 214 { 215 int rc = 0; 216 217 //printf("%s:Cleaning up directory %s \n", __FUNCTION__, file); 218 219 if (strcmp(rootPath, file) == 0) { 220 return 0; 221 } 222 223 if (flag == FTW_F) { 224 if (unlink(file)) { 225 printf("ERROR:%d removing file %s\n", errno, file); 226 } 227 } else if (flag == FTW_D) { 228 changedir(file); 229 ftw(file, (void *)cleanup_dirs, MAXNUM); 230 rmdir(file); 231 232 } else { 233 printf("No idea what we found here\n"); 234 } 235 236 return rc; 237 } 238 239 int do_create_file_test(char *path) 240 { 241 int i = 0; 242 int j = 0; 243 int k = 0; 244 int l = 0; 245 int rc = 0; 246 247 char dir1[MAXN]; 248 char dir2[MAXN]; 249 char dir3[MAXN]; 250 char filename[MAXN]; 251 252 time_t t; 253 254 int maxfiles = 0xFFFFFF; 255 256 time(&t); 257 258 srandom((unsigned int)getpid() ^ 259 (((unsigned int)t << 16) | (unsigned int)t >> 16)); 260 261 printf("Creating files...\n"); 262 263 for (i = 0; i < FILE_CREATE_COUNT; i++) { 264 265 sprintf(dir1, "%2.2x", i); 266 267 makedir(dir1); 268 269 changedir(dir1); 270 271 for (j = 0; j < FILE_CREATE_COUNT; j++) { 272 273 sprintf(dir2, "%2.2x", j); 274 275 makedir(dir2); 276 277 changedir(dir2); 278 279 for (k = 0; k < FILE_CREATE_COUNT; k++) { 280 281 sprintf(dir3, "%2.2x", k); 282 makedir(dir3); 283 changedir(dir3); 284 285 for (l = 0; l < FILE_CREATE_COUNT; l++) { 286 sprintf(filename, "%s%s%s%2.2x", dir1, 287 dir2, dir3, l); 288 rc = create_file(filename); 289 if (rc != 0 || maxfiles < dFileCount++) { 290 if (rc != ENOSPC) { 291 printf 292 ("ERROR: failed error:%d creating all the test files ! \n", 293 errno); 294 printf 295 ("ERROR2: rc:%d -- dFileCount:%d \n", 296 rc, dFileCount); 297 } 298 goto end; 299 } 300 } 301 changedir("../"); 302 } 303 changedir("../"); 304 } 305 changedir("../"); 306 } 307 end: 308 fprintf(stderr, "\nTotal create files: %d\n", cFileCount); 309 printf("Done\n"); 310 return rc; 311 } 312 313 int makedir(char *dir1) 314 { 315 if (mkdir(dir1, S_IRWXU) < 0) { 316 perror(dir1); 317 return (errno); 318 } 319 return 0; 320 } 321 322 int changedir(char *dir) 323 { 324 if (chdir(dir) < 0) { 325 perror(dir); 326 return (errno); 327 } 328 329 return 0; 330 } 331 332 int create_file(char *filename) 333 { 334 int fileHandle; 335 int randomsize; 336 337 if ((fileHandle = creat(filename, S_IRWXU)) < 0) { 338 339 fprintf(stderr, "\nERROR line %d: Total create files: %d\n", 340 __LINE__, cFileCount); 341 perror(filename); 342 return (errno); 343 } 344 345 if ((randomsize = gen_random_file_size(0, MAXFSIZE)) < 0) { 346 randomsize = MAXFSIZE; 347 } 348 if (write(fileHandle, wbuf, randomsize) < 0) { 349 350 fprintf(stderr, "\nERROR:%d line%d: Total create files: %d\n", 351 errno, __LINE__, cFileCount); 352 close(fileHandle); 353 354 perror(filename); 355 return (errno); 356 } 357 358 cFileCount++; 359 close(fileHandle); 360 return 0; 361 } 362 363 int delete_file(char *filename) 364 { 365 struct stat buf; 366 int st; 367 368 st = stat(filename, &buf); 369 370 if (st < 0) { 371 errorCount++; 372 printf("ERROR line %d: Getting file stats %s \n", __LINE__, 373 filename); 374 return (-1); 375 } 376 377 disk_space_pool += buf.st_size; 378 379 if (unlink(filename) < 0) { 380 errorCount++; 381 printf("ERROR line %d: Removing file %s \n", __LINE__, 382 filename); 383 return (-1); 384 } 385 386 dFileCount++; 387 return 0; 388 } 389 390 int LTP_fs_open_block_device() 391 { 392 dev_t devt; 393 struct stat statbuf; 394 int rc; 395 396 if (ltp_block_dev_handle == 0) { 397 398 /* check for the /dev/LTPFSTest subdir, and create if it does not exist. 399 * 400 * If devfs is running and mounted on /dev, these checks will all pass, 401 * so a new node will not be created. 402 */ 403 devt = makedev(LTPMAJOR, 0); 404 405 rc = stat(LTP_FS_DEV_NODE_PATH, &statbuf); 406 407 if (rc) { 408 if (errno == ENOENT) { 409 /* dev node does not exist. */ 410 rc = mkdir(LTP_FS_DEV_NODE_PATH, 411 (S_IFDIR | S_IRWXU | S_IRGRP | 412 S_IXGRP | S_IROTH | S_IXOTH)); 413 } else { 414 printf 415 ("ERROR: Problem with LTP FS dev directory. Error code from stat() is %d\n\n", 416 errno); 417 } 418 419 } else { 420 if (!(statbuf.st_mode & S_IFDIR)) { 421 rc = unlink(LTP_FS_DEV_NODE_PATH); 422 if (!rc) { 423 rc = mkdir(LTP_FS_DEV_NODE_PATH, 424 (S_IFDIR | S_IRWXU | S_IRGRP 425 | S_IXGRP | S_IROTH | 426 S_IXOTH)); 427 } 428 } 429 } 430 431 /* 432 * Check for the /dev/ltp-fs/block_device node, and create if it does not 433 * exist. 434 */ 435 rc = stat(LTP_FS_DEVICE_NAME, &statbuf); 436 if (rc) { 437 if (errno == ENOENT) { 438 /* dev node does not exist */ 439 rc = mknod(LTP_FS_DEVICE_NAME, 440 (S_IFBLK | S_IRUSR | S_IWUSR | 441 S_IRGRP | S_IWGRP), devt); 442 } else { 443 printf 444 ("ERROR:Problem with LTP FS block device node directory. Error code form stat() is %d\n\n", 445 errno); 446 } 447 448 } else { 449 /* 450 * /dev/ltp-fs/block_device exists. Check to make sure it is for a 451 * block device and that it has the right major and minor. 452 */ 453 if ((!(statbuf.st_mode & S_IFBLK)) || 454 (statbuf.st_rdev != devt)) { 455 456 /* Recreate the dev node. */ 457 rc = unlink(LTP_FS_DEVICE_NAME); 458 if (!rc) { 459 rc = mknod(LTP_FS_DEVICE_NAME, 460 (S_IFBLK | S_IRUSR | S_IWUSR 461 | S_IRGRP | S_IWGRP), devt); 462 } 463 } 464 } 465 466 } 467 468 return rc; 469 } 470 471 int gen_random_file_size(int min, int max) 472 { 473 double u1, u2, z; 474 int i; 475 int ave; 476 int range; 477 int ZZ; 478 if (min >= max) { 479 return (-1); 480 } 481 range = max - min; 482 ave = range / 2; 483 for (i = 0; i < 10; i++) { 484 u1 = ((double)(random() % 1000000)) / 1000000; 485 u2 = ((double)(random() % 1000000)) / 1000000; 486 z = sqrt(-2.0 * log(u1)) * cos(M_2PI * u2); 487 ZZ = min + (ave + (z * (ave / 4))); 488 if (ZZ >= min && ZZ < max) { 489 return (ZZ); 490 } 491 } 492 return (-1); 493 } 494 495 int do_random_access_test(int maxNum) 496 { 497 int r; 498 char fname[1024]; 499 time_t t; 500 int i; 501 502 printf("Running random access test...\n"); 503 changedir(rootPath); 504 505 if (maxNum < 1 || maxNum > MAXNUM) { 506 printf("out of size %d\n", maxNum); 507 return 1; 508 } 509 510 time(&t); 511 srandom((unsigned int)getpid() ^ 512 (((unsigned int)t << 16) | (unsigned int)t >> 16)); 513 514 if ((nullFileHandle = open("/dev/null", O_WRONLY)) < 0) { 515 perror("/dev/null"); 516 return (errno); 517 } 518 519 /* 00/00/00/00 */ 520 for (i = 0; i < maxNum; i++) { 521 522 r = random() % maxNum; 523 524 sprintf(fname, "00/%2.2x/%2.2x/00%2.2x%2.2x%2.2x", 525 ((r >> 16) & 0xFF), 526 ((r >> 8) & 0xFF), 527 ((r >> 16) & 0xFF), ((r >> 8) & 0xFF), (r & 0xFF)); 528 529 open_read_close(fname); 530 } 531 close(nullFileHandle); 532 printf("Success:\t%d\nFail:\t%d\n", openlog[SUCCESS], openlog[FAIL]); 533 return 0; 534 } 535 536 int open_read_close(char *fname) 537 { 538 int fileHandle, fileHandle2; 539 char buffer[BUFFSIZE]; 540 int c; 541 542 if ((fileHandle = open(fname, O_RDONLY | O_SYNC | O_ASYNC)) < 0) { 543 openlog[FAIL]++; 544 printf("ERROR:opening file %s failed %d \n", fname, errno); 545 return (errno); 546 } 547 548 if ((fileHandle2 = open(fname, O_RDONLY | O_SYNC | O_ASYNC)) < 0) { 549 openlog[FAIL]++; 550 printf("ERROR:2nd opening file %s failed %d \n", fname, errno); 551 return (errno); 552 } 553 554 openlog[SUCCESS]++; 555 556 while ((c = read(fileHandle, buffer, BUFFSIZE)) > 0) { 557 if (write(nullFileHandle, buffer, c) < 0) { 558 perror("/dev/null"); 559 printf("Opened\t %d\nUnopend:\t%d\n", openlog[SUCCESS], 560 openlog[FAIL]); 561 close(fileHandle2); 562 close(fileHandle); 563 return (errno); 564 } 565 if ((c = read(fileHandle2, buffer, BUFFSIZE)) > 0) { 566 if (write(nullFileHandle, buffer, c) < 0) { 567 perror("/dev/null"); 568 printf("Opened\t %d\nUnopend:\t%d\n", 569 openlog[SUCCESS], openlog[FAIL]); 570 close(fileHandle2); 571 close(fileHandle); 572 return (errno); 573 } 574 } 575 } 576 577 if (c < 0) { 578 perror(fname); 579 printf("Opened\t %d\nUnopend:\t%d\n", openlog[SUCCESS], 580 openlog[FAIL]); 581 return (errno); 582 } 583 584 close(fileHandle2); 585 close(fileHandle); 586 return 0; 587 } 588 589 int create_or_delete(char *fname) 590 { 591 int r, rc; 592 593 r = (random() & 1); 594 595 /* create */ 596 if ((create_file(fname) == 0)) { 597 rc = delete_file(fname); 598 } else { 599 printf("Error: %d creating random file \n", errno); 600 } 601 602 if ((errorCount > dFileCount || errorCount > cFileCount) 603 && (errorCount > MAXERROR)) { 604 fprintf(stderr, "Too many errors -- Aborting test\n"); 605 fprintf(stderr, "Total create files: %d\n", cFileCount); 606 fprintf(stderr, "Total delete files: %d\n", dFileCount); 607 fprintf(stderr, "Total error : %d\n", errorCount); 608 return (MAXERROR); 609 } 610 611 return 0; 612 } 613 614 int do_random_create_delete(int maxNum) 615 { 616 int r, rc = 0; 617 char fname[1024]; 618 time_t t; 619 int i; 620 621 printf("Running random create/delete test...\n"); 622 623 if (maxNum < 1 || maxNum > MAXNUM) { 624 printf("MAX out of size %d\n", maxNum); 625 return (maxNum); 626 } 627 628 time(&t); 629 srandom((unsigned int)getpid() ^ 630 (((unsigned int)t << 16) | (unsigned int)t >> 16)); 631 632 /* 00/00/00/00 */ 633 for (i = 0; i < maxNum && rc != MAXERROR; i++) { 634 r = random() % maxNum; 635 sprintf(fname, "00/%2.2x/%2.2x/00%2.2x%2.2x%2.2x", 636 ((r >> 16) & 0xFF), 637 ((r >> 8) & 0xFF), 638 ((r >> 16) & 0xFF), ((r >> 8) & 0xFF), (r & 0xFF)); 639 640 rc = create_or_delete(fname); 641 } 642 643 fprintf(stderr, "Total create files: %d\n", cFileCount); 644 fprintf(stderr, "Total delete files: %d\n", dFileCount); 645 fprintf(stderr, "Total error : %d\n", errorCount); 646 return (rc); 647 } 648