📄 dtgen.c
字号:
file, dip->di_fd); }#if defined(EEI) if ( (status == SUCCESS) && eei_flag && (dip->di_dtype->dt_dtype == DT_TAPE) ) { clear_eei_status(dip->di_fd, FALSE); }#endif /* defined(EEI) */ return (status);}/************************************************************************ * * * initialize() - Do the default program initialization. * * * * Description: * * This function does the default (generic) test initialization. * * * * Inputs: dip = The device information pointer. * * * * Outputs: Always SUCCESS right now. * * * ************************************************************************/intinitialize (struct dinfo *dip){ if (!data_buffer) { base_buffer = data_buffer = myalloc (data_size, align_offset); } return (SUCCESS);}/************************************************************************ * * * init_file() - Initial file processing. * * * * Description: * * This function is used to process options before starting tests. * * * * Inputs: dip = The device information pointer. * * * * Outputs: Always SUCCESS right now. * * * ************************************************************************/intinit_file (struct dinfo *dip){ int status = SUCCESS; int fd = dip->di_fd; /* * If the lba option is specified, and we're a disk device, * then setup a file position to be seek'ed to below. */ if ( lbdata_addr && !user_position && ((dip->di_dtype->dt_dtype == DT_DISK) || (dip->di_dtype->dt_dtype == DT_BLOCK)) ) { file_position = make_position(dip, lbdata_addr); if ( (io_type == RANDOM_IO) && (rdata_limit <= file_position) ) { LogMsg (efp, logLevelCrit, 0, "Please specify a random data limit > lba file position!\n"); exit (FATAL_ERROR); } } /* * Seek to specified offset (if requested). */ if (file_position) { last_position = set_position (dip, file_position); } /* * Seek to specified record (if requested). */ if (seek_count) {#if defined(_BSD) last_position = seek_file (fd, seek_count, block_size, L_INCR);#else /* !defined(_BSD) */ last_position = seek_file (fd, seek_count, block_size, SEEK_CUR);#endif /* defined(_BSD) */ if (last_position == (off_t) FAILURE) return (FAILURE); show_position (dip, last_position); } /* * Skip over input record(s) (if requested). */ if (skip_count) { status = skip_records (dip, skip_count, data_buffer, block_size); if (debug_flag && (status != FAILURE)) { Printf ("Successfully skipped %d records.\n", skip_count); } } return (status);}/************************************************************************ * * * flush_file() - Flush file data to disk. * * * * Description: * * This function is used to flush the file data to disk after the * * write pass of each test. * * * * Inputs: dip = The device information pointer. * * * * Return Value: * * Returns SUCCESS / FAILURE = Ok / Sync Failed. * * * ************************************************************************/intflush_file (struct dinfo *dip){ int status = SUCCESS; int fd = dip->di_fd; /* * Ensure data is sync'ed to disk file. */ if ( fsync_flag ) { if (debug_flag) { Printf ("Flushing data to file '%s'...\n", dip->di_dname); }#if defined(_QNX_SOURCE) if ((status = fcntl (fd, F_SETFL, O_DSYNC)) < 0) { report_error("F_SETFL", TRUE); }#else /* !defined(_QNX_SOURCE) */ if ((status = fsync (fd)) < 0) { /* Force data to disk. */ report_error ("fsync", TRUE); }#endif /* !defined(_QNX_SOURCE) */ } return (status);}/************************************************************************ * * * read_file - Read and optionally verify data in the test file. * * * * Inputs: dip = The device information pointer. * * * * Return Value: * * Returns SUCCESS/FAILURE = Ok / Error. * * * ************************************************************************/intread_file (struct dinfo *dip){ int status; struct dtfuncs *dtf = dip->di_funcs;#if defined(MUNSA) if (munsa_flag) { if (debug_flag) { Printf ("converting to dlm NL-> %d \n", input_munsa_lock_type); } gen_stat = dlm_cvt(&lkid, input_munsa_lock_type, NULL, 0, 0, 0, NULL, 0); if (gen_stat != DLM_SUCCESS) { Fprintf ("dlm_cvt failed\n"); dlm_error(&lkid, gen_stat); /* exit with FATAL ERROR */ } if (debug_flag) { Printf ("done, converting to dlm NL-> %d \n", input_munsa_lock_type); } } /* end if(munsa_flag) .... */#endif /* defined(MUNSA) */ dip->di_offset = make_offset(dip, lbdata_addr); /* * Loop reading/comparing data until we've detected end of file * or we've reached the data limit or record limit. */ do { /* Read/compare data. */ dip->di_fbytes_read =(v_large) 0; dip->di_records_read = (v_large) 0;read_some_more: if ((status = (*dtf->tf_read_data)(dip)) == FAILURE) break; if (volumes_flag && (multi_volume >= volume_limit) && (dip->di_volume_records >= volume_records)) { break; } /* * Handle reading multiple tapes and multiple files. */ if (end_of_file && multi_flag && (dip->di_dtype->dt_dtype == DT_TAPE) && ((dip->di_records_read != record_limit) && (dip->di_fbytes_read != data_limit)) ) { /* Check for logical end of tape. */ (void) (*dtf->tf_cancel_reads)(dip); if ((status = read_eom(dip)) != SUCCESS) break; if ( !end_of_file ) goto read_some_more; } if (end_of_file) dip->di_files_read++; if ( (dip->di_dtype->dt_dtype == DT_TAPE) && (file_limit && (dip->di_files_read < file_limit)) ) { /* * Normally, we handle EOF conditions on the fly, but when lbdata * or the IOT pattern is enabled, we must cancel outstanding I/O's * so that aio_offset (for LBA) is accurate on subsequent files. */ if (lbdata_flag || iot_pattern) { (void) (*dtf->tf_cancel_reads)(dip); } /* * An exact record or data limit keeps us short of file marks, * so we read and check for an expected end of file here. */ if (!end_of_file) {#if defined(__NUTC__) || defined(__QNXNTO__) || defined(AIX) if ((status = read_eof(dip)) != SUCCESS) break;#else /* !defined(__NUTC__) && !defined(__QNXNTO__) && !defined(AIX) */ status = DoForwardSpaceFile (dip, (daddr_t) 1); if (status != SUCCESS) break;#endif /* defined(__NUTC__) || defined(__QNXNTO__) || defined(AIX) */ if (++dip->di_files_read == file_limit) break; } dip->di_fbytes_read =(v_large) 0; dip->di_records_read = (v_large) 0; end_of_file = FALSE; continue; } } while ( !end_of_file && (error_count < error_limit) && (dip->di_records_read < record_limit) && (dip->di_fbytes_read < data_limit) ); /* * We cancel the reads here incase multiple files were being * read, so reads continue while we process each file mark. */ (void) (*dtf->tf_cancel_reads)(dip); return (status);}/************************************************************************ * * * write_file() - Write data to the test file/device. * * * * Inputs: dip = The device information pointer. * * * * Return Value: * * Returns SUCCESS/FAILURE = Ok/Error. * * * ************************************************************************/intwrite_file (struct dinfo *dip){ int status; struct dtfuncs *dtf = dip->di_funcs;#if defined(MUNSA) if (munsa_flag) { if (debug_flag) { Printf ("converting to dlm NL-> %d .\n", output_munsa_lock_type); } gen_stat = dlm_cvt(&lkid, output_munsa_lock_type, NULL, 0, 0, 0, NULL, 0); if (gen_stat != DLM_SUCCESS) { Fprintf ("dlm_cvt failed\n"); dlm_error(&lkid, gen_stat); /* exit with FATAL ERROR */ } if (debug_flag) { Printf ("done, converting to dlm NL-> %d .\n", output_munsa_lock_type); } } /* end if(munsa_flag)... */#endif /* defined(MUNSA) */ dip->di_offset = make_offset(dip, lbdata_addr); /* * Initialize the data buffer with a pattern if compare is * disabled, so we honor the user specified pattern. */ if ((io_mode == TEST_MODE) && !compare_flag) { if (iot_pattern) { u_int32 lba = make_lbdata (dip, dip->di_offset); (void)init_iotdata(block_size, lba, lbdata_size); } fill_buffer (data_buffer, block_size, pattern); } /* * Loop writing data until end of media or data limit reached. */ do { /* Write data pattern. */ if (raw_flag) { dip->di_fbytes_read =(v_large) 0; dip->di_records_read = (v_large) 0; } dip->di_fbytes_written =(v_large) 0; dip->di_records_written = (v_large) 0; if ((status = (*dtf->tf_write_data)(dip)) == FAILURE) break; if (volumes_flag && (multi_volume >= volume_limit) && (dip->di_volume_records >= volume_records)) { break; } /* * Handle writing multiple tape files. */ if ( (dip->di_dtype->dt_dtype == DT_TAPE) && (file_limit && (dip->di_files_written < file_limit)) ) { /* * For tapes, write a file mark for all but last file. * The last file mark(s) are written when closing tape. */#if !defined(__NUTC__) && !defined(__QNXNTO__) && !defined(AIX) if ((dip->di_files_written + 1) < file_limit) { status = DoWriteFileMark (dip, (daddr_t) 1); if (status != SUCCESS) break; }#endif /* !defined(__NUTC__) && !defined(__QNXNTO__) && !defined(AIX) */ if (++dip->di_files_written < file_limit) { dip->di_fbytes_written =(v_large) 0; dip->di_records_written = (v_large) 0; continue; /* Write the next file. */ } } } while ( !end_of_file && (error_count < error_limit) && (dip->di_records_written < record_limit) && (dip->di_fbytes_written < data_limit) ); return (status);}/************************************************************************ * * * validate_opts() - Generic Validate Option Test Criteria. * * * * Description: * * This function verifies the options specified are valid for the * * test criteria selected. * * * * Inputs: dip = The device information pointer. * * * * Return Value: * * Returns SUCESS / FAILURE = Valid / Invalid Options. * * * ************************************************************************/intvalidate_opts (struct dinfo *dip){ if (bypass_flag) return (SUCCESS); if (dip->di_fd == NoFd) { /* * Validation checks *before* the device is open. */ if (min_size) { size_t value; char *emsg = NULL; if (dip->di_dsize > min_size) { value = min_size; emsg = "min size"; } else if (dip->di_dsize > max_size) { value = max_size; emsg = "max size"; } if (emsg) { Fprintf( "Please specify %s (%u) greater than device size %u of bytes.\n", emsg, value, dip->di_dsize); return (FAILURE); } } } else { /* * Validation checks *after* the device is open. */ if ( (dip->di_dtype->dt_dtype == DT_REGULAR) && (dip->di_ftype == OUTPUT_FILE) && num_slices && (dispose_mode == DELETE_FILE) ) { dispose_mode = KEEP_FILE; if (verbose_flag) { Printf("Warning: Multiple slices to same file, setting dispose=keep!\n"); } } if ( (io_dir == REVERSE) || (io_type == RANDOM_IO) ) { if ( !dip->di_random_access ) { Fprintf( "Random I/O or reverse direction, is only valid for random access device!\n"); return (FAILURE); } if ( (dip->di_dtype->dt_dtype == DT_REGULAR) && !user_capacity ) { Fprintf( "Please specify a data limit, record count, or capacity for random I/O.\n"); return (FAILURE); } } if (dip->di_random_access) { size_t value; char *emsg = NULL; if (block_size % dip->di_dsize) { value = block_size; emsg = "block size"; } else if (min_size && (min_size % dip->di_dsize)) { value = min_size; emsg = "min size"; } else if (max_size && (max_size % dip->di_dsize)) { value = max_size; emsg = "max size"; } else if (incr_count && (incr_count % dip->di_dsize)) { value = incr_count; emsg = "incr count"; } if (emsg) { Fprintf( "Please specify a %s (%u) modulo the device size of %u bytes!\n", emsg, value, dip->di_dsize); return (FAILURE); } } } return (SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -