⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 integck.c

📁 mtd-utils 是一套更改linux mtd設備的工具
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (errno == ENOSPC)			full = 1;		CHECK(errno == ENOSPC || errno == EBUSY);		free(path);		free(name);		free(to);		return;	}	free(path);	free(to);	if (rename_entry && rename_entry->type == entry->type &&	    rename_entry->entry.target == entry->entry.target) {		free(name);		return;	}	add_dir_entry(parent, entry->type, name, entry->entry.target);	if (rename_entry)		remove_dir_entry(rename_entry);	remove_dir_entry(entry);	free(name);}static size_t str_count(const char *s, char c){	size_t count = 0;	char cc;	while ((cc = *s++) != '\0')		if (cc == c)			count += 1;	return count;}static char *relative_path(const char *path1, const char *path2){	const char *p1, *p2;	char *rel;	size_t up, len, len2, i;	p1 = path1;	p2 = path2;	while (*p1 == *p2 && *p1) {		p1 += 1;		p2 += 1;	}	len2 = strlen(p2);	up = str_count(p1, '/');	if (up == 0 && len2 != 0)		return copy_string(p2);	if (up == 0 && len2 == 0) {		p2 = strrchr(path2, '/');		return copy_string(p2);	}	if (up == 1 && len2 == 0)		return copy_string(".");	if (len2 == 0)		up -= 1;	len = up * 3 + len2 + 1;	rel = malloc(len);	CHECK(rel != NULL);	rel[0] = '\0';	if (up) {		strcat(rel, "..");		for (i = 1; i < up; i++)			strcat(rel, "/..");		if (len2)			strcat(rel, "/");	}	if (len2)		strcat(rel, p2);	return rel;}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;}static void symlink_new(struct dir_info *dir, const char *name_){	struct symlink_info *s;	char *path, *target, *name = copy_string(name_);	size_t sz;	path = dir_path(dir, name);	target = pick_symlink_target(path);	if (symlink(target, path) == -1) {		CHECK(errno == ENOSPC || errno == ENAMETOOLONG);		if (errno == ENOSPC)			full = 1;		free(target);		free(path);		free(name);		return;	}	free(path);	sz = sizeof(struct symlink_info);	s = malloc(sz);	CHECK(s != NULL);	memset(s, 0, sz);	add_dir_entry(dir, 's', name, s);	s->target_pathname = target;	free(name);}static void symlink_remove(struct symlink_info *symlink){	char *path;	path = dir_path(symlink->entry->parent, symlink->entry->name);	remove_dir_entry(symlink->entry);	CHECK(unlink(path) != -1);	free(path);}static void operate_on_dir(struct dir_info *dir);static void operate_on_file(struct file_info *file);/* 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);	}}/* 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);	}}/* 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);		}	}}/* 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);		}	}}/* 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;		}}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();}static void create_test_data(void){	uint64_t i, n;	grow = 1;	shrink = 0;	full = 0;	operation_count = 0;	while (!full) {		do_an_operation();		++operation_count;	}	grow = 0;	shrink = 1;	/* Drop to less than 90% full */	n = operation_count / 40;	while (n--) {		uint64_t free;		uint64_t total;		for (i = 0; i < 10; ++i)			do_an_operation();		free = tests_get_free_space();		total = tests_get_total_space();		if ((free * 100) / total >= 10)			break;	}	grow = 0;	shrink = 0;	full = 0;	n = operation_count * 2;	for (i = 0; i < n; ++i)		do_an_operation();}static void update_test_data(void){	uint64_t i, n;	grow = 1;	shrink = 0;	full = 0;	while (!full)		do_an_operation();	grow = 0;	shrink = 1;	/* Drop to less than 50% full */	n = operation_count / 10;	while (n--) {		uint64_t free;		uint64_t total;		for (i = 0; i < 10; ++i)			do_an_operation();		free = tests_get_free_space();		total = tests_get_total_space();		if ((free * 100) / total >= 50)			break;	}	grow = 0;	shrink = 0;	full = 0;	n = operation_count * 2;	for (i = 0; i < n; ++i)		do_an_operation();}void integck(void){	pid_t pid;	int64_t rpt;	uint64_t z;	char dir_name[256];	/* Get memory page size for mmap */	mem_page_size = sysconf(_SC_PAGE_SIZE);	CHECK(mem_page_size > 0);	/* Make our top directory */	pid = getpid();	printf("pid is %u\n", (unsigned) pid);	tests_cat_pid(dir_name, "integck_test_dir_", pid);	if (chdir(dir_name) != -1) {		/* Remove it if it is already there */		tests_clear_dir(".");		CHECK(chdir("..") != -1);		CHECK(rmdir(dir_name) != -1);	}	initial_free_space = tests_get_free_space();	log10_initial_free_space = 0;	for (z = initial_free_space; z >= 10; z /= 10)		++log10_initial_free_space;	top_dir = dir_new(NULL, dir_name);	if (!top_dir)		return;	srand(pid);	create_test_data();	if (!tests_fs_is_rootfs()) {		close_open_files();		tests_remount(); /* Requires root access */	}	/* Check everything */	check_run_no += 1;	dir_check(top_dir);	check_deleted_files();	for (rpt = 0; tests_repeat_parameter == 0 ||				rpt < tests_repeat_parameter; ++rpt) {		update_test_data();		if (!tests_fs_is_rootfs()) {			close_open_files();			tests_remount(); /* Requires root access */		}		/* Check everything */		check_run_no += 1;		dir_check(top_dir);		check_deleted_files();	}	/* Tidy up by removing everything */	close_open_files();	tests_clear_dir(dir_name);	CHECK(rmdir(dir_name) != -1);}/* Title of this test */const char *integck_get_title(void){	return "Test file system integrity";}/* Description of this test */const char *integck_get_description(void){	return		"Create a directory named integck_test_dir_pid " \		"where pid is the process id. " \		"Randomly create and delete files and directories. " \		"Randomly write to and truncate files. " \		"Un-mount and re-mount test file " \		"system (if it is not the root file system ). " \		"Check data. Make more random changes. " \		"Un-mount and re-mount again. Check again. " \		"Repeat some number of times. "		"The repeat count is set by the -n or --repeat option, " \		"otherwise it defaults to 1. " \		"A repeat count of zero repeats forever.";}int main(int argc, char *argv[]){	int run_test;	/* Set default test repetition */	tests_repeat_parameter = 1;	/* Handle common arguments */	run_test = tests_get_args(argc, argv, integck_get_title(),			integck_get_description(), "n");	if (!run_test)		return 1;	/* Change directory to the file system and check it is ok for testing */	tests_check_test_file_system();	/*	 * We expect accurate file size from ubifs even after "no space"	 * errors. And we can mmap.	 */	if (strcmp(tests_file_system_type, "ubifs") == 0) {		check_nospc_files = 1;		can_mmap = 1;	}	/* Do the actual test */	integck();	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -