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

📄 fsx.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1998-2001 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License").  You may not use this file except in compliance with the * License.  Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ * *	File:	fsx.c *	Author:	Avadis Tevanian, Jr. * *	File system exerciser. * *	Rewrite and enhancements 1998-2001 Conrad Minshall -- conrad@mac.com * *	Various features from Joe Sokol, Pat Dirks, and Clark Warner. * *	Small changes to work under Linux -- davej@suse.de * *	Sundry porting patches from Guy Harris 12/2001 * $FreeBSD: src/tools/regression/fsx/fsx.c,v 1.1 2001/12/20 04:15:57 jkh Exp $ */#include <sys/types.h>#include <sys/stat.h>#if defined(_UWIN) || defined(__linux__)# include <sys/param.h># include <limits.h># include <time.h># include <strings.h># include <sys/time.h>#endif#include <fcntl.h>#include <sys/mman.h>#ifndef MAP_FILE# define MAP_FILE 0#endif#include <limits.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <stdarg.h>#include <errno.h>#define NUMPRINTCOLUMNS 32	/* # columns of data to print on each line *//* *	A log entry is an operation and a bunch of arguments. */struct log_entry {	int	operation;	struct timeval tv;	int	args[3];};#define	LOGSIZE	1000struct log_entry	oplog[LOGSIZE];	/* the log */int			logptr = 0;	/* current position in log */int			logcount = 0;	/* total ops *//* *	Define operations */#define	OP_READ		1#define OP_WRITE	2#define OP_TRUNCATE	3#define OP_CLOSEOPEN	4#define OP_MAPREAD	5#define OP_MAPWRITE	6#define OP_SKIPPED	7int page_size;int page_mask;char	*original_buf;			/* a pointer to the original data */char	*good_buf;			/* a pointer to the correct data */char	*temp_buf;			/* a pointer to the current data */char	*fname;				/* name of our test file */char	logfile[1024];			/* name of our log file */char	goodfile[1024];			/* name of our test file */off_t		file_size = 0;off_t		biggest = 0;char		state[256];unsigned long	testcalls = 0;		/* calls to function "test" */unsigned long	simulatedopcount = 0;	/* -b flag */int	closeprob = 0;			/* -c flag */int	debug = 0;			/* -d flag */unsigned long	debugstart = 0;		/* -D flag */unsigned long	maxfilelen = 256 * 1024;	/* -l flag */int	sizechecks = 1;			/* -n flag disables them */int	maxoplen = 64 * 1024;		/* -o flag */int	quiet = 0;			/* -q flag */unsigned long progressinterval = 0;	/* -p flag */int	readbdy = 1;			/* -r flag */int	style = 0;			/* -s flag */int	truncbdy = 1;			/* -t flag */int	writebdy = 1;			/* -w flag */long	monitorstart = -1;		/* -m flag */long	monitorend = -1;		/* -m flag */int	lite = 0;			/* -L flag */long	numops = -1;			/* -N flag */int	randomoplen = 1;		/* -O flag disables it */int	seed = 1;			/* -S flag */int     mapped_writes = 1;              /* -W flag disables */int 	mapped_reads = 1;		/* -R flag disables it */int	fsxgoodfd = 0;FILE *	fsxlogf = NULL;int badoff = -1;voidvwarnc(code, fmt, ap)	int code;	const char *fmt;	va_list ap;{	fprintf(stderr, "fsx: ");	if (fmt != NULL) {		vfprintf(stderr, fmt, ap);		fprintf(stderr, ": ");	}	fprintf(stderr, "%s\n", strerror(code));}voidwarn(const char * fmt, ...){	va_list ap;	va_start(ap, fmt);	vwarnc(errno, fmt, ap);	va_end(ap);}void__attribute__((format(printf, 1, 2)))prt(char *fmt, ...){	va_list args;	va_start(args, fmt);	vfprintf(stdout, fmt, args);	va_end(args);	if (fsxlogf) {		va_start(args, fmt);		vfprintf(fsxlogf, fmt, args);		va_end(args);	}}voidprterr(char *prefix){	prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(errno));}voidlog4(int operation, int arg0, int arg1, int arg2, struct timeval *tv){	struct log_entry *le;	le = &oplog[logptr];	le->tv = *tv;	le->operation = operation;	le->args[0] = arg0;	le->args[1] = arg1;	le->args[2] = arg2;	logptr++;	logcount++;	if (logptr >= LOGSIZE)		logptr = 0;}voidlogdump(void){	int	i, count, down;	struct log_entry	*lp;	prt("LOG DUMP (%d total operations):\n", logcount);	if (logcount < LOGSIZE) {		i = 0;		count = logcount;	} else {		i = logptr;		count = LOGSIZE;	}	for ( ; count > 0; count--) {		int opnum;		opnum = i+1 + (logcount/LOGSIZE)*LOGSIZE;		lp = &oplog[i];		prt("%d: %lu.%06lu ", opnum,		    lp->tv.tv_sec, lp->tv.tv_usec);		switch (lp->operation) {		case OP_MAPREAD:			prt("MAPREAD  0x%x thru 0x%x (0x%x bytes)",			    lp->args[0], lp->args[0] + lp->args[1] - 1,			    lp->args[1]);			if (badoff >= lp->args[0] && badoff <						     lp->args[0] + lp->args[1])				prt("\t***RRRR***");			break;		case OP_MAPWRITE:			prt("MAPWRITE 0x%x thru 0x%x (0x%x bytes)",			    lp->args[0], lp->args[0] + lp->args[1] - 1,			    lp->args[1]);			if (badoff >= lp->args[0] && badoff <						     lp->args[0] + lp->args[1])				prt("\t******WWWW");			break;		case OP_READ:			prt("READ     0x%x thru 0x%x (0x%x bytes)",			    lp->args[0], lp->args[0] + lp->args[1] - 1,			    lp->args[1]);			if (badoff >= lp->args[0] &&			    badoff < lp->args[0] + lp->args[1])				prt("\t***RRRR***");			break;		case OP_WRITE:			prt("WRITE    0x%x thru 0x%x (0x%x bytes)",			    lp->args[0], lp->args[0] + lp->args[1] - 1,			    lp->args[1]);			if (lp->args[0] > lp->args[2])				prt(" HOLE");			else if (lp->args[0] + lp->args[1] > lp->args[2])				prt(" EXTEND");			if ((badoff >= lp->args[0] || badoff >=lp->args[2]) &&			    badoff < lp->args[0] + lp->args[1])				prt("\t***WWWW");			break;		case OP_TRUNCATE:			down = lp->args[0] < lp->args[1];			prt("TRUNCATE %s\tfrom 0x%x to 0x%x",			    down ? "DOWN" : "UP", lp->args[1], lp->args[0]);			if (badoff >= lp->args[!down] &&			    badoff < lp->args[!!down])				prt("\t******WWWW");			break;		case OP_CLOSEOPEN:			prt("CLOSE/OPEN");			break;		case OP_SKIPPED:			prt("SKIPPED (no operation)");			break;		default:			prt("BOGUS LOG ENTRY (operation code = %d)!",			    lp->operation);		}		prt("\n");		i++;		if (i == LOGSIZE)			i = 0;	}}voidsave_buffer(char *buffer, off_t bufferlength, int fd){	off_t ret;	ssize_t byteswritten;	if (fd <= 0 || bufferlength == 0)		return;	if (bufferlength > SSIZE_MAX) {		prt("fsx flaw: overflow in save_buffer\n");		exit(67);	}	if (lite) {		off_t size_by_seek = lseek(fd, (off_t)0, SEEK_END);		if (size_by_seek == (off_t)-1)			prterr("save_buffer: lseek eof");		else if (bufferlength > size_by_seek) {			warn("save_buffer: .fsxgood file too short... will"				"save 0x%llx bytes instead of 0x%llx\n", 				(unsigned long long)size_by_seek,				(unsigned long long)bufferlength);			bufferlength = size_by_seek;		}	}	ret = lseek(fd, (off_t)0, SEEK_SET);	if (ret == (off_t)-1)		prterr("save_buffer: lseek 0");	byteswritten = write(fd, buffer, (size_t)bufferlength);	if (byteswritten != bufferlength) {		if (byteswritten == -1)			prterr("save_buffer write");		else			warn("save_buffer: short write, 0x%x bytes instead"				"of 0x%llx\n",			     (unsigned)byteswritten,			     (unsigned long long)bufferlength);	}}voidreport_failure(int status){	logdump();	if (fsxgoodfd) {		if (good_buf) {			save_buffer(good_buf, file_size, fsxgoodfd);			prt("Correct content saved for comparison\n");			prt("(maybe hexdump \"%s\" vs \"%s\")\n",			    fname, goodfile);		}		close(fsxgoodfd);	}	exit(status);}#define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \				        *(((unsigned char *)(cp)) + 1)))voidcheck_buffers(unsigned offset, unsigned size){	unsigned char c, t;	unsigned i = 0;	unsigned n = 0;	unsigned op = 0;	unsigned bad = 0;	if (memcmp(good_buf + offset, temp_buf, size) != 0) {		prt("READ BAD DATA: offset = 0x%x, size = 0x%x\n",		    offset, size);		prt("OFFSET\tGOOD\tBAD\tRANGE\n");		while (size > 0) {			c = good_buf[offset];			t = temp_buf[i];			if (c != t) {			        if (n == 0) {					bad = short_at(&temp_buf[i]);				        prt("%#07x\t%#06x\t%#06x", offset,				            short_at(&good_buf[offset]), bad);					op = temp_buf[offset & 1 ? i+1 : i];				}				n++;				badoff = offset;			}			offset++;			i++;			size--;		}		if (n) {		        prt("\t%#7x\n", n);			if (bad)				prt("operation# (mod 256) for the bad data"					"may be %u\n", ((unsigned)op & 0xff));			else				prt("operation# (mod 256) for the bad data"					"unknown, check HOLE and EXTEND ops\n");		} else		        prt("????????????????\n");		report_failure(110);	}}struct test_file {	char *path;	int fd;} *test_files = NULL;int num_test_files = 0;enum fd_iteration_policy {	FD_SINGLE,	FD_ROTATE,	FD_RANDOM,};int fd_policy = FD_RANDOM;int fd_last = 0;struct test_file * get_tf(void){	unsigned index = 0;	switch (fd_policy) {		case FD_ROTATE:			index = fd_last++;			break;		case FD_RANDOM:			index = random();			break;		case FD_SINGLE:			index = 0;			break;		default:			prt("unknown policy");			exit(1);			break;	}	return &test_files[ index % num_test_files ];}voidassign_fd_policy(char *policy){	if (!strcmp(policy, "random"))		fd_policy = FD_RANDOM;	else if (!strcmp(policy, "rotate"))		fd_policy = FD_ROTATE;	else {		prt("unknown -I policy: '%s'\n", policy);		exit(1);	}}intget_fd(void){	struct test_file *tf = get_tf();	return tf->fd;}static const char *my_basename(const char *path){	char *c = strrchr(path, '/');	return c ? c++ : path;}voidopen_test_files(char **argv, int argc){	struct test_file *tf;	int i;	num_test_files = argc;	if (num_test_files == 1)		fd_policy = FD_SINGLE;	test_files = calloc(num_test_files, sizeof(*test_files));	if (test_files == NULL) {		prterr("reallocating space for test files");

⌨️ 快捷键说明

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