Home | History | Annotate | Download | only in progs
      1 /*
      2  * random_exercise.c --- Test program which exercises an ext2
      3  * 	filesystem.  It creates a lot of random files in the current
      4  * 	directory, while holding some files open while they are being
      5  * 	deleted.  This exercises the orphan list code, as well as
      6  * 	creating lots of fodder for the ext3 journal.
      7  *
      8  * Copyright (C) 2000 Theodore Ts'o.
      9  *
     10  * %Begin-Header%
     11  * This file may be redistributed under the terms of the GNU Public
     12  * License.
     13  * %End-Header%
     14  */
     15 
     16 #include <unistd.h>
     17 #include <stdio.h>
     18 #include <sys/types.h>
     19 #include <sys/stat.h>
     20 #include <fcntl.h>
     21 
     22 #define MAXFDS	128
     23 
     24 struct state {
     25 	char	name[16];
     26 	int	state;
     27 	int	isdir;
     28 };
     29 
     30 #define STATE_CLEAR	0
     31 #define STATE_CREATED	1
     32 #define STATE_DELETED	2
     33 
     34 struct state state_array[MAXFDS];
     35 
     36 #define DATA_SIZE 65536
     37 
     38 char data_buffer[DATA_SIZE];
     39 
     40 void clear_state_array()
     41 {
     42 	int	i;
     43 
     44 	for (i = 0; i < MAXFDS; i++)
     45 		state_array[i].state = STATE_CLEAR;
     46 }
     47 
     48 int get_random_fd()
     49 {
     50 	int	fd;
     51 
     52 	while (1) {
     53 		fd = ((int) random()) % MAXFDS;
     54 		if (fd > 2)
     55 			return fd;
     56 	}
     57 }
     58 
     59 unsigned int get_inode_num(int fd)
     60 {
     61 	struct stat st;
     62 
     63 	if (fstat(fd, &st) < 0) {
     64 		perror("fstat");
     65 		return 0;
     66 	}
     67 	return st.st_ino;
     68 }
     69 
     70 
     71 void create_random_file()
     72 {
     73 	char template[16] = "EX.XXXXXX";
     74 	int	fd;
     75 	int	isdir = 0;
     76 	int	size;
     77 
     78 	mktemp(template);
     79 	isdir = random() & 1;
     80 	if (isdir) {
     81 		if (mkdir(template, 0700) < 0)
     82 			return;
     83 		fd = open(template, O_RDONLY, 0600);
     84 		printf("Created temp directory %s, fd = %d\n",
     85 		       template, fd);
     86 	} else {
     87 		size = random() & (DATA_SIZE-1);
     88 		fd = open(template, O_CREAT|O_RDWR, 0600);
     89 		write(fd, data_buffer, size);
     90 		printf("Created temp file %s, fd = %d, size=%d\n",
     91 		       template, fd, size);
     92 	}
     93 	state_array[fd].isdir = isdir;
     94 	if (fd < 0)
     95 		return;
     96 	state_array[fd].isdir = isdir;
     97 	state_array[fd].state = STATE_CREATED;
     98 	strcpy(state_array[fd].name, template);
     99 }
    100 
    101 void truncate_file(int fd)
    102 {
    103 	int	size;
    104 
    105 	size = random() & (DATA_SIZE-1);
    106 
    107 	if (state_array[fd].isdir)
    108 		return;
    109 
    110 	ftruncate(fd, size);
    111 	printf("Truncating temp file %s, fd = %d, ino=%u, size=%d\n",
    112 	       state_array[fd].name, fd, get_inode_num(fd), size);
    113 }
    114 
    115 
    116 void unlink_file(int fd)
    117 {
    118 	char *filename = state_array[fd].name;
    119 
    120 	printf("Deleting %s, fd = %d, ino = %u\n", filename, fd,
    121 	       get_inode_num(fd));
    122 
    123 	if (state_array[fd].isdir)
    124 		rmdir(filename);
    125 	else
    126 		unlink(filename);
    127 	state_array[fd].state = STATE_DELETED;
    128 }
    129 
    130 void close_file(int fd)
    131 {
    132 	char *filename = state_array[fd].name;
    133 
    134 	printf("Closing %s, fd = %d, ino = %u\n", filename, fd,
    135 	       get_inode_num(fd));
    136 
    137 	close(fd);
    138 	state_array[fd].state = STATE_CLEAR;
    139 }
    140 
    141 
    142 main(int argc, char **argv)
    143 {
    144 	int	i, fd;
    145 
    146 	memset(data_buffer, 0, sizeof(data_buffer));
    147 	sprintf(data_buffer, "This is a test file created by the "
    148 		"random_exerciser program\n");
    149 
    150 	for (i=0; i < 100000; i++) {
    151 		fd = get_random_fd();
    152 		switch (state_array[fd].state) {
    153 		case STATE_CLEAR:
    154 			create_random_file();
    155 			break;
    156 		case STATE_CREATED:
    157 			if ((state_array[fd].isdir == 0) &&
    158 			    (random() & 2))
    159 				truncate_file(fd);
    160 			else
    161 				unlink_file(fd);
    162 			break;
    163 		case STATE_DELETED:
    164 			close_file(fd);
    165 			break;
    166 		}
    167 	}
    168 }
    169 
    170 
    171