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

📄 rndrm99.c

📁 mtd-utils 是一套更改linux mtd設備的工具
💻 C
字号:
/* * Copyright (C) 2007 Nokia Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Author: Adrian Hunter */#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <stdint.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <sys/time.h>#include <time.h>#include <sys/vfs.h>#include <sys/statvfs.h>#include <dirent.h>#include <ctype.h>#include <limits.h>#include "tests.h"uint32_t files_created = 0;uint32_t files_removed = 0;uint32_t dirs_created = 0;uint32_t dirs_removed = 0;int64_t *size_ptr = 0;void display_stats(void){	printf(	"\nrndrm99 stats:\n"		"\tNumber of files created = %u\n"		"\tNumber of files deleted = %u\n"		"\tNumber of directories created = %u\n"		"\tNumber of directories deleted = %u\n"		"\tCurrent net size of creates and deletes = %lld\n",		(unsigned) files_created,		(unsigned) files_removed,		(unsigned) dirs_created,		(unsigned) dirs_removed,		(long long) (size_ptr ? *size_ptr : 0));	fflush(stdout);}struct timeval tv_before;struct timeval tv_after;void before(void){	CHECK(gettimeofday(&tv_before, NULL) != -1);}void after(const char *msg){	time_t diff;	CHECK(gettimeofday(&tv_after, NULL) != -1);	diff = tv_after.tv_sec - tv_before.tv_sec;	if (diff >= 8) {		printf("\nrndrm99: the following fn took more than 8 seconds: %s (took %u secs)\n",msg,(unsigned) diff);		fflush(stdout);		display_stats();	}}#define WRITE_BUFFER_SIZE 32768static char write_buffer[WRITE_BUFFER_SIZE];static void init_write_buffer(){	static int init = 0;	if (!init) {		int i, d;		uint64_t u;		u = RAND_MAX;		u += 1;		u /= 256;		d = (int) u;		srand(1);		for (i = 0; i < WRITE_BUFFER_SIZE; ++i)			write_buffer[i] = rand() / d;		init = 1;	}}/* Write size random bytes into file descriptor fd at the current position,   returning the number of bytes actually written */uint64_t fill_file(int fd, uint64_t size){	ssize_t written;	size_t sz;	unsigned start = 0, length;	uint64_t remains;	uint64_t actual_size = 0;	init_write_buffer();	remains = size;	while (remains > 0) {		length = WRITE_BUFFER_SIZE - start;		if (remains > length)			sz = length;		else			sz = (size_t) remains;		before();		written = write(fd, write_buffer + start, sz);		if (written <= 0) {			CHECK(errno == ENOSPC); /* File system full */			errno = 0;			after("write");			fprintf(stderr,"\nrndrm99: write failed with ENOSPC\n");fflush(stderr);			display_stats();			break;		}		after("write");		remains -= written;		actual_size += written;		if ((size_t) written == sz)			start = 0;		else			start += written;	}	return actual_size;}/* Create a file of size file_size */uint64_t create_file(const char *file_name, uint64_t file_size){	int fd;	int flags;	mode_t mode;	uint64_t actual_size; /* Less than size if the file system is full */	flags = O_CREAT | O_TRUNC | O_WRONLY;	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;	before();	fd = open(file_name, flags, mode);	if (fd == -1 && errno == ENOSPC) {		errno = 0;		after("open");		fprintf(stderr,"\nrndrm99: open failed with ENOSPC\n");fflush(stderr);		display_stats();		return 0; /* File system full */	}	CHECK(fd != -1);	after("open");	actual_size = fill_file(fd, file_size);	before();	CHECK(close(fd) != -1);	after("close");	if (file_size != 0 && actual_size == 0) {		printf("\nrndrm99: unlinking zero size file\n");fflush(stdout);		before();		CHECK(unlink(file_name) != -1);		after("unlink (create_file)");	}	return actual_size;}/* Create an empty sub-directory or small file in the current directory */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;	}}/* Remove a random file of empty sub-directory from the current directory */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;}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;}/* Title of this test */const char *rndrm99_get_title(void){	return "Randomly create and remove directories and files";}/* Description of this test */const char *rndrm99_get_description(void){	return		"Create a directory named rndrm99_test_dir_pid, where " \		"pid is the process id.  Within that directory, " \		"randomly create and remove " \		"a number of sub-directories and small files, " \		"but do more creates than removes. " \		"When the total size of all sub-directories and files " \		"is greater than the size specified by the size parameter, " \		"start to do more removes than creates. " \		"The size parameter is given by the -z or --size option, " \		"otherwise it defaults to 1000000. " \		"A size of zero fills the file system until there is no "		"space left. " \		"The task repeats, sleeping in between each iteration. " \		"The repeat count is set by the -n or --repeat option, " \		"otherwise it defaults to 1. " \		"A repeat count of zero repeats forever. " \		"The sleep value is given by the -p or --sleep option, " \		"otherwise it defaults to 0. "		"Sleep is specified in milliseconds.";}int main(int argc, char *argv[]){	int run_test;	/* Set default test size */	tests_size_parameter = 1000000;	/* Set default test repetition */	tests_repeat_parameter = 1;	/* Set default test sleep */	tests_sleep_parameter = 0;	/* Handle common arguments */	run_test = tests_get_args(argc, argv, rndrm99_get_title(),			rndrm99_get_description(), "znp");	if (!run_test)		return 1;	/* Change directory to the file system and check it is ok for testing */	tests_check_test_file_system();	/* Do the actual test */	rndrm99();	return 0;}

⌨️ 快捷键说明

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