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 "config.h"
     17 #include <unistd.h>
     18 #include <stdio.h>
     19 #include <sys/types.h>
     20 #include <sys/stat.h>
     21 #include <fcntl.h>
     22 
     23 #define MAXFDS	128
     24 
     25 struct state {
     26 	char	name[16];
     27 	int	state;
     28 	int	isdir;
     29 };
     30 
     31 #define STATE_CLEAR	0
     32 #define STATE_CREATED	1
     33 #define STATE_DELETED	2
     34 
     35 struct state state_array[MAXFDS];
     36 
     37 #define DATA_SIZE 65536
     38 
     39 char data_buffer[DATA_SIZE];
     40 
     41 void clear_state_array()
     42 {
     43 	int	i;
     44 
     45 	for (i = 0; i < MAXFDS; i++)
     46 		state_array[i].state = STATE_CLEAR;
     47 }
     48 
     49 int get_random_fd()
     50 {
     51 	int	fd;
     52 
     53 	while (1) {
     54 		fd = ((int) random()) % MAXFDS;
     55 		if (fd > 2)
     56 			return fd;
     57 	}
     58 }
     59 
     60 unsigned int get_inode_num(int fd)
     61 {
     62 	struct stat st;
     63 
     64 	if (fstat(fd, &st) < 0) {
     65 		perror("fstat");
     66 		return 0;
     67 	}
     68 	return st.st_ino;
     69 }
     70 
     71 
     72 void create_random_file()
     73 {
     74 	char template[16] = "EX.XXXXXX";
     75 	int	fd;
     76 	int	isdir = 0;
     77 	int	size;
     78 
     79 	mktemp(template);
     80 	isdir = random() & 1;
     81 	if (isdir) {
     82 		if (mkdir(template, 0700) < 0)
     83 			return;
     84 		fd = open(template, O_RDONLY, 0600);
     85 		printf("Created temp directory %s, fd = %d\n",
     86 		       template, fd);
     87 	} else {
     88 		size = random() & (DATA_SIZE-1);
     89 		fd = open(template, O_CREAT|O_RDWR, 0600);
     90 		write(fd, data_buffer, size);
     91 		printf("Created temp file %s, fd = %d, size=%d\n",
     92 		       template, fd, size);
     93 	}
     94 	state_array[fd].isdir = isdir;
     95 	if (fd < 0)
     96 		return;
     97 	state_array[fd].isdir = isdir;
     98 	state_array[fd].state = STATE_CREATED;
     99 	strcpy(state_array[fd].name, template);
    100 }
    101 
    102 void truncate_file(int fd)
    103 {
    104 	int	size;
    105 
    106 	size = random() & (DATA_SIZE-1);
    107 
    108 	if (state_array[fd].isdir)
    109 		return;
    110 
    111 	ftruncate(fd, size);
    112 	printf("Truncating temp file %s, fd = %d, ino=%u, size=%d\n",
    113 	       state_array[fd].name, fd, get_inode_num(fd), size);
    114 }
    115 
    116 
    117 void unlink_file(int fd)
    118 {
    119 	char *filename = state_array[fd].name;
    120 
    121 	printf("Deleting %s, fd = %d, ino = %u\n", filename, fd,
    122 	       get_inode_num(fd));
    123 
    124 	if (state_array[fd].isdir)
    125 		rmdir(filename);
    126 	else
    127 		unlink(filename);
    128 	state_array[fd].state = STATE_DELETED;
    129 }
    130 
    131 void close_file(int fd)
    132 {
    133 	char *filename = state_array[fd].name;
    134 
    135 	printf("Closing %s, fd = %d, ino = %u\n", filename, fd,
    136 	       get_inode_num(fd));
    137 
    138 	close(fd);
    139 	state_array[fd].state = STATE_CLEAR;
    140 }
    141 
    142 
    143 main(int argc, char **argv)
    144 {
    145 	int	i, fd;
    146 
    147 	memset(data_buffer, 0, sizeof(data_buffer));
    148 	sprintf(data_buffer, "This is a test file created by the "
    149 		"random_exerciser program\n");
    150 
    151 	for (i=0; i < 100000; i++) {
    152 		fd = get_random_fd();
    153 		switch (state_array[fd].state) {
    154 		case STATE_CLEAR:
    155 			create_random_file();
    156 			break;
    157 		case STATE_CREATED:
    158 			if ((state_array[fd].isdir == 0) &&
    159 			    (random() & 2))
    160 				truncate_file(fd);
    161 			else
    162 				unlink_file(fd);
    163 			break;
    164 		case STATE_DELETED:
    165 			close_file(fd);
    166 			break;
    167 		}
    168 	}
    169 }
    170 
    171 
    172