blob: 6b0d693573fcdb3a8018925cd58b57e60fe0fba7 [file] [log] [blame]
#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);
}