1 /************************************************************************** 2 * 3 * iorate.h - General information for IORATE 4 * 5 * Copyright by EMC Corporation, 1997-2011. 6 * All rights reserved. 7 * 8 * Written by Vince Westin (vince.westin@emc.com), with a lot of 9 * assistance from the EMC Engineering Team. 10 * 11 * This code is the property of EMC Corporation. However, it may be used, 12 * reproduced, and passed on to others as long as the contents, including 13 * all copyright notices, remain intact. Modifications to, or modified 14 * versions of these files, may also be distributed, provided that they 15 * are clearly labeled as having been modified from the original. In the 16 * event that modified files are created, the original files are to be 17 * included with every distribution of those modified files. Inclusion of 18 * this code into a commercial product by any company other than EMC is 19 * prohibited without prior written consent. 20 * 21 * Having said the legal stuff, this code is designed to provide a good, 22 * generic tool for testing I/O subsystems under various kinds of loads. 23 * If you have suggestions for improvements in this tool, please send them 24 * along to the above address. 25 * 26 *************************************************************************/ 27 28 /* 29 * Defines for general structures, funtions, etc. 30 * 31 * $Header: /home/westiv/iorate/RCS/iorate.h,v 3.18 2011/11/03 15:49:26 westiv Exp westiv $ 32 */ 33 34 #ifndef IORATE_INCLUDE 35 #define IORATE_INCLUDE 36 37 #include "ior_mach.h" /* machine dependent stuff */ 38 39 #define IOR_MAX_IO_SIZE ((HUGE)(4*1024*1024)) 40 #define IOR_MAX_DEVICES 1024 41 #define IOR_MAX_PATTERNS 96 42 #define IOR_MAX_TESTS 256 43 #define IOR_MAX_DEV_COPIES 256 44 45 #define IOR_OVER_MAX 60 /* limit to 60 seconds over */ 46 47 #define IOR_BUFFER_SIZE 1024 48 49 #define IOR_READ 1L 50 #define IOR_WRITE 2L 51 52 #define IOR_HISTORY_DEFAULT 32 53 54 #define IOR_ZONES_DEFAULT 1 55 #define IOR_ZONE_LIMIT_DEFAULT 32 56 57 #define IOR_SKEW_MIN 50 /* minimum skew we allow */ 58 #define IOR_SKEW_SEED 1939 /* default seed for skew */ 59 #define IOR_SKEW_MAX_SEQ 100 /* max seq. for skew test */ 60 #define IOR_SKEW_LISTS 16 /* skew lists to drive I/O against */ 61 #define IOR_CORRELATE_ODDS 20 /* correlation factors we use */ 62 #define IOR_AREA_MIN (1024 * 1024) 63 #define IOR_AREA_MAX (100*IOR_AREA_MIN) 64 #define IOR_AREA_MIN_PER_DRIVE 1000 /* minimum areas per drive */ 65 #define IOR_AREA_GROUPING 10000 /* above this level, scale size by reusing areas */ 66 67 #define IOR_DEBUG_MAJOR 10 68 #define IOR_DEBUG_MINOR 100 69 #define IOR_DEBUG_SMALL 500 70 #define IOR_DEBUG_ALL 1000 71 72 #ifndef NULL 73 #define NULL 0 74 #endif 75 76 #ifndef FALSE 77 #define FALSE 0 78 #endif 79 80 #ifndef TRUE 81 #define TRUE 1 82 #endif 83 84 85 #define PROC_PERF_FILE "%s/iorate-%d.%d.%d.per" 86 87 88 /* 89 * ior_odds_item_struct - odds item tracking structure 90 */ 91 typedef struct ior_odds_item_struct { 92 int i_id; /* ID of the item with these odds */ 93 long i_odds_start; /* odds starting value */ 94 long i_odds_count; /* number of chances this item has */ 95 long i_odds_end; /* odds ending value */ 96 void *i_id_ptr; /* pointer to the item with odds */ 97 } ior_odds_item; 98 99 /* 100 * ior_odds_struct - odds tracking structure 101 */ 102 typedef struct ior_odds_struct { 103 int o_items_count; /* how many are we choosing between */ 104 long o_odds_count; /* total options to pick from */ 105 ior_odds_item *o_odds; /* the true odds list */ 106 } ior_odds; 107 108 109 /* 110 * ior_skew_perf - performace record for a skew area group 111 * 112 * Could have these per I/O size or pattern, but a LOT more data 113 */ 114 typedef struct ior_skew_perf_struct { 115 HUGE sp_rand_reads; /* random reads against this profile */ 116 HUGE sp_seq_reads; /* sequentail reads against this profile */ 117 HUGE sp_rand_writes; /* random writes against this profile */ 118 HUGE sp_seq_writes; /* sequential writes against this profile */ 119 double sp_rand_read_resp; /* response time on random reads */ 120 double sp_seq_read_resp; /* response time on sequential reads */ 121 double sp_rand_write_resp; /* response time on random writes */ 122 double sp_seq_write_resp; /* response time on sequential writes */ 123 } ior_skew_perf; 124 125 /* 126 * ior_skew_area - areas of skew performance I/O 127 */ 128 typedef struct ior_skew_area_struct { 129 long a_id; /* ID of this area */ 130 131 long a_copies; /* how many copies on THIS device */ 132 133 HUGE a_start; /* starting location */ 134 HUGE a_end; /* ending location */ 135 HUGE a_size; /* size of this area */ 136 137 struct ior_skew_area_struct *a_prev; /* previous area in our linked list */ 138 struct ior_skew_area_struct *a_next; /* next area in our linked list */ 139 140 struct ior_skew_list_struct *a_list; /* the list we are a part of */ 141 } ior_skew_area; 142 143 /* 144 * ior_skew_pat_struct - pattern information structure for skew groups 145 */ 146 typedef struct ior_skew_pat_struct { /* I/O pattern definitions */ 147 char *p_name; /* name of this pattern */ 148 ior_skew_area *p_seq_area; /* area for sequntial I/O */ 149 long p_seq_copy; /* which copy of the area */ 150 HUGE *p_hist_records; /* history of recent I/Os */ 151 ior_skew_area **p_hist_areas; /* area for historical I/Os */ 152 BYTE p_read_use[ 100 ]; /* % lookup for read access */ 153 BYTE p_hist_use[ 100 ]; /* % lookup for history access */ 154 long p_io_size; /* size of each I/O */ 155 long p_history; /* limit of history count */ 156 long p_hist_active; /* count of active history records */ 157 long p_hist_next; /* next history record to replace */ 158 long p_max_seq; /* maximum seqential I/Os */ 159 long p_cur_seq; /* current seq. completed */ 160 HUGE p_pos; /* position of next I/O */ 161 float p_read_pct; /* read percentage */ 162 float p_reuse_pct; /* reuse % - I/O hits */ 163 BYTE p_is_seq; /* seq/random toggle */ 164 BYTE p_valid; /* is this pattern OK to use? */ 165 } ior_skew_pat; 166 167 /* 168 * ior_skew_list - collection of areas where testing will happen 169 */ 170 typedef struct ior_skew_list_struct { 171 int s_id; /* ID of this skew list */ 172 ior_skew_area *s_areas; /* areas to be tested */ 173 ior_skew_pat s_pats[ IOR_MAX_PATTERNS + 2 ]; /* partial I/O patterns */ 174 long s_area_goal; /* how many areas should we get */ 175 long s_area_current; /* how many areas do we already have */ 176 ior_skew_perf s_perf; /* performance tracking items */ 177 } ior_skew_list; 178 179 180 /* 181 * ior_dev_struct - device information structure 182 */ 183 typedef struct ior_dev_struct { /* device to do I/O against */ 184 char *d_name; /* name of the file */ 185 HUGE d_offset; /* offset to start of test */ 186 HUGE d_capacity; /* active test size */ 187 long d_block_size; /* minimum block size */ 188 long d_procs[ IOR_MAX_DEV_COPIES + 2 ]; /* PIDs active on dev */ 189 int d_count; /* number of copies to run */ 190 int d_fid; /* file ID for open file */ 191 BYTE d_is_async; /* use async I/O? */ 192 BYTE d_read_only; /* reads only? */ 193 BYTE d_is_temp; /* make temporary FS file for test? */ 194 BYTE d_create; /* create (and leave) if needed? */ 195 BYTE d_lock; /* use advisory locks on this file? */ 196 BYTE d_is_created; /* temp file already built? */ 197 BYTE d_is_active; /* is this device active? */ 198 BYTE d_valid; /* is this device OK to use? */ 199 } ior_device; 200 201 /* 202 * ior_pat_struct - pattern information structure 203 * 204 * p_max_seq - maximum number of seqential I/Os that will be performed 205 * before picking a new (random) starting location for the next batch 206 * of sequentail I/O. This can simulate log file type activity. 207 */ 208 typedef struct ior_pat_struct { /* I/O pattern definitions */ 209 char *p_name; /* name of this pattern */ 210 BYTE p_read_use[ 100 ]; /* % lookup for read access */ 211 BYTE p_hist_use[ 100 ]; /* % lookup for history access */ 212 HUGE *p_local_uses; /* locality I/O count */ 213 HUGE *p_local_seqs; /* locality seq. I/O count */ 214 HUGE *p_local_pos; /* position within localities */ 215 HUGE *p_local_starts; /* starts of localities */ 216 HUGE *p_local_ends; /* ends of localities */ 217 HUGE *p_hist_records; /* history of recent I/Os */ 218 long p_io_size; /* size of each I/O */ 219 long p_history; /* limit of history count */ 220 long p_hist_active; /* count of active history records */ 221 long p_hist_next; /* next history record to replace */ 222 HUGE p_max_seq; /* maximum seqential I/Os */ 223 HUGE p_cur_seq; /* current seq. completed */ 224 HUGE p_pos; /* position of next I/O */ 225 HUGE p_start; /* where do we start? */ 226 HUGE p_size; /* how much do we test? */ 227 HUGE p_end; /* end of test area - start + size */ 228 HUGE p_local_size; /* size of locality areas */ 229 HUGE p_local_count; /* number of active localities */ 230 HUGE p_local_limit; /* limit on I/Os to a locality */ 231 HUGE p_cur_local; /* active locality */ 232 HUGE p_local_avail; /* number of localities in test size */ 233 float p_start_pct; /* starting percentage */ 234 float p_size_pct; /* size percentage */ 235 float p_read_pct; /* read percentage */ 236 float p_local_pct; /* locality use % */ 237 float p_reuse_pct; /* reuse % - I/O hits */ 238 BYTE p_is_seq; /* seq/random toggle */ 239 BYTE p_valid; /* is this pattern OK to use? */ 240 } ior_pattern; 241 242 /* 243 * ior_test - definitions of the tests that will be run 244 * 245 * t_patterns - an array of 100 pattern IDs. For each test run, a random 246 * number (mod 100) is used to select which pattern will be used next. 247 */ 248 typedef struct ior_test_struct { /* I/O test definitions */ 249 char *t_name; /* name of this test */ 250 long t_duration; /* duration in seconds */ 251 long t_ignore; /* seconds of 'start-up' stats */ 252 long t_pause; /* seconds of waiting before test */ 253 long t_iops; /* maximum I/Os per sec. to drive */ 254 255 int t_skew; /* sub-LUN skew level to emulate */ 256 long t_seed; /* random seed for skew data */ 257 int t_shift; /* sub-LUN skew shift */ 258 int t_correlate; /* correlation of skewed data */ 259 HUGE t_area; /* size of each area for skew */ 260 261 HUGE t_start; /* where do we start? */ 262 HUGE t_size; /* how much do we test? */ 263 HUGE t_end; /* end of test area - start + size */ 264 float t_start_pct; /* starting percentage */ 265 float t_size_pct; /* size percentage */ 266 int t_pat_pct[ IOR_MAX_PATTERNS + 2 ]; /* percent of each pattern */ 267 int t_patterns[ 100 ]; /* patterns to run */ 268 BYTE t_running; /* running with stats on */ 269 BYTE t_valid; /* is this test OK to use? */ 270 } ior_test; 271 272 /* 273 * ior_config - overall configuration information for iorate 274 * 275 * c_sleep - will give any outstanding data (like that stored in cache for 276 * a cached array) time to destage, enabling the next test to be more 277 * accurate of what the particular test is trying to measure. 278 * 279 * c_ignore - stats for this many seconds at the start of each test will be 280 * dropped from the test totals, to give a 'steady state' measure of 281 * the I/O rate for the particular test. 282 */ 283 typedef struct ior_config_struct { /* overall iorate config info */ 284 char *c_program; /* name of this program */ 285 BYTE c_verbose; /* be chatty about work in progress */ 286 BYTE c_debug; /* ONLY used for program debugging */ 287 BYTE c_silent; /* be silent to stdout */ 288 BYTE c_show_limit; /* display size limits and exit */ 289 BYTE c_no_testing; /* don't actually do any testing */ 290 BYTE c_is_active; /* are tests in progress */ 291 BYTE c_tollerate_short_reads; /* be OK with reads that are short */ 292 BYTE c_direct_io; /* set direct I/O when opening files */ 293 int c_debug_level; /* level of debug messages to show */ 294 char *c_log_name; /* name of log info file */ 295 char *c_perf_name; /* name of perf info file */ 296 char *c_perf_dir; /* directory for performance info */ 297 FILE *c_log_file; /* file for log info */ 298 FILE *c_perf_file; /* file for performance info */ 299 int c_sleep; /* seconds to sleep between tests */ 300 int c_ignore; /* seconds of I/O to not rate */ 301 long c_target_resp; /* target response time - slowed */ 302 double c_target_sec; /* target response time - in seconds */ 303 int c_target_rate; /* percent of target iops to use */ 304 305 int c_shift; /* sub-LUN skew shift for all tests */ 306 float c_area_count; /* how many area groups on the device */ 307 long c_num_areas; /* number of used areas */ 308 ior_skew_area *c_areas; /* the areas holding our data */ 309 HUGE c_max_area; /* largest area size for skew testing */ 310 HUGE c_area; /* current area size for skew testing */ 311 HUGE c_skew_set_size; /* the size of the device covered by a full set of all areas */ 312 HUGE c_max_dev_size; /* size of the largest active device */ 313 HUGE c_min_dev_size; /* size of the smallest active device */ 314 float c_skew_capacities[ 5 ]; /* capacities for skewed data */ 315 float c_skew_workloads[ 5 ]; /* iops for skewed data */ 316 int c_skew_group_count[ 5 ]; /* number of skew groups in each target range */ 317 ior_skew_list c_skewed[ IOR_SKEW_LISTS + 2 ]; /* our skew lists */ 318 ior_odds_item c_odds_i[ IOR_SKEW_LISTS + 2 ]; /* odds of I/O to each skew list */ 319 ior_odds c_odds; /* odds for I/Os */ 320 321 int c_ndev; /* number of target devices */ 322 int c_vdev; /* number of valid target devices */ 323 int c_adev; /* number of active target devices */ 324 /* note active includes copies */ 325 int c_npat; /* number of defined patterns */ 326 int c_ntest; /* number of defined tests */ 327 char *c_dev_name; /* device file name */ 328 char *c_pat_name; /* pattern file name */ 329 char *c_test_name; /* test file name */ 330 char *c_iops_name; /* iops file name */ 331 ior_device c_devs[ IOR_MAX_DEVICES + 2 ]; /* target device list */ 332 ior_pattern c_pats[ IOR_MAX_PATTERNS + 2 ]; /* available patterns to run */ 333 ior_test c_tests[ IOR_MAX_TESTS + 2 ]; /* the tests that will be run */ 334 335 long c_fid; /* file descriptor */ 336 HUGE c_pos; /* current file position */ 337 HUGE c_start; /* where do we start? */ 338 HUGE c_size; /* how much do we test? */ 339 HUGE c_end; /* end of test area - start + size */ 340 HUGE c_align; /* block count to align on */ 341 HUGE c_blocks_read; /* count of blocks read */ 342 HUGE c_blocks_written; /* count of blocks written */ 343 HUGE c_reads; /* number of reads performed */ 344 HUGE c_writes; /* number of writes performed */ 345 double c_read_time_msecs; /* read perf time in milisecs */ 346 double c_write_time_msecs; /* write perf time in milisecs */ 347 ior_clock c_io_time; /* elapsed time for counted I/Os */ 348 int c_errors; /* # of errors seen this pass */ 349 int c_cur_dev; /* active device */ 350 int c_cur_adev; /* active within count on device */ 351 int c_cur_test; /* test we are running */ 352 int c_cur_pat; /* pattern we are using */ 353 ior_clock c_start_time; /* time we started this test run */ 354 355 /* file parsing records */ 356 char c_l_str[ 256 ]; /* contents of found strings */ 357 double c_l_value; /* values of parsed numbers */ 358 int c_l_line; /* line number being parsed */ 359 char *c_l_name; /* name of file being parsed */ 360 char *c_l_cur_txt; /* text of current line being read */ 361 int c_l_cur_pos; /* location of current read */ 362 char c_l_error[ 256 ]; /* string of error message */ 363 364 BYTE *c_read_buf; /* buffers for the real I/O */ 365 BYTE *c_write_buf; 366 } ior_config; 367 368 extern char msg_buf[]; /* message buffer */ 369 370 /* 371 * functions from ior_file.c 372 */ 373 extern int ior_read_devs( ior_config *cfg ); 374 extern int ior_read_pats( ior_config *cfg ); 375 extern int ior_read_tests( ior_config *cfg ); 376 extern int ior_log_devs( ior_config *cfg ); 377 extern int ior_log_pats( ior_config *cfg ); 378 extern int ior_log_tests( ior_config *cfg ); 379 extern char *ior_size_to_ascii( ior_config *cfg, HUGE t_size ); 380 extern char *ior_time_to_ascii( ior_config *cfg, long t_time ); 381 382 /* 383 * functions from ior_mach.c 384 */ 385 extern int ior_open_dev( ior_config *cfg, int dev ); 386 extern int ior_close_dev( ior_config *cfg, int dev ); 387 extern int ior_read( ior_config *cfg, long io_size, double *io_resp ); 388 extern int ior_write( ior_config *cfg, long io_size, double *io_resp ); 389 extern int ior_seek( ior_config *cfg, HUGE pos ); 390 extern int ior_get_capacity( ior_config *cfg, long dev ); 391 extern HUGE ior_rand( ior_config *cfg ); 392 extern int ior_random_seed( ior_config *cfg, long seed ); 393 extern int ior_randomize( ior_config *cfg ); 394 extern long ior_get_time( ior_config *cfg ); 395 extern int ior_date_string( ior_config *cfg, ior_clock clk, char *str ); 396 extern int ior_sleep( ior_config *cfg, int sec ); 397 extern int ior_sleep_usec( ior_config *cfg, long usec ); 398 extern int ior_set_lock( ior_config *cfg ); 399 extern int ior_clear_lock( ior_config *cfg ); 400 401 /* 402 * functions from ior_test.c 403 */ 404 extern int ior_run_dev_test( ior_config *cfg ); 405 extern int ior_test_prep_std( ior_config *cfg ); 406 extern int ior_test_prep_skew( ior_config *cfg ); 407 extern int ior_run_pat( ior_config *cfg, long pat ); 408 extern int ior_run_skew( ior_config *cfg, long pat ); 409 extern int ior_run_sel_pat( ior_config *cfg, long pat ); 410 extern int ior_io( ior_config *cfg, long io, long io_size, HUGE pos, ior_skew_list *skew ); 411 extern int ior_set_rand_pos( ior_config *cfg, long pat ); 412 413 /* 414 * functions from iorate.c 415 */ 416 extern int ior_read_args( ior_config *cfg, int argc, char **argv ); 417 extern int ior_read_config( ior_config *cfg ); 418 extern int ior_prepare( ior_config *cfg ); 419 extern int ior_run_tests( ior_config *cfg ); 420 extern int ior_cleanup( ior_config *cfg ); 421 extern int ior_usage( ior_config *cfg ); 422 extern int ior_error( ior_config *cfg, char *msg ); 423 extern int ior_warn( ior_config *cfg, char *msg ); 424 extern int ior_msg( ior_config *cfg, char *msg_type, char *msg ); 425 extern int ior_verbose( ior_config *cfg, char *msg ); 426 extern int ior_log( ior_config *cfg, char *msg ); 427 extern int ior_write_log( ior_config *cfg, char *str ); 428 extern char *ior_strdup( ior_config *cfg, char *str ); 429 #define IOR_AREA_HEAD TRUE 430 #define IOR_AREA_TAIL FALSE 431 extern int ior_area( ior_config *cfg, int to_head, ior_skew_area *area, ior_skew_list *list ); 432 extern int ior_odds_pick( ior_config *cfg, ior_odds *odds ); 433 extern int ior_signal_kids( ior_config *cfg, int sig ); 434 extern void ior_signal( int sig ); 435 436 extern int ior_read_iops( ior_config *cfg ); 437 438 extern int ior_parse_prep( ior_config *cfg, char *f_name ); 439 440 extern int yyparse(); 441 extern int ior_debug( ior_config *cfg, char *msg ); 442 extern int ior_debug_l( ior_config *cfg, int level, char *msg ); 443 extern int ior_dev_lock( ior_config *cfg, long dev ); 444 extern int ior_dev_unlock( ior_config *cfg, long dev ); 445 extern int ior_time_usec( ior_config *cfg, long *sec, long *usec ); 446 447 extern int ior_lex_prep( ior_config *cfg); 448 extern int ior_parse_dev_clear( ior_config *cfg ); 449 extern int ior_parse_pat_clear( ior_config *cfg ); 450 extern int ior_parse_test_clear( ior_config *cfg ); 451 extern int ior_lex_done( ior_config *cfg); 452 453 extern int yylex(); 454 455 extern int ior_lex_is_sep( ior_config *cfg, char c ); 456 457 #ifdef IOR_ENGINEERING 458 extern int ior_eng_prep( ior_config *cfg ); 459 extern int ior_eng_pre_test( ior_config *cfg ); 460 extern int ior_eng_test_done( ior_config *cfg ); 461 extern int ior_eng_clean( ior_config *cfg ); 462 extern int ior_eng_read( ior_config *cfg, long io_size, 463 long bytes_trans, double resp_time ); 464 extern int ior_eng_write( ior_config *cfg, long io_size, 465 long bytes_trans, double resp_time ); 466 #endif 467 468 #endif 469 470