blob: 0be389fb1e6af320f1e3031575f4276215c3fc01 [file] [log] [blame]
Theodore Ts'oda1a0222000-08-20 21:48:45 +00001/*
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.
Theodore Ts'oefc6f622008-08-27 23:07:54 -04007 *
Theodore Ts'oda1a0222000-08-20 21:48:45 +00008 * 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
24struct state {
25 char name[16];
26 int state;
Theodore Ts'oad8e5532000-10-18 19:06:13 +000027 int isdir;
Theodore Ts'oda1a0222000-08-20 21:48:45 +000028};
29
30#define STATE_CLEAR 0
31#define STATE_CREATED 1
32#define STATE_DELETED 2
33
34struct state state_array[MAXFDS];
35
Theodore Ts'oa7de6992001-05-10 21:03:38 +000036#define DATA_SIZE 65536
37
38char data_buffer[DATA_SIZE];
Theodore Ts'oad8e5532000-10-18 19:06:13 +000039
Theodore Ts'oda1a0222000-08-20 21:48:45 +000040void clear_state_array()
41{
42 int i;
43
44 for (i = 0; i < MAXFDS; i++)
45 state_array[i].state = STATE_CLEAR;
46}
47
48int 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
Theodore Ts'oa7de6992001-05-10 21:03:38 +000059unsigned 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
Theodore Ts'oda1a0222000-08-20 21:48:45 +000071void create_random_file()
72{
73 char template[16] = "EX.XXXXXX";
74 int fd;
Theodore Ts'oad8e5532000-10-18 19:06:13 +000075 int isdir = 0;
Theodore Ts'oa7de6992001-05-10 21:03:38 +000076 int size;
Theodore Ts'oefc6f622008-08-27 23:07:54 -040077
Theodore Ts'oda1a0222000-08-20 21:48:45 +000078 mktemp(template);
Theodore Ts'oad8e5532000-10-18 19:06:13 +000079 isdir = random() & 1;
80 if (isdir) {
81 if (mkdir(template, 0700) < 0)
82 return;
83 fd = open(template, O_RDONLY, 0600);
Theodore Ts'oa7de6992001-05-10 21:03:38 +000084 printf("Created temp directory %s, fd = %d\n",
85 template, fd);
Theodore Ts'oad8e5532000-10-18 19:06:13 +000086 } else {
Theodore Ts'oefc6f622008-08-27 23:07:54 -040087 size = random() & (DATA_SIZE-1);
Theodore Ts'oad8e5532000-10-18 19:06:13 +000088 fd = open(template, O_CREAT|O_RDWR, 0600);
Theodore Ts'oa7de6992001-05-10 21:03:38 +000089 write(fd, data_buffer, size);
90 printf("Created temp file %s, fd = %d, size=%d\n",
91 template, fd, size);
Theodore Ts'oad8e5532000-10-18 19:06:13 +000092 }
Theodore Ts'oa7de6992001-05-10 21:03:38 +000093 state_array[fd].isdir = isdir;
Theodore Ts'oda1a0222000-08-20 21:48:45 +000094 if (fd < 0)
95 return;
Theodore Ts'oad8e5532000-10-18 19:06:13 +000096 state_array[fd].isdir = isdir;
Theodore Ts'oda1a0222000-08-20 21:48:45 +000097 state_array[fd].state = STATE_CREATED;
98 strcpy(state_array[fd].name, template);
99}
100
Theodore Ts'oa7de6992001-05-10 21:03:38 +0000101void 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
Theodore Ts'oda1a0222000-08-20 21:48:45 +0000116void unlink_file(int fd)
117{
118 char *filename = state_array[fd].name;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400119
Theodore Ts'oa7de6992001-05-10 21:03:38 +0000120 printf("Deleting %s, fd = %d, ino = %u\n", filename, fd,
121 get_inode_num(fd));
Theodore Ts'oad8e5532000-10-18 19:06:13 +0000122
123 if (state_array[fd].isdir)
124 rmdir(filename);
125 else
126 unlink(filename);
Theodore Ts'oda1a0222000-08-20 21:48:45 +0000127 state_array[fd].state = STATE_DELETED;
128}
129
130void close_file(int fd)
131{
132 char *filename = state_array[fd].name;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400133
Theodore Ts'oa7de6992001-05-10 21:03:38 +0000134 printf("Closing %s, fd = %d, ino = %u\n", filename, fd,
135 get_inode_num(fd));
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400136
Theodore Ts'oda1a0222000-08-20 21:48:45 +0000137 close(fd);
138 state_array[fd].state = STATE_CLEAR;
139}
140
141
142main(int argc, char **argv)
143{
144 int i, fd;
Theodore Ts'oad8e5532000-10-18 19:06:13 +0000145
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");
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400149
Theodore Ts'oda1a0222000-08-20 21:48:45 +0000150 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:
Theodore Ts'oa7de6992001-05-10 21:03:38 +0000157 if ((state_array[fd].isdir == 0) &&
158 (random() & 2))
159 truncate_file(fd);
160 else
161 unlink_file(fd);
Theodore Ts'oda1a0222000-08-20 21:48:45 +0000162 break;
163 case STATE_DELETED:
164 close_file(fd);
165 break;
166 }
167 }
168}
169
170