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

📄 dtaio.c

📁 Linux磁盘测试的源代码,测试磁盘的读写性能
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************** *									    * *			  COPYRIGHT (c) 1990 - 2004			    * *			   This Software Provided			    * *				     By					    * *			  Robin's Nest Software Inc.			    * *									    * * Permission to use, copy, modify, distribute and sell this software and   * * its documentation for any purpose and without fee is hereby granted,	    * * provided that the above copyright notice appear in all copies and that   * * both that copyright notice and this permission notice appear in the	    * * supporting documentation, and that the name of the author not be used    * * in advertising or publicity pertaining to distribution of the software   * * without specific, written prior permission.				    * *									    * * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 	    * * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN	    * * NO EVENT SHALL HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL   * * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR    * * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS  * * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF   * * THIS SOFTWARE.							    * *									    * ****************************************************************************//* * Module:	dtaio.c * Author:	Robin T. Miller * Date:	August 26, 1993  * * Description: *	Functions to handle POSIX Asynchronous I/O requests for 'dt' program. */#if defined(AIO)#include "dt.h"#include <aio.h>#include <limits.h>#include <sys/stat.h>#if !defined(AIO_PRIO_DFL)#  define AIO_PRIO_DFL	0		/* Default scheduling priority. */#endif /* !defined(AIO_PRIO_DFL) *//* * Modification History: * * February 13th, 2004 by Robin Miller. *      Factor in the file position when doing reverse I/O, to avoid * writing/reading into that area (which is now deemed protected). * * November 17th, 2003 by Robin Miller. *	Breakup output to stdout or stderr, rather than writing * all output to stderr.  If output file is stdout ('-') or a log * file is specified, then all output reverts to stderr. * * January 17th, 2003 by Robin Miller. *	On HP-UX, accept ENXIO for I/O's pass EOF. * * November 14th, 2002 by Robin Miller. *	On HP-UX, initialize aiocb->aio_sigevent field, or else * EINVAL is returned.  aio_sigevent.sigev_notify = SIGEV_NONE; * * June 25th, 2001 by Robin Miller. *	Restructured code associated with Tru64 Unix EEI, so we obtain * the EEI status for all tape errors, not just EIO errors. * * January 26th, 2001 by Robin Miller. *	Added support for reverse reading and writing. * * January 24th, 2001 by Robin Miller. *	Add support for variable I/O requests sizes. * * January 14th, 2001 by Robin Miller. *	Added support for multiple volumes option. *	Fixed multi-volume write w/lbdata option problem. * * October 4th, 2000 by Robin Miller. *	Update is_Eof() to accept ENXIO for AIO reads @ EOM on * SCO UnixWare systems.  All other systems return ENOSPC or zero. * * May 9th, 2000 by Robin Miller. *	Ensure the closing flag gets reset in dtaio_close_file() before * calling close_file(), or the file descriptor won't get closed! * * May 8th, 2000 by Robin Miller. *	Honor the di_closing flag, to avoid a race condition with the * close function being called again while still closing, from the * terminate() routine called by the runtime= alarm, or signals. * * February 17th, 2000 by Robin Miller. *	Adding better support for multi-volume tape testing.  Mainly, * make it work with writing multiple tape files, rather than one file. * * January 6th, 2000 by Robin Miller. *	Added support for multi-volume media. *	Added a couple missing aio_return() calls. * * December 30th, 1999 by Robin Miller. *	Modify call to do_random() to pass the transfer size. * * November 10th, 1999 by Robin Miller. *	If aio_return() fails, report device information. * * August 7th, 1999 by Robin Miller. *	Minor mods to support AIO on SCO UnixWare 7.1. * * July 29, 1999 by Robin Miller. *	Merge in changes made to compile on FreeBSD. * * July 22nd, 1999 by Robin Miller. *   o	Added support for IOT (DJ's) test pattern. *   o	Fixed problem writing wrong starting lba, when lbdata *	and random I/O options were enabled. *  * July 5th, 1999 by Robin Miller. *	Cleanup of compilation warnings on Linux. * * May 27, 1999 by Robin Miller. *	Added support for micro-second delays. * * March 1, 1999 by Robin Miller. *	For tapes when Debug is enabled, report the file number. * * January 13, 1998 by Robin Miller. *	Add support for restarting I/O's after EEI reset recovery. *	Modified dtaio_waitall() to optionally adjust data/file counts. * * December 21, 1998 by Robin Miller. *	Updates necessary to match tape API changes. * * November 16, 1998 by Robin Miller. *	Added pointer to current AIO control block for error reporting. * * October 26, 1998 by Robin Miller. *   o	Fix incorrect record number displayed when Debug is enabled. *   o	Don't exit read/write loops when processing partial records. *   o	Fix problem in write function, where short write processing, *	caused us not to write sufficent data bytes (actually, the *	file loop in write_file() caused dtaio_write_data() to be *	called again, and we'd actually end up writing too much! *   o	When random I/O and lbdata options are both enabled, use the *	file offset seeked to as the starting lbdata address. * * March 20, 1998 by Robin Miller. *	Update counts in dtaio_waitall() for accurate statistics. * * January 28, 1998 by Robin Miller. *	Add dtaio_close() function, to wait for queued I/O's when we're *	aborting, to avoid kernel I/O rundown problem, which panic's *	the system if we close the CAM disk driver device descriptor, *	prior to AIO's completing (fixed in steelos by Anton Verhulst). * * January 9, 1998 by Robin Miller. *	Don't initialize data buffer being written for "disable=compare" * which yields better performance. * * April 3, 1997 by Robin Miller. *	Removed use of undocumented AIO_SEEK_CUR in aio_offset. *	Also fixed bug where random I/O offset was clobbered, thus *	resulting in sequential I/O. * * February 28, 1996 by Robin Miller. *	Added support for copying and verifying device/files. *	Modified logic so read errors honor users' error limit. *	[ NOTE: Copy and verify operations are done sequentially. ] * * November 11, 1995 by Robin Miller. *	Fix bug with init'ing and performing pad byte verification. *	This caused variable length reads with small increment values *	to report an (invalid) pad byte data compare error. e.g.: * *	% dt of=/dev/rmt0h min=10k max=64k incr=1 pattern=incr * * July 17, 1995 by Robin Miller. *	Conditionalize aio_suspend() via "#if defined(POSIX_4D11)" for * earlier POSIX drafts so only one copy of this file is necessary. * [ NOTE: This is accomplished via -DPOSIX_4D11 in our Makefile. ] * * July 15, 1995 by Robin Miller. *	Fix end of media error handling (ENOSPC), and cleanup code. * * July 14, 1995 by Robin Miller. *	Add logic to allow rotating through 1st ROTATE_SIZE byes of buffers. *	[ This option was being silently ignored before, and nobody knew. ] * * April 15, 1994 by Wayne Casagrande. *	Update aiosuspend() interface, which now takes different arguments * due to POSIX standard changing. * * January 20, 1994 by Robin Miller. *	When initializing the data buffer, don't do the entire buffer since * init'ing large buffer (e.g. 100m) using min, max, and incr options cause * excessive paging and VERY poor performance. * * October 15, 1993 by Robin Miller. *	Sorry folks, major screw up on my part.  I forgot to redefine the * test function (tf_write_data) field to point a the dtaio_write_data() * function, so... synchronous writes were still being done (damn!!!). * Also fixed bug when writing to stop looping when end of file reached. *//* * Forward References: */#if 0static void dtaio_checkdevice(struct dinfo *dip);#endifstatic int dtaio_wait(struct dinfo *dip, struct aiocb *acbp);static int dtaio_waitall(struct dinfo *dip, bool canceling);static int dtaio_wait_reads(struct dinfo *dip);static int dtaio_wait_writes(struct dinfo *dip);static int dtaio_process_read(struct dinfo *dip, struct aiocb *acbp);static int dtaio_process_write(struct dinfo *dip, struct aiocb *acbp);#define AIO_BUFS	8		/* Default number of AIO buffers. */#define AIO_NotQed	-1		/* AIO request not queued flag.	*/int	aio_bufs = AIO_BUFS;		/* The number of AIO buffers.	*/int	aio_index;			/* Index to AIO control block.	*/volatile off_t aio_offset;		/* AIO offset (we maintain).	*/v_large	aio_data_bytes;			/* Total data bytes per pass.	*/v_large	aio_file_bytes;			/* # of tape bytes processed.	*/vu_long	aio_record_count;		/* # of records to processed.	*/u_int32	aio_lba;			/* AIO logical block address.	*//* * The following variables are meant to be used with tape devices to * backup unprocessed files and/or records due to read-ahead, to be * repositioned prior to the next test or before closing the tape. */u_long	aio_data_adjust;		/* # of data bytes to adjust.	*/u_long	aio_file_adjust;		/* # of tape files to adjust.	*/u_long	aio_record_adjust;		/* # of tape record to adjust.	*/struct aiocb	*acbs;			/* Pointer to AIO control blocks. */u_char		**aiobufs;		/* Pointer to base buffer addrs.  */struct aiocb	*current_acb;		/* Current acb for error reports. *//* * Declare the POSIX Asynchronous I/O test functions. */struct dtfuncs aio_funcs = {    /*	tf_open,		tf_close,		tf_initialize,	  */	open_file,		dtaio_close_file,	dtaio_initialize,    /*  tf_start_test,		tf_end_test,				  */	init_file,		nofunc,    /*	tf_read_file,		tf_read_data,		tf_cancel_reads,  */	read_file,		dtaio_read_data,	dtaio_cancel_reads,    /*	tf_write_file,		tf_write_data,		tf_cancel_writes, */	write_file,		dtaio_write_data,	nofunc,    /*	tf_flush_data,		tf_verify_data,		tf_reopen_file,   */	flush_file,		verify_data,		reopen_file,    /*	tf_startup,		tf_cleanup,		tf_validate_opts  */	nofunc,			nofunc,			validate_opts};/************************************************************************ *									* * dtaio_close_file() - Close an open file descriptor.			* *									* * Description:								* *	This function does the AIO file descriptor close processing.	* *									* * Inputs:	dip = The device information pointer.			* *									* * Return Value:							* *		Returns 0 / -1 = SUCCESS / FAILURE.			* *									* ************************************************************************/intdtaio_close_file (struct dinfo *dip){    int status = SUCCESS;    if (dip->di_closing || (dip->di_fd == NoFd)) {	return (status);		/* Closing or not open. */    }    /*     * Avoid cancel'ing I/O more than once using the closing flag.     * We can get called again by alarm expiring or signal handler.     */    dip->di_closing = TRUE;    (void) dtaio_cancel (dip);    status = dtaio_waitall (dip, FALSE);    dip->di_closing = FALSE;    return (close_file (dip));}/* * Allocate and initialize AIO data structures. */intdtaio_initialize (struct dinfo *dip){    struct aiocb *acbp;    size_t size = (sizeof(struct aiocb) * aio_bufs);    int index;    int status = SUCCESS;#if 0    /*     * This check isn't being done, since when linked with libaio.a,     * AIO is mimiced via multiple threads to any device, not just     * character devices as with libaioraw.a     */    dtaio_checkdevice (dip);#endif    if ( (dip->di_dtype->dt_dtype == DT_TAPE) && raw_flag && (aio_bufs > 1) ) {	Printf("Sorry, tapes are limited to 1 AIO with raw option!\n");	aio_bufs = 1;	size = (sizeof(struct aiocb) * aio_bufs);    }    aio_index = 0;    aio_offset = (off_t) 0;    if (acbs == NULL) {	acbs = (struct aiocb *) Malloc (size);	bzero ((char *) acbs, size);	if (rotate_flag) {	    size_t psize = (aio_bufs * sizeof(u_char *));	    aiobufs = (u_char **) Malloc (psize);	    bzero ((char *) aiobufs, psize);	}    }    for (index = 0, acbp = acbs; index < aio_bufs; index++, acbp++) {	if (acbp->aio_buf == NULL) {	    acbp->aio_buf = myalloc (data_size, align_offset);	    if (rotate_flag) {		aiobufs[index] = (u_char *) acbp->aio_buf;	    }	}	acbp->aio_fildes = AIO_NotQed;	acbp->aio_offset = (off_t) 0;	acbp->aio_nbytes = block_size;	acbp->aio_reqprio = AIO_PRIO_DFL;	/* Set default priority. */#if defined(SCO) || defined(HP_UX)	/*	 * Note: The AIO manual recommends setting AIO_RAW, but when	 *       this is set, EINVAL is returned by aio_read/aio_write!	 */#  if defined(SCO)	acbp->aio_flags = 0;			/* Must be zero to work! */#  endif /* defined(SCO) */	acbp->aio_sigevent.sigev_notify = SIGEV_NONE;#if 0	acbp->aio_flags = 0; /*AIO_RAW;*/	/* Required on SVR4.2(?) */	/*	 * This signaling method did not exist with the first release	 * of POSIX AIO.  Perhaps I'll add this completion method in	 * a future release.  Note: Tru64 Unix now supports this too!	 */	acbp->aio_sigevent.sigev_signo = /* use with SIGEV_SIGNAL */;	acbp->aio_sigevent.sigev_notify = SIGEV_CALLBACK;	acbp->aio_sigevent.sigev_func = my_aio_completion_function;	acbp->aio_sigevent.sigev_value = acbp;#endif#endif /* defined(SCO) || defined(HP_UX) */	/*	 * Use first buffer allocated for initial skip reads, etc.	 */	if (index == 0) data_buffer = (u_char *) acbp->aio_buf;    }    return (status);}#if 0static voiddtaio_checkdevice (struct dinfo *dip){    struct stat sb;    /*     * Asynchronous I/O is for character devices *only*.     *    [ Is this true for all operating systems? ]     */    if (fstat (dip->di_fd, &sb) == FAILURE) {	report_error("fstat", FALSE);	exit (FATAL_ERROR);    }    if (!S_ISCHR(sb.st_mode) ) {	LogMsg (efp, logLevelCrit, 0,		"'%s' is NOT a character device, cannot use asynchronous I/O.\n",								dip->di_dname);	exit (FATAL_ERROR);    }    return;}#endif /* 0 *//* * Cancel outstanding I/O on the specified file descriptor. */intdtaio_cancel (struct dinfo *dip){    int status;    /*     * This is not a very useful operation on DEC OSF/1 at this time,     * since the drivers do *not* contain a cancel entry point.     * So... you cannot actually cancel outstanding I/O requests.     */    if ((status = aio_cancel (dip->di_fd, NULL)) == FAILURE) {	/*	 * aio_cancel() returns EBADF if we never issued any AIO!	 */	if (errno != EBADF) {	    report_error ("aio_cancel", TRUE);	}	return (status);    }    if (debug_flag) {	switch (status) {	    case AIO_ALLDONE:		Printf ("All requests completed before cancel...\n");		break;	    case AIO_CANCELED:		Printf ("Outstanding requests were canceled...\n");		break;	    case AIO_NOTCANCELED:		Fprintf ("Outstanding (active?) request NOT canceled...\n");		break;	    default:		Fprintf ("Unexpected status of %d from aio_cancel()...\n", status);		break;	}    }    return (status);}intdtaio_cancel_reads (struct dinfo *dip){    int status;    struct dtype *dtp = dip->di_dtype;    aio_data_adjust = aio_file_adjust = aio_record_adjust = 0L;    (void) dtaio_cancel (dip);    status = dtaio_waitall (dip, TRUE);    if (aio_file_adjust && (dtp->dt_dtype == DT_TAPE) ) {	daddr_t count = (daddr_t)aio_file_adjust;	/*	 * Tapes are tricky... we must backup prior to the	 * last file(s) we processed, then forward space over	 * its' file mark to be properly positioned (yuck!!!).	 */	if (end_of_file) count++;	status = DoBackwardSpaceFile (dip, count);	if (status == SUCCESS) {	    status = DoForwardSpaceFile (dip, (daddr_t) 1);	}    } else if (aio_record_adjust && (dtp->dt_dtype == DT_TAPE) ) {	/*	 * If we've read partially into the next file, backup.	 */	status = DoBackwardSpaceFile (dip, (daddr_t) 1);	if (status == SUCCESS) {	    status = DoForwardSpaceFile (dip, (daddr_t) 1);	}    }    return (status);

⌨️ 快捷键说明

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