648 lines
13 KiB
C
648 lines
13 KiB
C
|
|
#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);
|
|
}
|