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

📄 dt.c

📁 Linux磁盘测试的源代码,测试磁盘的读写性能
💻 C
📖 第 1 页 / 共 5 页
字号:
		    "Please specify a record or data limit for random I/O.\n");	    exit (FATAL_ERROR);	}	/*	 * Sanity check the random I/O data limits.	 */	if ( (io_type == RANDOM_IO) &&	     ((file_position + block_size + random_align) > rdata_limit)) {	    LogMsg (efp, logLevelCrit, 0,		    "The max block size is too large for random data limits!\n");	    if (Debug_flag) {	        Printf ("file position " FUF ", bs=%ld, ralign=%ld, rlimit=" LUF "\n",			file_position, block_size, random_align, rdata_limit);	    }	    exit (FATAL_ERROR);	}	/*	 * Ensure either a data limit and/or a record count was specified.	 */	if (!record_limit) {	    LogMsg (efp, logLevelCrit, 0,		    "You must specify a data limit, a record count, or both.\n");	    exit (FATAL_ERROR);	}	/*	 * Allocate buffer for pre-formatting messages.	 */	msg_buffer = (char *)Malloc(LOG_BUFSIZE);#if defined(LOG_DIAG_INFO)	/*	 * If logging of diagnostic info is enabled, save copy of cmd line.	 */	if (logdiag_flag) {	    int arg;	    char *bp;	    bp = cmd_line = (char *)Malloc(LOG_BUFSIZE);	    for (arg = 0; arg < argc; arg++) {		(void)sprintf(bp, "%s ", argv[arg]);		bp += strlen(bp);	    }	    sprintf(bp, "\n");	}#endif /* defined(LOG_DIAG_INFO) */	/*	 * Catch a couple signals to do elegant cleanup.	 */	(void) signal (SIGHUP, terminate);	(void) signal (SIGINT, terminate);	(void) signal (SIGTERM, terminate);	(void) signal (SIGPIPE, terminate);	/*	 * If both an input and an output files were specified, then	 * fork and make child process the reader, parent the writer.	 */	if ( (io_mode == TEST_MODE) && input_file && output_file) {	    if ( (child_pid = fork()) == (pid_t) -1) {		report_error ("fork", TRUE);		exit (exit_status);	    }	    forked_flag = TRUE;	    if (child_pid) {			/* Parent = writer. */		struct dinfo *dip = input_dinfo;		(void) close_file (dip);		input_file = NULL;		if (debug_flag) {		    Printf ("Parent PID (Writer) = %d, Child PID (Reader) = %d\n",						getpid(), child_pid);		}#if !defined(__MSDOS__) || defined(__NUTC__)		signal (SIGCHLD, terminate);#endif	    } else {				/* Child = reader. */		struct dinfo *dip = output_dinfo;		(void) close_file (dip);		output_file = NULL;	    }	}	/*	 * Some drivers require the input device to open before we start	 * writing.  For example, terminal devices must have speed, parity,	 * and flow control setup before we start writing.  The parallel	 * input device must open before we send the "readya" interrupt.	 */	if (output_file && (sdelay_count != 0)) {	    mySleep (sdelay_count);		/* Allow reader to start. */	}	/*	 * Calculate size necessary for the data buffer & the pad bytes.	 */	data_size = (block_size + PADBUFR_SIZE);	if (rotate_flag) data_size += ROTATE_SIZE;	/*	 * For read-after-write (raw) option, we need a verification buffer.	 * Note:  Other tests can benefit from this too, switch to later.	 */	if (raw_flag) {	    verify_buffer = myalloc(data_size, align_offset);	}	/*	 * Do the device / test specific initialization.	 *	 * This function is responsible for allocating the necessary	 * data buffers and performing special device setup/checking.	 */	if (input_file) {	    dip = input_dinfo;	    status = (*dip->di_funcs->tf_initialize)(dip);	    if (status == FAILURE) exit (FATAL_ERROR);	}	if (output_file) {	    dip = output_dinfo;	    status = (*dip->di_funcs->tf_initialize)(dip);	    if (status == FAILURE) exit (FATAL_ERROR);	}	/*	 * Re-adjust size of data buffer to avoid init'ing too much.	 */	if (rotate_flag) data_size -= ROTATE_SIZE;	/*	 * Finally format the prefix string (if any), after the device is	 * setup and processes are forked so we can setup a unique prefix.	 */	if (prefix_string) {	    status = FmtPrefix(dip, &prefix_string, &prefix_size);	    if (status == FAILURE) exit (FATAL_ERROR);            if ((prefix_size) > lbdata_size) {                LogMsg (efp, logLevelCrit, 0,                        "The prefix size (%d) is larger than lbdata size (%d)!\n",                        prefix_size, lbdata_size);                exit (FATAL_ERROR);            }	}	/*	 * Start an alarm timer if the run time was specified.	 */	if (runtime) {	    (void) signal (SIGALRM, terminate);	    (void) alarm (runtime);	    TimerActive = TRUE;	}	/*	 * Start of main test loop.	 */	start_time = times (&stimes);#if defined(LOG_DIAG_INFO)	if (logdiag_flag) {	    sprintf(msg_buffer, "Starting: %s", cmd_line);	    LogDiagMsg(msg_buffer);	}#endif /* defined(LOG_DIAG_INFO) */#if defined(DEC)	if (table_flag) {	    status = table(TBL_SYSINFO,0,(char *)&s_table,1,sizeof(struct tbl_sysinfo));	    if (status == FAILURE) report_error ("table", FALSE);	}#endif /* defined(DEC) */    /*     * We support multiple modes of operation: copy, test, & verify     */    if ( (io_mode == COPY_MODE) || (io_mode == VERIFY_MODE) ) {	/*	 * This is ugly, but I'm using pattern buffer as verify buffer.	 */	if ( (io_mode == VERIFY_MODE) || verify_flag) {	    pattern_buffer = myalloc (data_size, align_offset);	    setup_pattern (pattern_buffer, data_size);	}	pass_time = times (&ptimes);	/* Start the pass timer	*/#if defined(DEC)	if (table_flag) {	    status = table(TBL_SYSINFO,0,(char *)&p_table,1,sizeof(struct tbl_sysinfo));	    if (status == FAILURE) report_error ("table", FALSE);	}#endif /* defined(DEC) */	dip = active_dinfo = input_dinfo;	dtf = dip->di_funcs;	dip->di_mode = READ_MODE;	(void) (*dtf->tf_start_test)(dip);	(void) (*dtf->tf_read_file)(dip);	(void) (*dtf->tf_end_test)(dip);	gather_stats(output_dinfo);	/*	 * Now verify the data copied (if requested).	 */	if ( (io_mode == COPY_MODE) && verify_flag &&	     !stdin_flag && (error_count < error_limit) ) {	    struct dinfo *odip = output_dinfo;	    int open_mode = (ropen_mode | open_flags);	    report_pass (dip, COPY_STATS);	/* Report copy statistics. */	    /*	     * Verify Pass.	     */	    status = (*dtf->tf_reopen_file)(dip, open_mode);	    if (status != SUCCESS) terminate(status);	    odip->di_mode = READ_MODE;	/* Switch to read mode. */	    status = (*odip->di_funcs->tf_reopen_file)(odip, open_mode);	    if (status != SUCCESS) terminate(status);	    pass_time = times (&ptimes); /* Time the verify. */#if defined(DEC)	    if (table_flag) {		status = table(TBL_SYSINFO,0,(char *)&p_table,1,sizeof(struct tbl_sysinfo));		if (status == FAILURE) report_error ("table", FALSE);	    }#endif /* defined(DEC) */	    io_mode = VERIFY_MODE;	    (void) (*dtf->tf_start_test)(dip);	    (void) (*dtf->tf_read_file)(dip);	    (void) (*dtf->tf_end_test)(dip);	    pass_count++;			/* End of copy/verify pass. */	    gather_stats(output_dinfo);		/* Gather device statistics. */	    report_pass (dip, VERIFY_STATS);	/* Report the verify stats. */	} else {	    pass_count++;			/* End of copy pass. */	}    } else { /* not Copy or Verify modes, Test Mode! */	while ( (total_errors < error_limit) &&		((pass_count < pass_limit) || runtime) ) {	    if (pattern_buffer) {		pattern_bufptr = pattern_buffer;	    }	    /*	     * Use a different data pattern for each pass.	     */	    if ( !user_pattern && !ttyport_flag &&		 (loopback || output_file || stdin_flag ||		  (input_file && num_slices)) ) {		/*		 * Logic:		 * - If multiple slices, choose a different pattern		 *   for each pass, factoring in the process number.		 * - Else, each pass gets a different data pattern		 *   unless multiple processes were selected.		 */		if ( unique_pattern &&		     ( (!num_procs && num_slices) ||		       (num_procs && (dip->di_dtype->dt_dtype == DT_REGULAR)) ) ) {		    int pindex = ((cur_proc - 1) + pass_count);		    pattern = data_patterns[pindex % npatterns];		} else if (!num_procs) {		    pattern = data_patterns[pass_count % npatterns];		}		if (pattern_buffer) copy_pattern (pattern, pattern_buffer);		if (debug_flag) {		    Printf ("Using data pattern 0x%08x for pass %u\n",						pattern, (pass_count + 1));		}	    }	    /*	     * Use time for random # generator seed so different areas	     * of disk get affected during multiple passes.  Seed set	     * here, since it must be the same seed during read pass.	     * NOTE: Pid is added so seed different for each process.	     */	    if ( (io_type == RANDOM_IO) || variable_flag) {		if ( !user_rseed ) {		    random_seed = (u_int) times(&ptimes) + getpid();		}		set_rseed (random_seed);	    }	    pass_time = times (&ptimes);	/* Start the pass timer	*/#if defined(DEC)	    if (table_flag) {		status = table(TBL_SYSINFO,0,(char *)&p_table,1,sizeof(struct tbl_sysinfo));		if (status == FAILURE) report_error ("table", FALSE);	    }#endif /* defined(DEC) */	    if (output_file) {			/* Write/read the file.	*/		bool do_read_pass;		dip = active_dinfo = output_dinfo;		dtf = dip->di_funcs;		dip->di_mode = WRITE_MODE;		(void) (*dtf->tf_start_test)(dip);		(void) (*dtf->tf_write_file)(dip);		(void) (*dtf->tf_flush_data)(dip);		(void) (*dtf->tf_end_test)(dip);		if (error_count >= error_limit) break;		do_read_pass = (dip->di_dbytes_written != (large_t) 0);		/*		 * Now verify (read and data compare) the data just written.		 */		if (verify_flag && do_read_pass && !raw_flag) { /* Verify data written. */		    int open_mode = (ropen_mode | open_flags);		    report_pass (dip, WRITE_STATS);	/* Report write stats.	*/		    if (multi_flag && media_changed) {			status = RequestFirstVolume(dip, open_flags);		    } else {			status = (*dtf->tf_reopen_file)(dip, open_mode);		    }		    if (status != SUCCESS) break;		    if ( (io_type == RANDOM_IO) || variable_flag) {			set_rseed (random_seed);		    }		    pass_time = times (&ptimes);	/* Time just the read.	*/#if defined(DEC)		    if (table_flag) {			status = table(TBL_SYSINFO,0,(char *)&p_table,1,sizeof(struct tbl_sysinfo));			if (status == FAILURE) report_error ("table", FALSE);		    }#endif /* defined(DEC) */		    /*rotate_offset = 0;*/		    if (pattern_buffer) {			pattern_bufptr = pattern_buffer;		    }		    dip->di_mode = READ_MODE;		    (void) (*dtf->tf_start_test)(dip);		    (void) (*dtf->tf_read_file)(dip);		    (void) (*dtf->tf_end_test)(dip);		    pass_count++;			/* End read/write pass. */		    report_pass (dip, READ_STATS);	/* Report read stats.	*/		} else {		    pass_count++;		/* End of write pass.	*/		    if ( (pass_limit > 1) || runtime) {			/* Report write stats. */			if (raw_flag) {			    report_pass (dip, RAW_STATS);			} else {			    report_pass (dip, WRITE_STATS);			}		    }		}		if ( (pass_count < pass_limit) || runtime) {		    int open_mode;		    if (skip_count || raw_flag) {			open_mode = (O_RDWR | wopen_flags | open_flags);		    } else {			open_mode = (wopen_mode | wopen_flags | open_flags);		    }		    status = (*dtf->tf_reopen_file)(dip, open_mode);		    if (status != SUCCESS) break;		}	    } else { /* Reading only. */		dip = active_dinfo = input_dinfo;		dtf = dip->di_funcs;		dip->di_mode = READ_MODE;		(void) (*dtf->tf_start_test)(dip);		(void) (*dtf->tf_read_file)(dip);		(void) (*dtf->tf_end_test)(dip);		pass_count++;			/* End of read pass.	*/		/*		 * Prevent pass unless looping, since terminate reports		 * the total statistics when called (prevents dup stats).		 */		if ( (pass_limit > 1) || runtime) {		    report_pass (dip, READ_STATS);	/* Report read stats.	*/		}		if ( (total_errors < err

⌨️ 快捷键说明

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