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