Esempio n. 1
0
static char *pick_rename_name(struct dir_info **parent,
			      struct dir_entry_info **rename_entry, int isdir)
{
	struct dir_info *dir = pick_dir();
	struct dir_entry_info *entry;
	size_t r;

	*parent = dir;
	*rename_entry = NULL;

	if (grow || tests_random_no(20) < 10)
		return copy_string(make_name(dir));

	r = tests_random_no(dir->number_of_entries);
	entry = dir->first;
	while (entry && r) {
		entry = entry->next;
		--r;
	}
	if (!entry)
		entry = dir->first;
	if (!entry ||
	    (entry->type == 'd' && entry->entry.dir->number_of_entries != 0))
		return copy_string(make_name(dir));

	if ((isdir && entry->type != 'd') ||
	    (!isdir && entry->type == 'd'))
		return copy_string(make_name(dir));

	*rename_entry = entry;
	return copy_string(entry->name);
}
Esempio n. 2
0
static char *pick_symlink_target(const char *symlink_path)
{
	struct dir_info *dir;
	struct dir_entry_info *entry;
	size_t r;
	char *path, *rel_path;

	dir = pick_dir();

	if (tests_random_no(100) < 10)
		return dir_path(dir, make_name(dir));

	r = tests_random_no(dir->number_of_entries);
	entry = dir->first;
	while (entry && r) {
		entry = entry->next;
		--r;
	}
	if (!entry)
		entry = dir->first;
	if (!entry)
		return dir_path(dir, make_name(dir));
	path = dir_path(dir, entry->name);
	if (tests_random_no(20) < 10)
		return path;
	rel_path = relative_path(symlink_path, path);
	free(path);
	return rel_path;
}
Esempio n. 3
0
/* Randomly select something to do with a file */
static void operate_on_file(struct file_info *file)
{
	/* Try to keep at least 10 files open */
	if (open_files_count < 10) {
		file_open(file);
		return;
	}
	/* Try to keep about 20 files open */
	if (open_files_count < 20 && tests_random_no(2) == 0) {
		file_open(file);
		return;
	}
	/* Try to keep up to 40 files open */
	if (open_files_count < 40 && tests_random_no(20) == 0) {
		file_open(file);
		return;
	}
	/* Occasionly truncate */
	if (shrink && tests_random_no(100) == 0) {
		file_truncate_file(file);
		return;
	}
	/* Mostly just write */
	file_write_file(file);
}
/* Create an empty sub-directory or small file in the current directory */
int64_t tests_create_entry(char *return_name)
{
	int fd;
	char name[256];

	for (;;) {
		sprintf(name, "%u", (unsigned) tests_random_no(10000000));
		fd = open(name, O_RDONLY);
		if (fd == -1)
			break;
		close(fd);
	}
	if (return_name)
		strcpy(return_name, name);
	if (tests_random_no(2)) {
		return tests_create_file(name, tests_random_no(4096));
	} else {
		if (mkdir(name, 0777) == -1) {
			CHECK(errno == ENOSPC);
			errno = 0;
			return 0;
		}
		return TESTS_EMPTY_DIR_SIZE;
	}
}
Esempio n. 5
0
/* Randomly select something to do with a directory */
static void operate_on_dir(struct dir_info *dir)
{
	size_t r;
	struct dir_entry_info *entry;
	struct file_info *file;

	r = tests_random_no(14);
	if (r == 0 && grow)
		/* When growing, 1 time in 14 create a file */
		file_new(dir, make_name(dir));
	else if (r == 1 && grow)
		/* When growing, 1 time in 14 create a directory */
		dir_new(dir, make_name(dir));
	else if (r == 2 && grow && (file = pick_file()) != NULL)
		/* When growing, 1 time in 14 create a hard link */
		link_new(dir, make_name(dir), file);
	else if (r == 3 && grow && tests_random_no(5) == 0)
		/* When growing, 1 time in 70 create a symbolic link */
		symlink_new(dir, make_name(dir));
	else {
		/* Otherwise randomly select an entry to operate on */
		r = tests_random_no(dir->number_of_entries);
		entry = dir->first;
		while (entry && r) {
			entry = entry->next;
			--r;
		}
		if (entry)
			operate_on_entry(entry);
	}
}
Esempio n. 6
0
static char *make_name(struct dir_info *dir)
{
	static char name[256];
	struct dir_entry_info *entry;
	int found;

	do {
		found = 0;
		if (tests_random_no(5) == 1) {
			int i, n = tests_random_no(255) + 1;

			CHECK(n > 0 && n < 256);
			for (i = 0; i < n; i++)
				name[i] = 'a' + tests_random_no(26);
			name[i] = '\0';
		} else
			sprintf(name, "%u", (unsigned) tests_random_no(1000000));
		for (entry = dir->first; entry; entry = entry->next) {
			if (strcmp(entry->name, name) == 0) {
				found = 1;
				break;
			}
		}
	} while (found);
	return name;
}
Esempio n. 7
0
static struct file_info *pick_file(void)
{
	struct dir_info *dir = top_dir;

	for (;;) {
		struct dir_entry_info *entry;
		size_t r;

		r = tests_random_no(dir->number_of_entries);
		entry = dir->first;
		while (entry && r) {
			entry = entry->next;
			--r;
		}
		for (;;) {
			if (!entry)
				return NULL;
			if (entry->type == 'f')
				return entry->entry.file;
			if (entry->type == 'd')
				if (entry->entry.dir->number_of_entries != 0)
					break;
			entry = entry->next;
		}
		dir = entry->entry.dir;
	}
}
Esempio n. 8
0
static void do_an_operation(void)
{
	/* Half the time operate on already open files */
	if (tests_random_no(100) < 50)
		operate_on_dir(top_dir);
	else
		operate_on_an_open_file();
}
Esempio n. 9
0
/* Randomly select offset and and size to write in a file */
static void get_offset_and_size(struct file_info *file,
				off_t *offset,
				size_t *size)
{
	size_t r, n;

	r = tests_random_no(100);
	if (r == 0 && grow)
		/* 1 time in 100, when growing, write off the end of the file */
		*offset = file->length + tests_random_no(10000000);
	else if (r < 4)
		/* 3 (or 4) times in 100, write at the beginning of file */
		*offset = 0;
	else if (r < 52 || !grow)
		/* 48 times in 100, write into the file */
		*offset = tests_random_no(file->length);
	else
		/* 48 times in 100, write at the end of the  file */
		*offset = file->length;
	/* Distribute the size logarithmically */
	if (tests_random_no(1000) == 0)
		r = tests_random_no(log10_initial_free_space + 2);
	else
		r = tests_random_no(log10_initial_free_space);
	n = 1;
	while (r--)
		n *= 10;
	*size = tests_random_no(n);
	if (!grow && *offset + *size > file->length)
		*size = file->length - *offset;
	if (*size == 0)
		*size = 1;
}
Esempio n. 10
0
static void file_truncate(struct file_info *file, int fd)
{
	size_t new_length;

	new_length = tests_random_no(file->length);

	if (file_ftruncate(file, fd, new_length))
		file_truncate_info(file, new_length);
}
Esempio n. 11
0
/* Randomly select something to do with a directory entry */
static void operate_on_entry(struct dir_entry_info *entry)
{
	/* If shrinking, 1 time in 50, remove a directory */
	if (entry->type == 'd') {
		if (shrink && tests_random_no(50) == 0) {
			dir_remove(entry->entry.dir);
			return;
		}
		operate_on_dir(entry->entry.dir);
	}
	/* If shrinking, 1 time in 10, remove a file */
	if (entry->type == 'f') {
		if (shrink && tests_random_no(10) == 0) {
			file_delete(entry->entry.file);
			return;
		}
		operate_on_file(entry->entry.file);
	}
}
Esempio n. 12
0
static void file_write(struct file_info *file, int fd)
{
	off_t offset;
	size_t size, actual;
	unsigned seed;
	int truncate = 0;

	get_offset_and_size(file, &offset, &size);
	seed = tests_random_no(10000000);
	actual = file_write_data(file, fd, offset, size, seed);

	if (offset + actual <= file->length && shrink)
		/* 1 time in 100, when shrinking
		   truncate after the write */
		if (tests_random_no(100) == 0)
			truncate = 1;

	if (actual != 0)
		file_write_info(file, offset, actual, seed);

	/* Delete errored files */
	if (file->no_space_error) {
		if (!file->deleted) {
			struct fd_info *fdi;

			fdi = file->fds;
			while (fdi) {
				file_close(fdi);
				fdi = file->fds;
			}
			file_delete(file);
		}
		return;
	}

	if (truncate) {
		size_t new_length = offset + actual;
		if (file_ftruncate(file, fd, new_length))
			file_truncate_info(file, new_length);
	}
}
Esempio n. 13
0
/* Randomly select something to do with an open file */
static void operate_on_open_file(struct fd_info *fdi)
{
	size_t r;

	r = tests_random_no(1000);
	if (shrink && r < 5)
		file_truncate(fdi->file, fdi->fd);
	else if (r < 21)
		file_close(fdi);
	else if (shrink && r < 121 && !fdi->file->deleted)
		file_delete(fdi->file);
	else {
		file_write(fdi->file, fdi->fd);
		if (r >= 999) {
			if (tests_random_no(100) >= 50)
				CHECK(fsync(fdi->fd) != -1);
			else
				CHECK(fdatasync(fdi->fd) != -1);
		}
	}
}
Esempio n. 14
0
static struct dir_info *pick_dir(void)
{
	struct dir_info *dir = top_dir;

	if (tests_random_no(40) >= 30)
		return dir;
	for (;;) {
		struct dir_entry_info *entry;
		size_t r;

		r = tests_random_no(dir->number_of_entries);
		entry = dir->first;
		while (entry && r) {
			entry = entry->next;
			--r;
		}
		for (;;) {
			if (!entry)
				break;
			if (entry->type == 'd')
				break;
			entry = entry->next;
		}
		if (!entry) {
			entry = dir->first;
			for (;;) {
				if (!entry)
					break;
				if (entry->type == 'd')
					break;
				entry = entry->next;
			}
		}
		if (!entry)
			return dir;
		dir = entry->entry.dir;
		if (tests_random_no(40) >= 30)
			return dir;
	}
}
Esempio n. 15
0
static struct fd_info *file_open(struct file_info *file)
{
	int fd, flags = O_RDWR;
	char *path;

	path = dir_path(file->links->parent, file->links->name);
	if (tests_random_no(100) == 1)
		flags |= O_SYNC;
	fd = open(path, flags);
	CHECK(fd != -1);
	free(path);
	return add_fd(file, fd);
}
Esempio n. 16
0
/* Create an empty sub-directory or small file in the current directory */
static int64_t create_entry(char *return_name)
{
	int fd;
	char name[256];
	int64_t res;

	for (;;) {
		sprintf(name, "%u", (unsigned) tests_random_no(10000000));
		before();
		fd = open(name, O_RDONLY);
		after("open (create_entry)");
		if (fd == -1)
			break;
		before();
		close(fd);
		after("close (create_entry)");
	}
	if (return_name)
		strcpy(return_name, name);
	if (tests_random_no(2)) {
		res = create_file(name, tests_random_no(4096));
		if (res > 0)
			files_created += 1;
		return res;
	} else {
		before();
		if (mkdir(name, 0777) == -1) {
			CHECK(errno == ENOSPC);
			after("mkdir");
			errno = 0;
			fprintf(stderr,"\nrndrm99: mkdir failed with ENOSPC\n");fflush(stderr);
			display_stats();
			return 0;
		}
		after("mkdir");
		dirs_created += 1;
		return TESTS_EMPTY_DIR_SIZE;
	}
}
Esempio n. 17
0
static struct dir_entry_info *pick_entry(struct file_info *file)
{
	struct dir_entry_info *entry;
	size_t r;

	if (!file->link_count)
		return NULL;
	r = tests_random_no(file->link_count);
	entry = file->links;
	while (entry && r--)
		entry = entry->next_link;
	return entry;
}
/* Remove a random file of empty sub-directory from the current directory */
int64_t tests_remove_entry(void)
{
	DIR *dir;
	struct dirent *entry;
	unsigned count = 0, pos;
	int64_t result = 0;

	dir = opendir(".");
	CHECK(dir != NULL);
	for (;;) {
		errno = 0;
		entry = readdir(dir);
		if (entry) {
			if (strcmp(".",entry->d_name) != 0 &&
					strcmp("..",entry->d_name) != 0)
				++count;
		} else {
			CHECK(errno == 0);
			break;
		}
	}
	pos = tests_random_no(count);
	count = 0;
	rewinddir(dir);
	for (;;) {
		errno = 0;
		entry = readdir(dir);
		if (!entry) {
			CHECK(errno == 0);
			break;
		}
		if (strcmp(".",entry->d_name) != 0 &&
				strcmp("..",entry->d_name) != 0) {
			if (count == pos) {
				if (entry->d_type == DT_DIR) {
					tests_clear_dir(entry->d_name);
					CHECK(rmdir(entry->d_name) != -1);
					result = TESTS_EMPTY_DIR_SIZE;
				} else {
					struct stat st;
					CHECK(stat(entry->d_name, &st) != -1);
					result = st.st_size;
					CHECK(unlink(entry->d_name) != -1);
				}
			}
			++count;
		}
	}
	CHECK(closedir(dir) != -1);
	return result;
}
Esempio n. 19
0
/* Randomly select something to do with a file */
static void operate_on_file(struct file_info *file)
{
	/* Try to keep at least 10 files open */
	if (open_files_count < 10) {
		file_open(file);
		return;
	}
	/* Try to keep about 20 files open */
	if (open_files_count < 20 && tests_random_no(2) == 0) {
		file_open(file);
		return;
	}
	/* Try to keep up to 40 files open */
	if (open_files_count < 40 && tests_random_no(20) == 0) {
		file_open(file);
		return;
	}
	/* Occasionly truncate */
	if (shrink && tests_random_no(100) == 0) {
		file_truncate_file(file);
		return;
	}
	/* Mostly just write */
	file_write_file(file);
	/* Once in a while check it too */
	if (tests_random_no(100) == 1) {
		int fd = -2;

		if (file->links)
			fd = -1;
		else if (file->fds)
			fd = file->fds->fd;
		if (fd != -2) {
			check_run_no += 1;
			file_check(file, fd);
		}
	}
}
Esempio n. 20
0
/* Randomly select something to do with an open file */
static void operate_on_open_file(struct fd_info *fdi)
{
	size_t r;

	r = tests_random_no(1000);
	if (shrink && r == 0)
		file_truncate(fdi->file, fdi->fd);
	else if (r < 21)
		file_close(fdi);
	else if (shrink && r < 121 && !fdi->file->deleted)
		file_delete(fdi->file);
	else
		file_write(fdi->file, fdi->fd);
}
Esempio n. 21
0
/* Randomly select something to do with a directory entry */
static void operate_on_entry(struct dir_entry_info *entry)
{
	/* 1 time in 1000 rename */
	if (tests_random_no(1000) == 0) {
		rename_entry(entry);
		return;
	}
	if (entry->type == 's') {
		symlink_check(entry->entry.symlink);
		/* If shrinking, 1 time in 50, remove a symlink */
		if (shrink && tests_random_no(50) == 0)
			symlink_remove(entry->entry.symlink);
		return;
	}
	if (entry->type == 'd') {
		/* If shrinking, 1 time in 50, remove a directory */
		if (shrink && tests_random_no(50) == 0) {
			dir_remove(entry->entry.dir);
			return;
		}
		operate_on_dir(entry->entry.dir);
	}
	if (entry->type == 'f') {
		/* If shrinking, 1 time in 10, remove a file */
		if (shrink && tests_random_no(10) == 0) {
			file_delete(entry->entry.file);
			return;
		}
		/* If not growing, 1 time in 10, unlink a file with links > 1 */
		if (!grow && entry->entry.file->link_count > 1 &&
		    tests_random_no(10) == 0) {
			file_unlink_file(entry->entry.file);
			return;
		}
		operate_on_file(entry->entry.file);
	}
}
Esempio n. 22
0
static void file_write(struct file_info *file, int fd)
{
	off_t offset;
	size_t size, actual;
	unsigned seed;
	int truncate = 0;

	if (can_mmap && !full && !file->deleted && tests_random_no(100) == 1) {
		file_mmap_write(file);
		return;
	}

	get_offset_and_size(file, &offset, &size);
	seed = tests_random_no(10000000);
	actual = file_write_data(file, fd, offset, size, seed);

	if (offset + actual <= file->length && shrink)
		/* 1 time in 100, when shrinking
		   truncate after the write */
		if (tests_random_no(100) == 0)
			truncate = 1;

	if (actual != 0)
		file_write_info(file, offset, actual, seed);

	/* Delete errored files */
	if (!check_nospc_files && file->no_space_error) {
		file_delete(file);
		return;
	}

	if (truncate) {
		size_t new_length = offset + actual;
		if (file_ftruncate(file, fd, new_length))
			file_truncate_info(file, new_length);
	}
}
Esempio n. 23
0
/* Randomly select something to do with a directory */
static void operate_on_dir(struct dir_info *dir)
{
	size_t r;
	struct dir_entry_info *entry;

	r = tests_random_no(12);
	if (r == 0 && grow)
		/* When growing, 1 time in 12 create a file */
		file_new(dir, make_name(dir));
	else if (r == 1 && grow)
		/* When growing, 1 time in 12 create a directory */
		dir_new(dir, make_name(dir));
	else {
		/* Otherwise randomly select an entry to operate on */
		r = tests_random_no(dir->number_of_entries);
		entry = dir->first;
		while (entry && r) {
			entry = entry->next;
			--r;
		}
		if (entry)
			operate_on_entry(entry);
	}
}
Esempio n. 24
0
static char *make_name(struct dir_info *dir)
{
	static char name[256];
	struct dir_entry_info *entry;
	int found;

	do {
		found = 0;
		sprintf(name, "%u", (unsigned) tests_random_no(1000000));
		for (entry = dir->first; entry; entry = entry->next) {
			if (strcmp(dir_entry_name(entry), name) == 0) {
				found = 1;
				break;
			}
		}
	} while (found);
	return name;
}
Esempio n. 25
0
/* Select an open file at random */
static void operate_on_an_open_file(void)
{
	size_t r;
	struct open_file_info *ofi;

	/* When shrinking, close all open files 1 time in 128 */
	if (shrink) {
		static int x = 0;

		x += 1;
		x &= 127;
		if (x == 0) {
			close_open_files();
			return;
		}
	}
	/* Close any open files that have errored */
	if (!check_nospc_files) {
		ofi = open_files;
		while (ofi) {
			if (ofi->fdi->file->no_space_error) {
				struct fd_info *fdi;

				fdi = ofi->fdi;
				ofi = ofi->next;
				file_close(fdi);
			} else
				ofi = ofi->next;
		}
	}
	r = tests_random_no(open_files_count);
	for (ofi = open_files; ofi; ofi = ofi->next, --r)
		if (!r) {
			operate_on_open_file(ofi->fdi);
			return;
		}
}
Esempio n. 26
0
/* Select an open file at random */
static void operate_on_an_open_file(void)
{
	size_t r;
	struct open_file_info *ofi;

	/* Close any open files that have errored */
	ofi = open_files;
	while (ofi) {
		if (ofi->fdi->file->no_space_error) {
			struct fd_info *fdi;

			fdi = ofi->fdi;
			ofi = ofi->next;
			file_close(fdi);
		} else
			ofi = ofi->next;
	}
	r = tests_random_no(open_files_count);
	for (ofi = open_files; ofi; ofi = ofi->next, --r)
		if (!r) {
			operate_on_open_file(ofi->fdi);
			return;
		}
}
/*
 * Re-mount test file system. Randomly choose how to do this: re-mount R/O then
 * re-mount R/W, or unmount, then mount R/W, or unmount then mount R/O then
 * re-mount R/W, etc. This should improve test coverage.
 */
void tests_remount(void)
{
	int err;
	struct mntent mount_info;
	char *source, *target, *filesystemtype, *data;
	char cwd[4096];
	unsigned long mountflags, flags;
	unsigned int rorw1, um, um_ro, um_rorw, rorw2;

	CHECK(tests_get_mount_info(&mount_info));

	if (strcmp(mount_info.mnt_dir,"/") == 0)
		return;

	/* Save current working directory */
	CHECK(getcwd(cwd, 4096) != NULL);
	/* Temporarily change working directory to '/' */
	CHECK(chdir("/") != -1);

	/* Choose what to do */
	rorw1 = tests_random_no(2);
	um = tests_random_no(2);
	um_ro = tests_random_no(2);
	um_rorw = tests_random_no(2);
	rorw2 = tests_random_no(2);

	if (rorw1 + um + rorw2 == 0)
		um = 1;

	source = mount_info.mnt_fsname;
	target = tests_file_system_mount_dir;
	filesystemtype = tests_file_system_type;
	data = mount_info.mnt_opts;
	process_mount_options(&data, &mountflags);

	if (rorw1) {
		/* Re-mount R/O and then re-mount R/W */
		flags = mountflags | MS_RDONLY | MS_REMOUNT;
		err = mount(source, target, filesystemtype, flags, data);
		CHECK(err != -1);

		flags = mountflags | MS_REMOUNT;
		flags &= ~((unsigned long)MS_RDONLY);
		err = mount(source, target, filesystemtype, flags, data);
		CHECK(err != -1);
	}

	if (um) {
		/* Unmount and mount */
		if (um_ro) {
			/* But re-mount R/O before unmounting */
			flags = mountflags | MS_RDONLY | MS_REMOUNT;
			err = mount(source, target, filesystemtype,
				    flags, data);
			CHECK(err != -1);
		}

		CHECK(umount(target) != -1);

		if (!um_rorw) {
			/* Mount R/W straight away */
			err = mount(source, target, filesystemtype,
				    mountflags, data);
			CHECK(err != -1);
		} else {
			/* Mount R/O and then re-mount R/W */
			err = mount(source, target, filesystemtype,
				    mountflags | MS_RDONLY, data);
			CHECK(err != -1);

			flags = mountflags | MS_REMOUNT;
			flags &= ~((unsigned long)MS_RDONLY);
			err = mount(source, target, filesystemtype,
				    flags, data);
			CHECK(err != -1);
		}
	}

	if (rorw2) {
		/* Re-mount R/O and then re-mount R/W */
		flags = mountflags | MS_RDONLY | MS_REMOUNT;
		err = mount(source, target, filesystemtype, flags, data);
		CHECK(err != -1);

		flags = mountflags | MS_REMOUNT;
		flags &= ~((unsigned long)MS_RDONLY);
		err = mount(source, target, filesystemtype, flags, data);
		CHECK(err != -1);
	}

	/* Restore the previous working directory */
	CHECK(chdir(cwd) != -1);
}
Esempio n. 28
0
static void file_mmap_write(struct file_info *file)
{
	size_t write_cnt = 0, r, i, len, size;
	struct write_info *w = file->writes;
	void *addr;
	char *waddr;
	off_t offs, offset;
	unsigned seed;
	uint64_t free_space;
	int fd;
	char *path;

	if (!file->links)
		return;
	free_space = tests_get_free_space();
	if (!free_space)
		return;
	/* Randomly pick a written area of the file */
	if (!w)
		return;
	while (w) {
		write_cnt += 1;
		w = w->next;
	}
	r = tests_random_no(write_cnt);
	w = file->writes;
	for (i = 0; w && w->next && i < r; i++)
		w = w->next;

	offs = (w->offset / mem_page_size) * mem_page_size;
	len = w->size + (w->offset - offs);
	if (len > 1 << 24)
		len = 1 << 24;

	/* Open it */
	path = dir_path(file->links->parent, file->links->name);
	fd = open(path, O_RDWR);
	CHECK(fd != -1);
	free(path);

	/* mmap it */
	addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offs);
	CHECK(close(fd) != -1);
	CHECK(addr != MAP_FAILED);

	/* Randomly select a part of the mmapped area to write */
	size = tests_random_no(w->size);
	if (size > free_space)
		size = free_space;
	if (size == 0)
		size = 1;
	offset = w->offset + tests_random_no(w->size - size);

	/* Write it */
	seed = tests_random_no(10000000);
	srand(seed);
	waddr = addr + (offset - offs);
	for (i = 0; i < size; i++)
		waddr[i] = rand();

	/* Unmap it */
	CHECK(munmap(addr, len) != -1);

	/* Record what was written */
	file_write_info(file, offset, size, seed);
}
Esempio n. 29
0
/* Remove a random file of empty sub-directory from the current directory */
static int64_t remove_entry(void)
{
	DIR *dir;
	struct dirent *entry;
	unsigned count = 0, pos;
	int64_t result = 0;

	before();
	dir = opendir(".");
	CHECK(dir != NULL);
	after("opendir");
	for (;;) {
		errno = 0;
		before();
		entry = readdir(dir);
		if (entry) {
			after("readdir 1");
			if (strcmp(".",entry->d_name) != 0 &&
					strcmp("..",entry->d_name) != 0)
				++count;
		} else {
			CHECK(errno == 0);
			after("readdir 1");
			break;
		}
	}
	pos = tests_random_no(count);
	count = 0;
	before();
	rewinddir(dir);
	after("rewinddir");
	for (;;) {
		errno = 0;
		before();
		entry = readdir(dir);
		if (!entry) {
			CHECK(errno == 0);
			after("readdir 2");
			break;
		}
		after("readdir 2");
		if (strcmp(".",entry->d_name) != 0 &&
				strcmp("..",entry->d_name) != 0) {
			if (count == pos) {
				if (entry->d_type == DT_DIR) {
					before();
					tests_clear_dir(entry->d_name);
					after("tests_clear_dir");
					before();
					CHECK(rmdir(entry->d_name) != -1);
					after("rmdir");
					result = TESTS_EMPTY_DIR_SIZE;
					dirs_removed += 1;
				} else {
					struct stat st;
					before();
					CHECK(stat(entry->d_name, &st) != -1);
					after("stat");
					result = st.st_size;
					before();
					CHECK(unlink(entry->d_name) != -1);
					after("unlink");
					files_removed += 1;
				}
			}
			++count;
		}
	}
	before();
	CHECK(closedir(dir) != -1);
	after("closedir");
	return result;
}
Esempio n. 30
0
static void rndrm99(void)
{
	int64_t repeat, loop_cnt;
	int64_t size, this_size;
	pid_t pid;
	char dir_name[256];

	size_ptr = &size;
	/* Create a directory to test in */
	pid = getpid();
	tests_cat_pid(dir_name, "rndrm99_test_dir_", pid);
	if (chdir(dir_name) == -1)
		CHECK(mkdir(dir_name, 0777) != -1);
	CHECK(chdir(dir_name) != -1);
	/* Repeat loop */
	repeat = tests_repeat_parameter;
	size = 0;
	for (;;) {
		/* Create and remove sub-dirs and small files, */
		/* but tending to grow */
		printf("\nrndrm99: growing\n");fflush(stdout);
		loop_cnt = 0;
		do {
			if (loop_cnt++ % 2000 == 0)
				display_stats();
			if (tests_random_no(3)) {
				this_size = create_entry(NULL);
				if (!this_size)
					break;
				size += this_size;
			} else {
				this_size = remove_entry();
				size -= this_size;
				if (size < 0)
					size = 0;
				if (!this_size)
					this_size = 1;
			}
		} while (this_size &&
			(tests_size_parameter == 0 ||
			size < tests_size_parameter));
		/* Create and remove sub-dirs and small files, but */
		/* but tending to shrink */
		printf("\nrndrm99: shrinking\n");fflush(stdout);
		loop_cnt = 0;
		do {
			if (loop_cnt++ % 2000 == 0)
				display_stats();
			if (!tests_random_no(3)) {
				this_size = create_entry(NULL);
				size += this_size;
			} else {
				this_size = remove_entry();
				size -= this_size;
				if (size < 0)
					size = 0;
			}
		} while ((tests_size_parameter != 0 &&
			size > tests_size_parameter / 10) ||
			(tests_size_parameter == 0 && size > 100000));
		/* Break if repeat count exceeded */
		if (tests_repeat_parameter > 0 && --repeat <= 0)
			break;
		/* Sleep */
		if (tests_sleep_parameter > 0) {
			unsigned us = tests_sleep_parameter * 1000;
			unsigned rand_divisor = RAND_MAX / us;
			unsigned s = (us / 2) + (rand() / rand_divisor);
			printf("\nrndrm99: sleeping\n");fflush(stdout);
			usleep(s);
		}
	}
	printf("\nrndrm99: tidying\n");fflush(stdout);
	display_stats();
	/* Tidy up by removing everything */
	tests_clear_dir(".");
	CHECK(chdir("..") != -1);
	CHECK(rmdir(dir_name) != -1);
	size_ptr = 0;
}