📄 dt.c
字号:
vu_long partial_records; /* # of partial records proc'ed */large_t data_limit; /* Total data limit per pass. */u_long random_align = 0UL; /* Random I/O offset alignment. */large_t rdata_limit = 0; /* The random I/O data limit. */large_t total_bytes; /* Total bytes transferred. */large_t total_bytes_read; /* Total bytes read. */large_t total_bytes_written; /* Total bytes written. */vu_long total_errors; /* Total errors (all passes). */large_t total_files; /* Total files (all passes). */large_t total_files_read; /* Total files read. */large_t total_files_written; /* Total files written. */large_t total_records; /* Total records (all passes). */u_long total_partial; /* Total partial records. */u_long warning_errors; /* Total non-fatal error count. */bool pstats_flag = TRUE; /* Display per pass statistics. */bool raw_flag = FALSE; /* The read after write flag. */bool rotate_flag = FALSE; /* Force data buffer rotating. */int rotate_offset = 0; /* Current rotate buffer offset */bool stats_flag = TRUE; /* Display total statistics. */bool stdin_flag = FALSE; /* Presume not reading stdin. */bool stdout_flag = FALSE; /* Presume not writing stdout. */bool terminating_flag = FALSE; /* Program terminating flag. */bool ttyport_flag = FALSE; /* Input/output is a terminal. */bool verbose_flag = TRUE; /* Verbose messages output. */bool verify_flag = TRUE; /* Verify the read/write data. */bool verify_only = FALSE; /* Verify of copied data flag. */char *cmd_line; /* Copy of our command line. */char *log_file; /* Pointer to log file name. */char *log_buffer; /* Pointer to log file buffer. */char *log_bufptr; /* Pointer into log buffer. */char *msg_buffer; /* Diagnostic message buffer. */char *input_file; /* Pointer to input file name. */char *output_file; /* Pointer to output file name. */char *pattern_file; /* Pointer to pattern file name */u_char *pattern_buffer; /* Pointer to pattern buffer. */u_char *pattern_bufptr; /* Pointer into pattern buffer. */u_char *pattern_bufend; /* Pointer to end of pat buffer */u_char *base_buffer; /* Base address of data buffer. */u_char *data_buffer; /* Pointer to data buffer. */u_char *mmap_buffer; /* Pointer to mmapped buffer. */u_char *mmap_bufptr; /* Pointer into mmapped buffer. */u_char *verify_buffer; /* The data verification buffer.*/size_t patbuf_size; /* The pattern buffer size. */int pattern_size; /* User specified pattern size. */int prefix_size; /* User defined prefix size. */int page_size = 0; /* Define number of bytes/page. */u_int cdelay_count = 0; /* Delay before closing file. */u_int edelay_count = 0; /* Delay between multiple passes*/u_int rdelay_count = 0; /* Delay before reading record. */u_int sdelay_count = 0; /* Delay before starting test. */u_int tdelay_count = 1; /* Child terminate delay count. */u_int wdelay_count = 0; /* Delay before writing record. */u_int random_seed = 0; /* Seed for random # generator. */bool user_rseed = FALSE; /* Flags user specified rseed. */bool max_capacity = FALSE; /* Use max capacity from IOCTL. */large_t user_capacity; /* The user set drive capacity. */bool variable_flag = FALSE; /* Variable block size flag. */bool volumes_flag = FALSE; /* Flags the volumes option. */int volume_limit = 0; /* Number of volumes to process.*/vu_long volume_records = 1; /* The last volume record limit.*/#if defined(TTY)enum opt softcar_opt = OPT_NONE; /* Leave tty soft carrier alone.*/enum flow flow_type = XON_XOFF; /* Terminal flow type to use. */#endif /* defined(TTY) */enum iodir io_dir = FORWARD; /* Default is forward I/O. */enum iomode io_mode = TEST_MODE; /* Default to testing mode. */enum iotype io_type = SEQUENTIAL_IO; /* Default to sequential I/O. */enum dispose dispose_mode = DELETE_FILE; /* Output file dispose mode. */enum onerrors oncerr_action = CONTINUE; /* The child error action. */ /* Error limit controls tests. */#if defined(SOLARIS) || defined(OSFMK) || defined(__QNXNTO__) || defined(AIX)clock_t hz;#elseclock_t hz = HZ; /* Default clock ticks / second */#endif#if defined(TTY)/* * Values for Terminal (serial) Line Testing: */u_short tty_timeout = 3*10; /* Default tty timeout (3 sec). */ /* VTIME = 0.10 second interval */bool tty_minflag = FALSE; /* User specified VMIN value. */u_short tty_minimum = 0; /* The tty minimum (VMIN) value */#endif /* defined(TTY) */FILE *efp; /* Default error data stream. */FILE *ofp; /* Default output data stream. */int pfd = NoFd; /* Pattern file descriptor. */char *cmdname; /* Pointer to our program name. */char *string; /* Pointer to argument string. *//* * Pointers to various device information. */struct dinfo *active_dinfo; /* Active device information. */struct dinfo *input_dinfo; /* Input device information. */struct dinfo *output_dinfo; /* Output device information. */struct dtype *input_dtype; /* The input device type info. */struct dtype *output_dtype; /* The output device type info. *//* * System time information. */clock_t start_time, end_time, pass_time; /* Per pass elapsed time. */struct tms stimes, ptimes, etimes; /* For user / system times. */#if defined(DEC)bool table_flag = FALSE; /* Table control flag. */struct tbl_sysinfo s_table, p_table, e_table; /* Table information. */#endif /* defined(DEC) */#if defined(_BSD)union wait child_status; /* For child exit status. */#else /* !defined(_BSD) */int child_status; /* For child exit status. */#endif /* defined(_BSD) *//* * Program run time information. */time_t runtime; /* The program run time. */time_t elapsed_time; /* Amount of time program ran. */time_t program_start, program_end; /* Program start & end times, */time_t error_time; /* Time last error occurred. */bool TimerActive; /* Set after timer activated. */bool TimerExpired; /* Set after timer has expired. */char *user_runtime; /* User specific runtime string *//* * Data patterns used for multiple passes. */u_int32 data_patterns[] = { DEFAULT_PATTERN, 0x00ff00ffU, 0x0f0f0f0fU, 0xc6dec6deU, 0x6db6db6dU, 0x55555555U, 0xaaaaaaaaU, /* Complement of previous data pattern. */ 0x33333333U, /* Continuous worst case pattern (media defects) */ 0x26673333U, /* Frequency burst worst case pattern #1. */ 0x66673326U, /* Frequency burst worst case pattern #2. */ 0x71c7c71cU, /* Dibit worst case data pattern. */ 0x00000000U, 0xffffffffU,};int npatterns = sizeof(data_patterns) / sizeof(u_int32);/* * main() - Start of data transfer program. */intmain (int argc, char **argv){ struct dinfo *dip; struct dtfuncs *dtf; char *tmp; int status; efp = stderr; /* Initialize our error stream. */ ofp = stdout; /* Initialize our output stream.*/#if defined(_BSD) tmp = rindex (argv[0], '/');#else /* !defined(_BSD) */ tmp = strrchr (argv[0], '/');#endif /* defined(_BSD) */ cmdname = tmp ? &(tmp[1]) : argv[0];#if defined(_QNX_SOURCE) && !defined(_QNX_32BIT) page_size = 0; /* Presume page size doesn't matter. */#elif defined(_QNX_SOURCE) && defined(_QNX_32BIT) page_size = 4096; /* Not sure how to query for this... */#elif defined(DEC) || defined(SOLARIS) || defined(__linux__) || defined(SCO) || defined(__NUTC__) || defined(HP_UX) || defined(AIX) hz = sysconf(_SC_CLK_TCK); page_size = sysconf(_SC_PAGESIZE);#else /* !defined(_QNX_SOURCE) && !defined(_QNX_32BIT) */ page_size = getpagesize();#endif /* defined(_QNX_SOURCE) && !defined(_QNX_32BIT) */#if defined(OSFMK) || defined(__QNXNTO__) hz = CLK_TCK; /* Actually a libc function. */#endif /* defined(OSFMK) || defined(__QNX_NTO__) */#if defined(LOG_DIAG_INFO) /* * Allow DT_LOG_DIAG to enable logging diagnostic information. */ if (tmp = getenv ("DT_LOG_DIAG")) { logdiag_flag = TRUE; }#endif /* defined(LOG_DIAG_INFO) */ data_limit = INFINITY; /* Set to maximum limit. */ parse_args (argc, argv); /* * Options parsed, validate options, do initialization, and open * input & output files to be tested. */ program_start = time((time_t) 0); /* Record our start time. */ /* * If a log file was specified, redirect stderr to that file. */ if (log_file) { ofp = efp; /* Send all output to stderr. */ if (freopen (log_file, "a", efp) == NULL) { report_error (log_file, TRUE); exit (exit_status); } } /* * Make stderr buffered, so timing is not affected by output. */ if ((log_buffer = (char *) malloc (LOG_BUFSIZE)) == NULL) { LogMsg (efp, logLevelCrit, 0, "Unable to allocate log file buffer of %d bytes, exiting...\n", LOG_BUFSIZE); exit (ENOMEM); } /* * The concept here is simple, set stderr buffered so multiple processes * don't have their output intermixed. This piece of code has been very * problematic, so it you have problems with garbled output, remove it. */ log_bufptr = log_buffer; /* * Since stderr is normally unbuffered, we make it buffered here. */ if ( isatty(fileno(efp)) ) { char *stderr_buffer = (char *)malloc(LOG_BUFSIZE); if (stderr_buffer == NULL) { LogMsg (efp, logLevelCrit, 0, "Unable to allocate stderr buffer of %d bytes, exiting...\n", LOG_BUFSIZE); exit (ENOMEM); } /* * Can't use log buffer, or we get undesirable results :-) */ if (setvbuf(efp, stderr_buffer, _IOFBF, LOG_BUFSIZE) < 0) { report_error ("setvbuf", TRUE); exit (exit_status); } } /* * Write the command line to the log file, if one exists. */ if (log_file && header_flag) { int arg; /* * Write the command line for future reference. */ Lprintf("Command Line:\n\n %c ", getuid() ? '%' : '#'); for (arg = 0; arg < argc; arg++) { Lprintf("%s ", argv[arg]); } Lprintf("\n\n\t--> %s <--\n", version_str); Lflush(); } if (!input_file && !output_file) { LogMsg (efp, logLevelCrit, 0, "You must specify an input file, an output file, or both.\n"); exit (FATAL_ERROR); } /* * Disallow both seek type options, to simplify test loops. */ if ( (io_dir == REVERSE) && (io_type == RANDOM_IO) ) { LogMsg (efp, logLevelCrit, 0, "Please specify one of iodir=reverse or iotype=random, not both!\n"); exit (FATAL_ERROR); } if (slice_num) { if (!num_slices) { LogMsg (efp, logLevelCrit, 0, "Please specify number of slices with slice option!\n"); exit (FATAL_ERROR); } else if (slice_num > num_slices) { LogMsg (efp, logLevelCrit, 0, "Please specify slice (%d) <= max slices (%d)\n", slice_num, num_slices); exit (FATAL_ERROR); } }#if defined(MUNSA) if (munsa_flag) { if (input_file && !output_file) { input_munsa_lock_type = munsa_lock_type; if (debug_flag) { Printf ("input_munsa_lock_type = %d\n", input_munsa_lock_type); } } if (output_file && !input_file) { if ((munsa_lock_type == DLM_PWMODE) || (munsa_lock_type == DLM_EXMODE)) { output_munsa_lock_type = munsa_lock_type; if (debug_flag) { Printf ("output_munsa_lock_type = %d\n", output_munsa_lock_type); } } else { LogMsg (efp, logLevelCrit, 0, "invalid write lock type it should be pw,ex\n"); exit(FATAL_ERROR); } } if (input_file && output_file) { input_munsa_lock_type = DLM_PRMODE; output_munsa_lock_type = DLM_PWMODE; if (debug_flag) { Printf ("input_munsa_lock_type = %d\n", input_munsa_lock_type); Printf ("output_munsa_lock_type = %d\n", output_munsa_lock_type); } } } /* end if(munsa_flag) .... */#endif /* defined(MUNSA) */ if ( (!input_file || !output_file) && ((io_mode == COPY_MODE) || (io_mode == VERIFY_MODE)) ) { LogMsg (efp, logLevelCrit, 0, "Copy/verify modes require both input and output devices.\n"); exit (FATAL_ERROR); } /* * When reading multiple tape files, don't require data or record * limits (these will vary). But when writing multiple tape files, * we need to know how many records or bytes to be written. */ if (input_file && !output_file && file_limit && !record_limit) { record_limit = INFINITY; } /* * Check the variable record size parameters. */ if (min_size && !max_size) max_size = block_size; if (block_size < max_size) block_size = max_size; /* NOTE: Other checks are done below now... */ /* * Calculate the data limit if it wasn't specified by the user. */ if ( (data_limit == INFINITY) && ( (record_limit != 0L) && (record_limit != INFINITY) ) ) { data_limit = (block_size * record_limit); } /* * Process the pattern file (if one was specified). */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -