/************************************************************************** * * iorate.h - General information for IORATE * * Copyright by EMC Corporation, 1997-2011. * All rights reserved. * * Written by Vince Westin (vince.westin@emc.com), with a lot of * assistance from the EMC Engineering Team. * * This code is the property of EMC Corporation. However, it may be used, * reproduced, and passed on to others as long as the contents, including * all copyright notices, remain intact. Modifications to, or modified * versions of these files, may also be distributed, provided that they * are clearly labeled as having been modified from the original. In the * event that modified files are created, the original files are to be * included with every distribution of those modified files. Inclusion of * this code into a commercial product by any company other than EMC is * prohibited without prior written consent. * * Having said the legal stuff, this code is designed to provide a good, * generic tool for testing I/O subsystems under various kinds of loads. * If you have suggestions for improvements in this tool, please send them * along to the above address. * *************************************************************************/ /* * Defines for general structures, funtions, etc. * * $Header: /home/westiv/iorate/RCS/iorate.h,v 3.18 2011/11/03 15:49:26 westiv Exp westiv $ */ #ifndef IORATE_INCLUDE #define IORATE_INCLUDE #include "ior_mach.h" /* machine dependent stuff */ #define IOR_MAX_IO_SIZE ((HUGE)(4*1024*1024)) #define IOR_MAX_DEVICES 1024 #define IOR_MAX_PATTERNS 96 #define IOR_MAX_TESTS 256 #define IOR_MAX_DEV_COPIES 256 #define IOR_OVER_MAX 60 /* limit to 60 seconds over */ #define IOR_BUFFER_SIZE 1024 #define IOR_READ 1L #define IOR_WRITE 2L #define IOR_HISTORY_DEFAULT 32 #define IOR_ZONES_DEFAULT 1 #define IOR_ZONE_LIMIT_DEFAULT 32 #define IOR_SKEW_MIN 50 /* minimum skew we allow */ #define IOR_SKEW_SEED 1939 /* default seed for skew */ #define IOR_SKEW_MAX_SEQ 100 /* max seq. for skew test */ #define IOR_SKEW_LISTS 16 /* skew lists to drive I/O against */ #define IOR_CORRELATE_ODDS 20 /* correlation factors we use */ #define IOR_AREA_MIN (1024 * 1024) #define IOR_AREA_MAX (100*IOR_AREA_MIN) #define IOR_AREA_MIN_PER_DRIVE 1000 /* minimum areas per drive */ #define IOR_AREA_GROUPING 10000 /* above this level, scale size by reusing areas */ #define IOR_DEBUG_MAJOR 10 #define IOR_DEBUG_MINOR 100 #define IOR_DEBUG_SMALL 500 #define IOR_DEBUG_ALL 1000 #ifndef NULL #define NULL 0 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #define PROC_PERF_FILE "%s/iorate-%d.%d.%d.per" /* * ior_odds_item_struct - odds item tracking structure */ typedef struct ior_odds_item_struct { int i_id; /* ID of the item with these odds */ long i_odds_start; /* odds starting value */ long i_odds_count; /* number of chances this item has */ long i_odds_end; /* odds ending value */ void *i_id_ptr; /* pointer to the item with odds */ } ior_odds_item; /* * ior_odds_struct - odds tracking structure */ typedef struct ior_odds_struct { int o_items_count; /* how many are we choosing between */ long o_odds_count; /* total options to pick from */ ior_odds_item *o_odds; /* the true odds list */ } ior_odds; /* * ior_skew_perf - performace record for a skew area group * * Could have these per I/O size or pattern, but a LOT more data */ typedef struct ior_skew_perf_struct { HUGE sp_rand_reads; /* random reads against this profile */ HUGE sp_seq_reads; /* sequentail reads against this profile */ HUGE sp_rand_writes; /* random writes against this profile */ HUGE sp_seq_writes; /* sequential writes against this profile */ double sp_rand_read_resp; /* response time on random reads */ double sp_seq_read_resp; /* response time on sequential reads */ double sp_rand_write_resp; /* response time on random writes */ double sp_seq_write_resp; /* response time on sequential writes */ } ior_skew_perf; /* * ior_skew_area - areas of skew performance I/O */ typedef struct ior_skew_area_struct { long a_id; /* ID of this area */ long a_copies; /* how many copies on THIS device */ HUGE a_start; /* starting location */ HUGE a_end; /* ending location */ HUGE a_size; /* size of this area */ struct ior_skew_area_struct *a_prev; /* previous area in our linked list */ struct ior_skew_area_struct *a_next; /* next area in our linked list */ struct ior_skew_list_struct *a_list; /* the list we are a part of */ } ior_skew_area; /* * ior_skew_pat_struct - pattern information structure for skew groups */ typedef struct ior_skew_pat_struct { /* I/O pattern definitions */ char *p_name; /* name of this pattern */ ior_skew_area *p_seq_area; /* area for sequntial I/O */ long p_seq_copy; /* which copy of the area */ HUGE *p_hist_records; /* history of recent I/Os */ ior_skew_area **p_hist_areas; /* area for historical I/Os */ BYTE p_read_use[ 100 ]; /* % lookup for read access */ BYTE p_hist_use[ 100 ]; /* % lookup for history access */ long p_io_size; /* size of each I/O */ long p_history; /* limit of history count */ long p_hist_active; /* count of active history records */ long p_hist_next; /* next history record to replace */ long p_max_seq; /* maximum seqential I/Os */ long p_cur_seq; /* current seq. completed */ HUGE p_pos; /* position of next I/O */ float p_read_pct; /* read percentage */ float p_reuse_pct; /* reuse % - I/O hits */ BYTE p_is_seq; /* seq/random toggle */ BYTE p_valid; /* is this pattern OK to use? */ } ior_skew_pat; /* * ior_skew_list - collection of areas where testing will happen */ typedef struct ior_skew_list_struct { int s_id; /* ID of this skew list */ ior_skew_area *s_areas; /* areas to be tested */ ior_skew_pat s_pats[ IOR_MAX_PATTERNS + 2 ]; /* partial I/O patterns */ long s_area_goal; /* how many areas should we get */ long s_area_current; /* how many areas do we already have */ ior_skew_perf s_perf; /* performance tracking items */ } ior_skew_list; /* * ior_dev_struct - device information structure */ typedef struct ior_dev_struct { /* device to do I/O against */ char *d_name; /* name of the file */ HUGE d_offset; /* offset to start of test */ HUGE d_capacity; /* active test size */ long d_block_size; /* minimum block size */ long d_procs[ IOR_MAX_DEV_COPIES + 2 ]; /* PIDs active on dev */ int d_count; /* number of copies to run */ int d_fid; /* file ID for open file */ BYTE d_is_async; /* use async I/O? */ BYTE d_read_only; /* reads only? */ BYTE d_is_temp; /* make temporary FS file for test? */ BYTE d_create; /* create (and leave) if needed? */ BYTE d_lock; /* use advisory locks on this file? */ BYTE d_is_created; /* temp file already built? */ BYTE d_is_active; /* is this device active? */ BYTE d_valid; /* is this device OK to use? */ } ior_device; /* * ior_pat_struct - pattern information structure * * p_max_seq - maximum number of seqential I/Os that will be performed * before picking a new (random) starting location for the next batch * of sequentail I/O. This can simulate log file type activity. */ typedef struct ior_pat_struct { /* I/O pattern definitions */ char *p_name; /* name of this pattern */ BYTE p_read_use[ 100 ]; /* % lookup for read access */ BYTE p_hist_use[ 100 ]; /* % lookup for history access */ HUGE *p_local_uses; /* locality I/O count */ HUGE *p_local_seqs; /* locality seq. I/O count */ HUGE *p_local_pos; /* position within localities */ HUGE *p_local_starts; /* starts of localities */ HUGE *p_local_ends; /* ends of localities */ HUGE *p_hist_records; /* history of recent I/Os */ long p_io_size; /* size of each I/O */ long p_history; /* limit of history count */ long p_hist_active; /* count of active history records */ long p_hist_next; /* next history record to replace */ HUGE p_max_seq; /* maximum seqential I/Os */ HUGE p_cur_seq; /* current seq. completed */ HUGE p_pos; /* position of next I/O */ HUGE p_start; /* where do we start? */ HUGE p_size; /* how much do we test? */ HUGE p_end; /* end of test area - start + size */ HUGE p_local_size; /* size of locality areas */ HUGE p_local_count; /* number of active localities */ HUGE p_local_limit; /* limit on I/Os to a locality */ HUGE p_cur_local; /* active locality */ HUGE p_local_avail; /* number of localities in test size */ float p_start_pct; /* starting percentage */ float p_size_pct; /* size percentage */ float p_read_pct; /* read percentage */ float p_local_pct; /* locality use % */ float p_reuse_pct; /* reuse % - I/O hits */ BYTE p_is_seq; /* seq/random toggle */ BYTE p_valid; /* is this pattern OK to use? */ } ior_pattern; /* * ior_test - definitions of the tests that will be run * * t_patterns - an array of 100 pattern IDs. For each test run, a random * number (mod 100) is used to select which pattern will be used next. */ typedef struct ior_test_struct { /* I/O test definitions */ char *t_name; /* name of this test */ long t_duration; /* duration in seconds */ long t_ignore; /* seconds of 'start-up' stats */ long t_pause; /* seconds of waiting before test */ long t_iops; /* maximum I/Os per sec. to drive */ int t_skew; /* sub-LUN skew level to emulate */ long t_seed; /* random seed for skew data */ int t_shift; /* sub-LUN skew shift */ int t_correlate; /* correlation of skewed data */ HUGE t_area; /* size of each area for skew */ HUGE t_start; /* where do we start? */ HUGE t_size; /* how much do we test? */ HUGE t_end; /* end of test area - start + size */ float t_start_pct; /* starting percentage */ float t_size_pct; /* size percentage */ int t_pat_pct[ IOR_MAX_PATTERNS + 2 ]; /* percent of each pattern */ int t_patterns[ 100 ]; /* patterns to run */ BYTE t_running; /* running with stats on */ BYTE t_valid; /* is this test OK to use? */ } ior_test; /* * ior_config - overall configuration information for iorate * * c_sleep - will give any outstanding data (like that stored in cache for * a cached array) time to destage, enabling the next test to be more * accurate of what the particular test is trying to measure. * * c_ignore - stats for this many seconds at the start of each test will be * dropped from the test totals, to give a 'steady state' measure of * the I/O rate for the particular test. */ typedef struct ior_config_struct { /* overall iorate config info */ char *c_program; /* name of this program */ BYTE c_verbose; /* be chatty about work in progress */ BYTE c_debug; /* ONLY used for program debugging */ BYTE c_silent; /* be silent to stdout */ BYTE c_show_limit; /* display size limits and exit */ BYTE c_no_testing; /* don't actually do any testing */ BYTE c_is_active; /* are tests in progress */ BYTE c_tollerate_short_reads; /* be OK with reads that are short */ BYTE c_direct_io; /* set direct I/O when opening files */ int c_debug_level; /* level of debug messages to show */ char *c_log_name; /* name of log info file */ char *c_perf_name; /* name of perf info file */ char *c_perf_dir; /* directory for performance info */ FILE *c_log_file; /* file for log info */ FILE *c_perf_file; /* file for performance info */ int c_sleep; /* seconds to sleep between tests */ int c_ignore; /* seconds of I/O to not rate */ long c_target_resp; /* target response time - slowed */ double c_target_sec; /* target response time - in seconds */ int c_target_rate; /* percent of target iops to use */ int c_shift; /* sub-LUN skew shift for all tests */ float c_area_count; /* how many area groups on the device */ long c_num_areas; /* number of used areas */ ior_skew_area *c_areas; /* the areas holding our data */ HUGE c_max_area; /* largest area size for skew testing */ HUGE c_area; /* current area size for skew testing */ HUGE c_skew_set_size; /* the size of the device covered by a full set of all areas */ HUGE c_max_dev_size; /* size of the largest active device */ HUGE c_min_dev_size; /* size of the smallest active device */ float c_skew_capacities[ 5 ]; /* capacities for skewed data */ float c_skew_workloads[ 5 ]; /* iops for skewed data */ int c_skew_group_count[ 5 ]; /* number of skew groups in each target range */ ior_skew_list c_skewed[ IOR_SKEW_LISTS + 2 ]; /* our skew lists */ ior_odds_item c_odds_i[ IOR_SKEW_LISTS + 2 ]; /* odds of I/O to each skew list */ ior_odds c_odds; /* odds for I/Os */ int c_ndev; /* number of target devices */ int c_vdev; /* number of valid target devices */ int c_adev; /* number of active target devices */ /* note active includes copies */ int c_npat; /* number of defined patterns */ int c_ntest; /* number of defined tests */ char *c_dev_name; /* device file name */ char *c_pat_name; /* pattern file name */ char *c_test_name; /* test file name */ char *c_iops_name; /* iops file name */ ior_device c_devs[ IOR_MAX_DEVICES + 2 ]; /* target device list */ ior_pattern c_pats[ IOR_MAX_PATTERNS + 2 ]; /* available patterns to run */ ior_test c_tests[ IOR_MAX_TESTS + 2 ]; /* the tests that will be run */ long c_fid; /* file descriptor */ HUGE c_pos; /* current file position */ HUGE c_start; /* where do we start? */ HUGE c_size; /* how much do we test? */ HUGE c_end; /* end of test area - start + size */ HUGE c_align; /* block count to align on */ HUGE c_blocks_read; /* count of blocks read */ HUGE c_blocks_written; /* count of blocks written */ HUGE c_reads; /* number of reads performed */ HUGE c_writes; /* number of writes performed */ double c_read_time_msecs; /* read perf time in milisecs */ double c_write_time_msecs; /* write perf time in milisecs */ ior_clock c_io_time; /* elapsed time for counted I/Os */ int c_errors; /* # of errors seen this pass */ int c_cur_dev; /* active device */ int c_cur_adev; /* active within count on device */ int c_cur_test; /* test we are running */ int c_cur_pat; /* pattern we are using */ ior_clock c_start_time; /* time we started this test run */ /* file parsing records */ char c_l_str[ 256 ]; /* contents of found strings */ double c_l_value; /* values of parsed numbers */ int c_l_line; /* line number being parsed */ char *c_l_name; /* name of file being parsed */ char *c_l_cur_txt; /* text of current line being read */ int c_l_cur_pos; /* location of current read */ char c_l_error[ 256 ]; /* string of error message */ BYTE *c_read_buf; /* buffers for the real I/O */ BYTE *c_write_buf; } ior_config; extern char msg_buf[]; /* message buffer */ /* * functions from ior_file.c */ extern int ior_read_devs( ior_config *cfg ); extern int ior_read_pats( ior_config *cfg ); extern int ior_read_tests( ior_config *cfg ); extern int ior_log_devs( ior_config *cfg ); extern int ior_log_pats( ior_config *cfg ); extern int ior_log_tests( ior_config *cfg ); extern char *ior_size_to_ascii( ior_config *cfg, HUGE t_size ); extern char *ior_time_to_ascii( ior_config *cfg, long t_time ); /* * functions from ior_mach.c */ extern int ior_open_dev( ior_config *cfg, int dev ); extern int ior_close_dev( ior_config *cfg, int dev ); extern int ior_read( ior_config *cfg, long io_size, double *io_resp ); extern int ior_write( ior_config *cfg, long io_size, double *io_resp ); extern int ior_seek( ior_config *cfg, HUGE pos ); extern int ior_get_capacity( ior_config *cfg, long dev ); extern HUGE ior_rand( ior_config *cfg ); extern int ior_random_seed( ior_config *cfg, long seed ); extern int ior_randomize( ior_config *cfg ); extern long ior_get_time( ior_config *cfg ); extern int ior_date_string( ior_config *cfg, ior_clock clk, char *str ); extern int ior_sleep( ior_config *cfg, int sec ); extern int ior_sleep_usec( ior_config *cfg, long usec ); extern int ior_set_lock( ior_config *cfg ); extern int ior_clear_lock( ior_config *cfg ); /* * functions from ior_test.c */ extern int ior_run_dev_test( ior_config *cfg ); extern int ior_test_prep_std( ior_config *cfg ); extern int ior_test_prep_skew( ior_config *cfg ); extern int ior_run_pat( ior_config *cfg, long pat ); extern int ior_run_skew( ior_config *cfg, long pat ); extern int ior_run_sel_pat( ior_config *cfg, long pat ); extern int ior_io( ior_config *cfg, long io, long io_size, HUGE pos, ior_skew_list *skew ); extern int ior_set_rand_pos( ior_config *cfg, long pat ); /* * functions from iorate.c */ extern int ior_read_args( ior_config *cfg, int argc, char **argv ); extern int ior_read_config( ior_config *cfg ); extern int ior_prepare( ior_config *cfg ); extern int ior_run_tests( ior_config *cfg ); extern int ior_cleanup( ior_config *cfg ); extern int ior_usage( ior_config *cfg ); extern int ior_error( ior_config *cfg, char *msg ); extern int ior_warn( ior_config *cfg, char *msg ); extern int ior_msg( ior_config *cfg, char *msg_type, char *msg ); extern int ior_verbose( ior_config *cfg, char *msg ); extern int ior_log( ior_config *cfg, char *msg ); extern int ior_write_log( ior_config *cfg, char *str ); extern char *ior_strdup( ior_config *cfg, char *str ); #define IOR_AREA_HEAD TRUE #define IOR_AREA_TAIL FALSE extern int ior_area( ior_config *cfg, int to_head, ior_skew_area *area, ior_skew_list *list ); extern int ior_odds_pick( ior_config *cfg, ior_odds *odds ); extern int ior_signal_kids( ior_config *cfg, int sig ); extern void ior_signal( int sig ); extern int ior_read_iops( ior_config *cfg ); extern int ior_parse_prep( ior_config *cfg, char *f_name ); extern int yyparse(); extern int ior_debug( ior_config *cfg, char *msg ); extern int ior_debug_l( ior_config *cfg, int level, char *msg ); extern int ior_dev_lock( ior_config *cfg, long dev ); extern int ior_dev_unlock( ior_config *cfg, long dev ); extern int ior_time_usec( ior_config *cfg, long *sec, long *usec ); extern int ior_lex_prep( ior_config *cfg); extern int ior_parse_dev_clear( ior_config *cfg ); extern int ior_parse_pat_clear( ior_config *cfg ); extern int ior_parse_test_clear( ior_config *cfg ); extern int ior_lex_done( ior_config *cfg); extern int yylex(); extern int ior_lex_is_sep( ior_config *cfg, char c ); #ifdef IOR_ENGINEERING extern int ior_eng_prep( ior_config *cfg ); extern int ior_eng_pre_test( ior_config *cfg ); extern int ior_eng_test_done( ior_config *cfg ); extern int ior_eng_clean( ior_config *cfg ); extern int ior_eng_read( ior_config *cfg, long io_size, long bytes_trans, double resp_time ); extern int ior_eng_write( ior_config *cfg, long io_size, long bytes_trans, double resp_time ); #endif #endif