summaryrefslogtreecommitdiffstats
path: root/tests/progs/random_exercise.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/progs/random_exercise.c')
-rw-r--r--tests/progs/random_exercise.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/tests/progs/random_exercise.c b/tests/progs/random_exercise.c
new file mode 100644
index 0000000..38217ab
--- /dev/null
+++ b/tests/progs/random_exercise.c
@@ -0,0 +1,171 @@
+/*
+ * random_exercise.c --- Test program which exercises an ext2
+ * filesystem. It creates a lot of random files in the current
+ * directory, while holding some files open while they are being
+ * deleted. This exercises the orphan list code, as well as
+ * creating lots of fodder for the ext3 journal.
+ *
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define MAXFDS 128
+
+struct state {
+ char name[16];
+ int state;
+ int isdir;
+};
+
+#define STATE_CLEAR 0
+#define STATE_CREATED 1
+#define STATE_DELETED 2
+
+struct state state_array[MAXFDS];
+
+#define DATA_SIZE 65536
+
+char data_buffer[DATA_SIZE];
+
+void clear_state_array()
+{
+ int i;
+
+ for (i = 0; i < MAXFDS; i++)
+ state_array[i].state = STATE_CLEAR;
+}
+
+int get_random_fd()
+{
+ int fd;
+
+ while (1) {
+ fd = ((int) random()) % MAXFDS;
+ if (fd > 2)
+ return fd;
+ }
+}
+
+unsigned int get_inode_num(int fd)
+{
+ struct stat st;
+
+ if (fstat(fd, &st) < 0) {
+ perror("fstat");
+ return 0;
+ }
+ return st.st_ino;
+}
+
+
+void create_random_file()
+{
+ char template[16] = "EX.XXXXXX";
+ int fd;
+ int isdir = 0;
+ int size;
+
+ mktemp(template);
+ isdir = random() & 1;
+ if (isdir) {
+ if (mkdir(template, 0700) < 0)
+ return;
+ fd = open(template, O_RDONLY, 0600);
+ printf("Created temp directory %s, fd = %d\n",
+ template, fd);
+ } else {
+ size = random() & (DATA_SIZE-1);
+ fd = open(template, O_CREAT|O_RDWR, 0600);
+ write(fd, data_buffer, size);
+ printf("Created temp file %s, fd = %d, size=%d\n",
+ template, fd, size);
+ }
+ state_array[fd].isdir = isdir;
+ if (fd < 0)
+ return;
+ state_array[fd].isdir = isdir;
+ state_array[fd].state = STATE_CREATED;
+ strcpy(state_array[fd].name, template);
+}
+
+void truncate_file(int fd)
+{
+ int size;
+
+ size = random() & (DATA_SIZE-1);
+
+ if (state_array[fd].isdir)
+ return;
+
+ ftruncate(fd, size);
+ printf("Truncating temp file %s, fd = %d, ino=%u, size=%d\n",
+ state_array[fd].name, fd, get_inode_num(fd), size);
+}
+
+
+void unlink_file(int fd)
+{
+ char *filename = state_array[fd].name;
+
+ printf("Deleting %s, fd = %d, ino = %u\n", filename, fd,
+ get_inode_num(fd));
+
+ if (state_array[fd].isdir)
+ rmdir(filename);
+ else
+ unlink(filename);
+ state_array[fd].state = STATE_DELETED;
+}
+
+void close_file(int fd)
+{
+ char *filename = state_array[fd].name;
+
+ printf("Closing %s, fd = %d, ino = %u\n", filename, fd,
+ get_inode_num(fd));
+
+ close(fd);
+ state_array[fd].state = STATE_CLEAR;
+}
+
+
+main(int argc, char **argv)
+{
+ int i, fd;
+
+ memset(data_buffer, 0, sizeof(data_buffer));
+ sprintf(data_buffer, "This is a test file created by the "
+ "random_exerciser program\n");
+
+ for (i=0; i < 100000; i++) {
+ fd = get_random_fd();
+ switch (state_array[fd].state) {
+ case STATE_CLEAR:
+ create_random_file();
+ break;
+ case STATE_CREATED:
+ if ((state_array[fd].isdir == 0) &&
+ (random() & 2))
+ truncate_file(fd);
+ else
+ unlink_file(fd);
+ break;
+ case STATE_DELETED:
+ close_file(fd);
+ break;
+ }
+ }
+}
+
+