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
main(int argc,char ** argv)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
do_fs_thump_tests(char * path)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
do_tree_cleanup(char * path,int flag)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
cleanup_files(char * file,struct stat * statBuff,int flag)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
cleanup_dirs(char * file,struct stat * statBuff,int flag)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
do_create_file_test(char * path)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
makedir(char * dir1)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
changedir(char * dir)322 int changedir(char *dir)
323 {
324 if (chdir(dir) < 0) {
325 perror(dir);
326 return (errno);
327 }
328
329 return 0;
330 }
331
create_file(char * filename)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
delete_file(char * filename)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
LTP_fs_open_block_device()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
gen_random_file_size(int min,int max)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
do_random_access_test(int maxNum)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
open_read_close(char * fname)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
create_or_delete(char * fname)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
do_random_create_delete(int maxNum)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