| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <ctype.h> |
| #include <errno.h> |
| #include <math.h> |
| #include <time.h> |
| #include <ftw.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <sys/ioctl.h> |
| #include <linux/kd.h> |
| #include <linux/errno.h> |
| |
| #include "Ltpfs.h" |
| |
| #define M_2PI (M_PI*2) |
| #define MAXN 4096 |
| #define MAXFSIZE 1024 * 192 |
| #define FILE_CREATE_COUNT 256 |
| #define FAIL 0 |
| #define SUCCESS 1 |
| #define MAXNUM 5000 |
| #define BUFFSIZE 8192 |
| #define AVEFSIZE (MAXFSIZE/2) |
| #define POOLDISKSPACE (AVEFSIZE*128) |
| #define MAXERROR 1024 |
| #define FILES_ONLY 0x01 |
| #define ALL 0x00 |
| |
| // Globals |
| |
| char wbuf[MAXFSIZE]; |
| int startc=0; |
| int showchar[]={124,47,45,92,124,47,45,92}; |
| int nullFileHandle; |
| int openlog[2]={0,0}; |
| int cFileCount, dFileCount, errorCount; |
| static int disk_space_pool = 0; |
| char rootPath[BUFFSIZE]; |
| |
| int LTP_fs_open_block_device(void); |
| int do_fs_thump_tests(char * path); |
| int do_create_file_test(char * path); |
| int makedir(char *dir1); |
| int changedir(char *dir); |
| int do_random_access_test(int maxNum); |
| int do_random_create_delete(int maxNum); |
| int create_file(char *filename); |
| int delete_file(char *filename); |
| int gen_random_file_size(int min, int max); |
| int open_read_close(char *fname); |
| int create_or_delete(char *fname); |
| int do_tree_cleanup(char *path, int flag); |
| int cleanup_files(char * file, struct stat * statBuff, int flag); |
| int cleanup_dirs(char * file, struct stat * statBuff, int flag); |
| |
| |
| int ltp_block_dev_handle = 0; /* handle to LTP Test block device */ |
| int ltp_fileHandle = 0; |
| char * fileBuf; |
| |
| int main(int argc, char **argv) |
| { |
| |
| ltpdev_cmd_t cmd = {0,0}; |
| int rc, i, tmpHandle; |
| struct stat statBuf; |
| |
| printf("[%s] - Running test program\n", argv[0]); |
| |
| rc = LTP_fs_open_block_device(); |
| |
| if (!rc) { |
| |
| ltp_block_dev_handle = open(LTP_FS_DEVICE_NAME, O_RDWR); |
| |
| if (ltp_block_dev_handle < 0) { |
| printf("ERROR: Open of device %s failed %d errno = %d\n", LTP_FS_DEVICE_NAME,ltp_block_dev_handle, errno); |
| } |
| else { |
| rc = ioctl (ltp_block_dev_handle, LTPAIODEV_CMD, &cmd); |
| |
| printf("return from AIO ioctl %d \n", rc); |
| |
| rc = ioctl (ltp_block_dev_handle, LTPBIODEV_CMD, &cmd); |
| |
| printf("return from BIO ioctl %d \n", rc); |
| } |
| |
| } else { |
| printf("ERROR: Create/open block device failed\n"); |
| } |
| |
| ltp_fileHandle = open("/tmp/testfile", O_CREAT | O_RDWR | O_SYNC | FASYNC, |
| S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); |
| |
| if (ltp_fileHandle > 0) { |
| |
| tmpHandle = open("/usr/include/ctype.h", O_RDONLY); |
| |
| if (tmpHandle > 0) { |
| |
| rc = fstat(tmpHandle, &statBuf); |
| |
| if (!rc) { |
| fileBuf = malloc(statBuf.st_size); |
| |
| if (fileBuf) { |
| |
| read (tmpHandle, fileBuf, statBuf.st_size); |
| close(tmpHandle); |
| write(ltp_fileHandle, fileBuf, statBuf.st_size); |
| |
| for (i = 0 ; i < 100; i++) { |
| read(ltp_fileHandle, fileBuf, statBuf.st_size*i); |
| write(ltp_fileHandle, fileBuf, statBuf.st_size*i); |
| } |
| } |
| |
| } |
| |
| } else { |
| printf("ERROR: Create/open file failed\n"); |
| } |
| } |
| |
| printf("*** Starting FileSystem thump tests....****\n"); |
| printf("*** Please be patient, this may take a little while... ***\n"); |
| |
| for (i = 1; i < argc; i++) { |
| printf("Running test %d of %d on FileSystem %s \n", i, argc-1, argv[i]); |
| if (strcmp(argv[i], "|") != 0) { |
| strcpy(rootPath, argv[i]); |
| rc = do_fs_thump_tests(argv[i]); |
| if (rc != 0 && rc != ENOSPC) { |
| printf("ERROR: Failed on FileSystem %s with errno %d \n", argv[i], rc); |
| } |
| } |
| else { |
| printf("Test Program complete..\n"); |
| break; |
| } |
| |
| } |
| |
| printf("Test Program complete..\n"); |
| |
| return 0; |
| } |
| int do_fs_thump_tests(char * path) |
| { |
| int rc = 0; |
| |
| printf("Changing to directory %s \n", path); |
| |
| changedir(path); |
| |
| cFileCount = 0; |
| dFileCount = 0; |
| |
| rc |= do_create_file_test(path); |
| rc |= do_random_access_test(MAXNUM); |
| rc |= do_tree_cleanup(path, FILES_ONLY); |
| rc |= do_random_create_delete(MAXNUM); |
| rc |= do_tree_cleanup(path, ALL); |
| |
| return rc; |
| |
| } |
| int do_tree_cleanup(char *path, int flag) |
| { |
| |
| if (flag == FILES_ONLY) { |
| printf("Cleaning up test files...\n"); |
| ftw(path, (void *)cleanup_files, MAXNUM); |
| } |
| else { |
| printf("Cleaning up everything in the test directory...\n"); |
| ftw(path, (void *)cleanup_files, MAXNUM); |
| ftw(path, (void *)cleanup_dirs, MAXNUM); |
| } |
| |
| |
| return 0; |
| } |
| int cleanup_files(char * file, struct stat * statBuff, int flag) |
| { |
| int rc = 0; |
| |
| |
| if (flag == FTW_F) { |
| if(unlink(file)){ |
| printf("ERROR:%d removing file %s\n", errno, file); |
| } |
| } |
| |
| return rc; |
| } |
| |
| int cleanup_dirs(char * file, struct stat * statBuff, int flag) |
| { |
| int rc = 0; |
| |
| //printf("%s:Cleaning up directory %s \n", __FUNCTION__, file); |
| |
| if (strcmp(rootPath, file) == 0) { |
| return 0; |
| } |
| |
| if (flag == FTW_F) { |
| if(unlink(file)){ |
| printf("ERROR:%d removing file %s\n", errno, file); |
| } |
| } |
| else if (flag == FTW_D){ |
| changedir(file); |
| ftw(file, (void *)cleanup_dirs, MAXNUM); |
| rmdir(file); |
| |
| } |
| else { |
| printf("No idea what we found here\n"); |
| } |
| |
| return rc; |
| } |
| |
| |
| int do_create_file_test(char * path) |
| { |
| int i = 0; |
| int j = 0; |
| int k = 0; |
| int l = 0; |
| int rc = 0; |
| |
| char dir1[MAXN]; |
| char dir2[MAXN]; |
| char dir3[MAXN]; |
| char filename[MAXN]; |
| |
| time_t t; |
| |
| int maxfiles=0xFFFFFF; |
| |
| time(&t); |
| |
| srandom((unsigned int)getpid()^(((unsigned int)t<<16)| (unsigned int)t>>16)); |
| |
| printf("Creating files...\n"); |
| |
| for ( i = 0 ; i < FILE_CREATE_COUNT; i++) { |
| |
| sprintf(dir1,"%2.2x",i); |
| |
| |
| makedir(dir1); |
| |
| changedir(dir1); |
| |
| for ( j = 0 ; j < FILE_CREATE_COUNT ; j++) { |
| |
| sprintf(dir2,"%2.2x",j); |
| |
| makedir(dir2); |
| |
| changedir(dir2); |
| |
| for ( k = 0 ; k < FILE_CREATE_COUNT ; k++) { |
| |
| sprintf(dir3,"%2.2x",k); |
| makedir(dir3); |
| changedir(dir3); |
| |
| for ( l = 0 ; l < FILE_CREATE_COUNT ; l++) { |
| sprintf(filename,"%s%s%s%2.2x",dir1,dir2,dir3,l); |
| rc = create_file(filename); |
| if (rc != 0 || maxfiles < dFileCount++) { |
| if (rc != ENOSPC) { |
| printf("ERROR: failed error:%d creating all the test files ! \n", errno); |
| printf("ERROR2: rc:%d -- dFileCount:%d \n", rc, dFileCount); |
| } |
| goto end; |
| } |
| } |
| changedir("../"); |
| } |
| changedir("../"); |
| } |
| changedir("../"); |
| } |
| end: |
| fprintf(stderr,"\nTotal create files: %d\n",cFileCount); |
| printf("Done\n"); |
| return rc; |
| } |
| |
| int makedir(char *dir1) |
| { |
| if (mkdir(dir1, S_IRWXU) < 0) { |
| perror(dir1); |
| return(errno); |
| } |
| return 0; |
| } |
| |
| int changedir(char *dir) { |
| if ( chdir(dir) < 0 ) { |
| perror(dir); |
| return (errno); |
| } |
| |
| return 0; |
| } |
| |
| |
| int create_file(char *filename) |
| { |
| int fileHandle; |
| int randomsize; |
| |
| if ( (fileHandle=creat(filename, S_IRWXU)) < 0) { |
| |
| fprintf(stderr,"\nERROR line %d: Total create files: %d\n",__LINE__,cFileCount); |
| perror(filename); |
| return (errno); |
| } |
| |
| if ((randomsize = gen_random_file_size(0,MAXFSIZE)) < 0) { |
| randomsize = MAXFSIZE; |
| } |
| if (write(fileHandle,wbuf,randomsize) < 0 ) { |
| |
| fprintf(stderr,"\nERROR:%d line%d: Total create files: %d\n",errno,__LINE__,cFileCount); |
| close(fileHandle); |
| |
| perror(filename); |
| return (errno); |
| } |
| |
| cFileCount++; |
| close(fileHandle); |
| return 0; |
| } |
| |
| int delete_file(char *filename) |
| { |
| struct stat buf; |
| int st; |
| |
| st = stat(filename, &buf); |
| |
| if ( st < 0 ) { |
| errorCount++; |
| printf("ERROR line %d: Getting file stats %s \n", __LINE__, filename); |
| return(-1); |
| } |
| |
| disk_space_pool += buf.st_size; |
| |
| if ( unlink(filename) < 0 ) { |
| errorCount++; |
| printf("ERROR line %d: Removing file %s \n", __LINE__, filename); |
| return(-1); |
| } |
| |
| dFileCount++; |
| return 0; |
| } |
| |
| |
| |
| int LTP_fs_open_block_device() |
| { |
| dev_t devt; |
| struct stat statbuf; |
| int rc; |
| |
| |
| if (ltp_block_dev_handle == 0) { |
| |
| /* check for the /dev/LTPFSTest subdir, and create if it does not exist. |
| * |
| * If devfs is running and mounted on /dev, these checks will all pass, |
| * so a new node will not be created. |
| */ |
| devt = makedev(LTPMAJOR, 0); |
| |
| rc = stat(LTP_FS_DEV_NODE_PATH, &statbuf); |
| |
| if (rc) { |
| if (errno == ENOENT) { |
| /* dev node does not exist. */ |
| rc = mkdir(LTP_FS_DEV_NODE_PATH, (S_IFDIR | S_IRWXU | |
| S_IRGRP | S_IXGRP | |
| S_IROTH | S_IXOTH)); |
| } else { |
| printf("ERROR: Problem with LTP FS dev directory. Error code from stat() is %d\n\n", errno); |
| } |
| |
| } else { |
| if (!(statbuf.st_mode & S_IFDIR)) { |
| rc = unlink(LTP_FS_DEV_NODE_PATH); |
| if (!rc) { |
| rc = mkdir(LTP_FS_DEV_NODE_PATH, (S_IFDIR | S_IRWXU | |
| S_IRGRP | S_IXGRP | |
| S_IROTH | S_IXOTH)); |
| } |
| } |
| } |
| |
| |
| /* |
| * Check for the /dev/ltp-fs/block_device node, and create if it does not |
| * exist. |
| */ |
| rc = stat(LTP_FS_DEVICE_NAME, &statbuf); |
| if (rc) { |
| if (errno == ENOENT) { |
| /* dev node does not exist */ |
| rc = mknod(LTP_FS_DEVICE_NAME, (S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), devt); |
| } else { |
| printf("ERROR:Problem with LTP FS block device node directory. Error code form stat() is %d\n\n", errno); |
| } |
| |
| } else { |
| /* |
| * /dev/ltp-fs/block_device exists. Check to make sure it is for a |
| * block device and that it has the right major and minor. |
| */ |
| if ((!(statbuf.st_mode & S_IFBLK)) || |
| (statbuf.st_rdev != devt)) { |
| |
| /* Recreate the dev node. */ |
| rc = unlink(LTP_FS_DEVICE_NAME); |
| if (!rc) { |
| rc = mknod(LTP_FS_DEVICE_NAME, (S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), devt); |
| } |
| } |
| } |
| |
| } |
| |
| return rc; |
| } |
| |
| int gen_random_file_size(int min, int max) |
| { |
| double u1,u2,z; |
| int i; |
| int ave; |
| int range; |
| int ZZ; |
| if ( min >= max ) { |
| return (-1); |
| } |
| range = max - min; |
| ave = range/2; |
| for ( i = 0 ; i< 10 ; i++ ) { |
| u1 = ((double)(random() % 1000000))/ 1000000; |
| u2 = ((double)(random() % 1000000))/ 1000000; |
| z = sqrt( -2.0 * log(u1) ) * cos ( M_2PI * u2 ); |
| ZZ = min + (ave + (z*(ave/4))); |
| if (ZZ >= min && ZZ < max ) { |
| return (ZZ); |
| } |
| } |
| return (-1); |
| } |
| |
| int do_random_access_test(int maxNum) |
| { |
| int r; |
| char fname[1024]; |
| time_t t; |
| int i; |
| |
| |
| printf("Running random access test...\n"); |
| changedir(rootPath); |
| |
| if ( maxNum < 1 || maxNum > MAXNUM ) { |
| printf("out of size %d\n",maxNum); |
| return(1); |
| } |
| |
| time(&t); |
| srandom((unsigned int)getpid()^(((unsigned int)t<<16)| (unsigned int)t>>16)); |
| |
| if ( (nullFileHandle = open("/dev/null",O_WRONLY)) < 0 ) { |
| perror("/dev/null"); |
| return(errno); |
| } |
| |
| |
| /* 00/00/00/00 */ |
| for ( i = 0 ; i < maxNum ; i++) { |
| |
| r = random() % maxNum; |
| |
| sprintf(fname,"00/%2.2x/%2.2x/00%2.2x%2.2x%2.2x", |
| ((r>>16)&0xFF), |
| ((r>>8)&0xFF), |
| ((r>>16)&0xFF), |
| ((r>>8)&0xFF), |
| (r&0xFF)); |
| |
| open_read_close(fname); |
| } |
| close(nullFileHandle); |
| printf("Success:\t%d\nFail:\t%d\n",openlog[SUCCESS],openlog[FAIL]); |
| return 0; |
| } |
| |
| int open_read_close(char *fname) |
| { |
| int fileHandle, fileHandle2; |
| char buffer[BUFFSIZE]; |
| int c; |
| |
| if ( (fileHandle = open(fname, O_RDONLY | O_SYNC | O_ASYNC)) < 0 ) { |
| openlog[FAIL]++; |
| printf("ERROR:opening file %s failed %d \n", fname, errno); |
| return (errno); |
| } |
| |
| if ( (fileHandle2 = open(fname, O_RDONLY | O_SYNC | O_ASYNC)) < 0 ) { |
| openlog[FAIL]++; |
| printf("ERROR:2nd opening file %s failed %d \n", fname, errno); |
| return (errno); |
| } |
| |
| openlog[SUCCESS]++; |
| |
| while ( (c = read(fileHandle, buffer, BUFFSIZE)) > 0 ) { |
| if (write(nullFileHandle, buffer, c) < 0 ) { |
| perror("/dev/null"); |
| printf("Opened\t %d\nUnopend:\t%d\n",openlog[SUCCESS],openlog[FAIL]); |
| close(fileHandle2); |
| close(fileHandle); |
| return(errno); |
| } |
| if ( (c = read(fileHandle2, buffer, BUFFSIZE)) > 0 ) { |
| if (write(nullFileHandle, buffer, c) < 0 ) { |
| perror("/dev/null"); |
| printf("Opened\t %d\nUnopend:\t%d\n",openlog[SUCCESS],openlog[FAIL]); |
| close(fileHandle2); |
| close(fileHandle); |
| return(errno); |
| } |
| } |
| } |
| |
| if ( c < 0 ) { |
| perror(fname); |
| printf("Opened\t %d\nUnopend:\t%d\n",openlog[SUCCESS],openlog[FAIL]); |
| return(errno); |
| } |
| |
| close(fileHandle2); |
| close(fileHandle); |
| return 0; |
| } |
| |
| int create_or_delete(char *fname) |
| { |
| int r, rc; |
| |
| r = (random() & 1); |
| |
| /* create */ |
| if((create_file(fname) == 0)){ |
| rc = delete_file(fname); |
| } |
| else{ |
| printf("Error: %d creating random file \n", errno); |
| } |
| |
| if ( (errorCount > dFileCount || errorCount > cFileCount) && (errorCount > MAXERROR)) { |
| fprintf(stderr,"Too many errors -- Aborting test\n"); |
| fprintf(stderr,"Total create files: %d\n",cFileCount); |
| fprintf(stderr,"Total delete files: %d\n",dFileCount); |
| fprintf(stderr,"Total error : %d\n",errorCount); |
| return(MAXERROR); |
| } |
| |
| return 0; |
| } |
| |
| int do_random_create_delete(int maxNum) |
| { |
| int r, rc = 0; |
| char fname[1024]; |
| time_t t; |
| int i; |
| |
| printf("Running random create/delete test...\n"); |
| |
| if ( maxNum < 1 || maxNum > MAXNUM ) { |
| printf("MAX out of size %d\n",maxNum); |
| return(maxNum); |
| } |
| |
| time(&t); |
| srandom((unsigned int)getpid()^(((unsigned int)t<<16)| (unsigned int)t>>16)); |
| |
| |
| /* 00/00/00/00 */ |
| for ( i = 0 ; i < maxNum && rc != MAXERROR; i++) { |
| r = random() % maxNum; |
| sprintf(fname,"00/%2.2x/%2.2x/00%2.2x%2.2x%2.2x", |
| ((r>>16)&0xFF), |
| ((r>>8)&0xFF), |
| ((r>>16)&0xFF), |
| ((r>>8)&0xFF), |
| (r&0xFF)); |
| |
| rc = create_or_delete(fname); |
| } |
| |
| fprintf(stderr,"Total create files: %d\n",cFileCount); |
| fprintf(stderr,"Total delete files: %d\n",dFileCount); |
| fprintf(stderr,"Total error : %d\n",errorCount); |
| return(rc); |
| } |