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

📄 dteei.c

📁 Linux磁盘测试的源代码,测试磁盘的读写性能
💻 C
📖 第 1 页 / 共 5 页
字号:
#if defined(EEI)/**************************************************************************** *									    * *			  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:	dteei.c * Author:	Robin T. Miller * Date:	September 13, 1997 * * Description: *	This file contains functions for support of DEC EEI interface. * * Modification History: * * 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. * * April 21st, 2000 by Robin Miller. *	Converted tabs to spaces in all messages, so formatting is not * screwed up when messages are prefixed by a timestamp or process ID. * * April 10th, 2000 by Robin Miller. *	For Wave4, added logic to handle EEI_DEVPATH_FAILURE, so we try * to re-open the tape device to 1) find another path (multi-pathing) or * 2) force DRD failover (find another server for the tape). * * February 19th, 2000 by Robin Miller. *	While processing a reset condition, if another operation errors * with no EEI status (EEI_NO_STATUS), then retry that operation.  This * may be a driver related problem, but we wish to recover from this. * If not compiled for Tru64 clusters, retry target selection timeouts. * * February 14th, 2000 by Robin Miller. *	Merge Mike Gilmore's changes: *	- change the data format from DEVIOCGET to DEVGETINFO. * * March 25, 1999 by Robin Miller. *	Fix problem with my fileno going negative (bad check). * * February 25, 1999 by Robin Miller. *	Add support for multiple reset conditions. * * December 21, 1998 by Robin Miller. *	Add HandleTapeResets() to reposition the tape after resets. * * March 11, 1998 by George Bittner. *	Remove unnecessary include files for building in steelos. * */#include "dt.h"#include <sys/fcntl.h>#include <sys/ioctl.h>#include <sys/ioctl_compat.h>#include <sys/mtio.h>#include <io/common/iotypes.h>#include <io/common/devio.h>#include <io/common/devgetinfo.h>#include <io/cam/cam.h>#include <io/cam/scsi_all.h>#include <io/cam/scsi_status.h>#if !defined(STEELOS)#  include <io/common/kds.h>#  include <io/cam/camdb.h>#  include <io/cam/cam_tape.h>#endif /* !defined(STEELOS) *//* * These three defines are, unfortunately, not defined in the CAM code * because they are always used only as bit fields in the entire sense * data structure.  All we have available is the sense key itself. */#define	ILI		0x20#define	EOM		0x40#define	FILE_MARK	0x80#define DNL		0			/* Disable newline.	*/#define PNL		1			/* Print newline.	*//* * Declare CAM Debugging Definitions: */#define CDBG_BRIEF	0		/* Brief message text. */#define CDBG_FULL	1		/* Full message text. *//* * Additional Sense Code Table Entry Format: */struct sense_entry {	u_char	sense_code;		/* Additional sense code.	*/	u_char	sense_qualifier;	/* Sense code qualifier.	*/	char	*sense_message;		/* Error message text.		*/};static char *not_valid_str	= "<Not Valid>";long	mt_blkno;			/* Starting tape block number.	*/long	mt_fileno;			/* Starting tape file number.	*//* * Forward References: */bool is_ResetCondition(struct dinfo *dip, DEV_EEI_STATUS *eei);bool is_StatusRetryable(struct dinfo *dip, DEV_EEI_STATUS *eei);void print_eei(DEV_EEI_STATUS *eei);void print_devio(int fd);void print_erreg(short erreg);void print_stat(long stat);void print_category(long stat, device_info_t *devinfop);void PrintNumeric(char *field_str, u_long numeric_value, int nl_flag);void PrintDecimal(char *field_str, u_long numeric_value, int nl_flag);void PrintHex(char *field_str, u_long numeric_value, int nl_flag);void PrintAscii(char *field_str, char *ascii_str, int nl_flag);void PrintFields(u_char *bptr, int length);char *cdbg_SenseKeyTable[];char *cdbg_CamStatus(u_char cam_status, int report_format);char *cdbg_ScsiStatus(u_char scsi_status, int report_format);char *cdbg_SenseMessage(struct all_req_sns_data *sdp);char *cdbg_EEIStatus(u_int eei_status, int report_format);/* * HandleTapeResets() - Handle Tape Reset Conditions. * * Description: * 	This function is called to do reset processing for tape devices. * The idea is to reposition the tape to the file/record position prior * to the reset, then retry the operation. * * Inputs:	dip = The device information pointer. * * Return Value: *		TRUE/FALSE = Retry Operation/Error the Request. * */boolHandleTapeResets(struct dinfo *dip){	int status;	int fd = dip->di_fd;	struct mtget mtget, *mt;	int saved_errno;	u_long fileno, files, records;	if (dip->di_proc_eei) {	    mt = &mtget;	    memset(mt, '\0', sizeof(*mt));	} else {	    mt = dip->di_mt;	}	saved_errno = errno;	status = get_eei_status(fd, mt);	if (status != ESUCCESS) {	    errno = saved_errno;	    return (FALSE);	}	if (dip->di_mode == READ_MODE) {	    files = dip->di_files_read;	    records = dip->di_records_read;	} else {	    files = dip->di_files_written;	    records = dip->di_records_written;	}	if (dip->di_proc_eei) {	    if (debug_flag) print_mtstatus(fd, mt, FALSE);	    /*	     * See if we should retry this EEI status.	     */	    if ( is_StatusRetryable(dip, &mt->eei) ) {		if (dip->di_eei_retries-- == 0) {		    dip->di_eei_retries = EEI_RETRIES;		    return (FALSE);		/* Exhausted retries. */		}		if (verbose_flag) {		    Printf("Retry %d after %s status...\n",			    (EEI_RETRIES - dip->di_eei_retries),			    cdbg_EEIStatus(mt->eei.status, CDBG_BRIEF));		}		(void)sleep(dip->di_eei_sleep);		return (TRUE);		/* Retry please! */	    } else if ( is_ResetCondition(dip, &mt->eei) ) {		return (FALSE);		/* Don't retry. */	    } else {		if (!debug_flag) print_mtstatus(fd, mt, TRUE);		return (FALSE);		/* Don't retry. */	    }	}	if ( is_StatusRetryable(dip, &mt->eei) ) {	    if (verbose_flag) {		Printf("Retrying after %s status...\n",				cdbg_EEIStatus(mt->eei.status, CDBG_BRIEF));	    }	    (void)sleep(dip->di_eei_sleep);	    return (TRUE);	} else if ( !is_ResetCondition(dip, &mt->eei) ) {	    print_mtstatus(fd, mt, TRUE);	    return (FALSE);	}	dip->di_proc_eei = TRUE;		/* For recursion. */	dip->di_eei_retries = EEI_RETRIES;	if (verbose_flag) {	    Printf("Processing reset condition (%s) - file %lu, record %lu\n",				cdbg_EEIStatus(mt->eei.status, CDBG_BRIEF),					mt->mt_fileno, mt->mt_blkno);	}	if (debug_flag) print_mtstatus(fd, mt, FALSE);	/*	 * When writing tape files, the last file mark gets written	 * when closing the tape, so adjust file count appropriately.	 */	fileno = files;	if ( (dip->di_mode == WRITE_MODE) &&	     (files == file_limit) ) {	    if (fileno) fileno--;	}	/*	 * Sanity check the block and file counts.	 */	if (mt->mt_fileno != (fileno + mt_fileno)) {	    /* NFG if the no-rewind device is used! */	    Fprintf(	"File count sanity check failed, mt_fileno = %ld, my count = %ld\n",			mt->mt_fileno, (fileno + mt_fileno));#if 0	    return (FALSE);#endif	    /* Adjust and continue below... */	    mt->mt_fileno = (fileno + mt_fileno);	}	/*	 * ??? mt_blkno doesn't always match my counts ???	 */	if ( mt->mt_blkno != (records + mt_blkno) ) {	    Fprintf(	"Record count sanity check failed, mt_blkno = %ld, my count = %ld\n",		mt->mt_blkno, (records + mt_blkno));#if 0	    return (FALSE);#endif	    /* Adjust and continue below... */	    mt->mt_blkno = (records + mt_blkno);	}reposition:	dip->di_reset_condition = FALSE;#if defined(STEELOS)    if (dip->di_devpath_failure) {	dip->di_devpath_failure = FALSE;	/* We terminate if we can't re-open the device. */	(void) (*dip->di_funcs->tf_reopen_file)(dip, dip->di_oflags);    } else {	/*	 * Rewind and reposition the tape.	 */	status = DoRewindTape(dip);	if (status) {	    if (dip->di_reset_condition) goto reposition;	    dip->di_proc_eei = FALSE;	    return (FALSE);	}	/*	 * Bring the tape online, driver calls ctape_online(), to force	 * auto-density selection to be done.  Otherwise, we may proceed	 * with the wrong tape density.	 */	status = DoTapeOnline(dip);	if (status) {	    if (dip->di_reset_condition) goto reposition;	    dip->di_proc_eei = FALSE;	    return (FALSE);	}    }#else /* !defined(STEELOS) */	/*	 * NOTE:  Re-open the tape (assumes we're using rewind device),	 * and reposition the tape.  The re-open of the tape is necessary	 * to clear state flags (CTAPE_UNIT_ATTEN_STATE & CTAPE_RESET_STATE)	 * in the CAM tape driver.  If this is NOT done, the close function	 * won't write file marks. [ Fixed in Steel, not earlier releases! ]	 */	(void) (*dip->di_funcs->tf_reopen_file)(dip, dip->di_oflags);	/*	 * NOTE: reopen of the tape also brings the tape online.	 */#endif /* !defined(STEELOS) */	/*	 * Finally, reposition to the correct file and block numbers.	 */	if (mt->mt_fileno) {	    long fileno = mt->mt_fileno;	    if (verbose_flag) {		Printf("Positioning to file %lu...\n", fileno);	    }	    status = DoForwardSpaceFile(dip, fileno);	    if (status) {		if (dip->di_reset_condition) goto reposition;		dip->di_proc_eei = FALSE;		return (FALSE);	    }	}	if (mt->mt_blkno) {	    long record = MIN(mt->mt_blkno, records);	    if (record) {		if (verbose_flag) {		    Printf("Positioning to record %lu...\n", record);		}		status = DoForwardSpaceRecord(dip, record);		if (status) {		    if (dip->di_reset_condition) goto reposition;		    dip->di_proc_eei = FALSE;		    return (FALSE);		}	    }	}	dip->di_proc_eei = FALSE;	/*	 * Don't need to clear EEI status here, since this function is	 * called recursively when tape movement IOCTL errors occur.	 */	return (TRUE);}boolis_ResetCondition(	struct dinfo	*dip,	DEV_EEI_STATUS	*eei ){    /*     * For Reference:     *     *    EEI_DEVPATH_RESET == ( CAM_SCSI_BUS_RESET || ASCQ_PON_RESET     *						    || ASCQ_POWER_ON     *						    || ASCQ_BUS_RESET     *						    || ASCQ_BDR_RESET     *						    || ASCQ_FIRMWARE_REBOOT )     *     *    EEI_CNTBUSY_FAILURE == CAM_BUSY     *     * A status of CAM_BUSY indicates the SIM/HBA is in recovery,     * and usually that recovery is the result of reset handling.     * So in the case of tapes, we reposition on CAM_BUSY too.     *     * NOTE: CAM_BDR_SENT belongs with EEI_DEVPATH_RESET :-)     */    if ( (eei->status == EEI_DEVPATH_RESET)		||	 (eei->status == EEI_CNTBUSY_FAILURE)		||	 (eei->status == EEI_TAPE_POS_LOST)		||	 (eei->arch.cam.cam_status == CAM_BDR_SENT)	) {	dip->di_reset_condition = TRUE;	(void) sleep (EEI_RESET);	return (TRUE);    } else if (eei->status == EEI_DEVSTATE_FAILURE) {	struct all_req_sns_data *sdp;	sdp = (struct all_req_sns_data *)&eei->arch.cam.scsi_sense;	if ( (eei->flags & EEI_SCSI_SENSE_VALID) &&	     (sdp->sns_key == ALL_UNIT_ATTEN) ) {	    dip->di_reset_condition = TRUE;	    return (TRUE);	/* Result of reset or power on. */	}

⌨️ 快捷键说明

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