1 /* 2 * Disktest 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 20 * Please send e-mail to yardleyb (at) us.ibm.com if you have 21 * questions or comments. 22 * 23 * Project Website: TBD 24 * 25 * $Id: main.h,v 1.5 2008/02/14 08:22:23 subrata_modak Exp $ 26 * 27 */ 28 29 #ifndef _DISKTEST_H 30 #define _DISKTEST_H 31 32 #ifdef WINDOWS 33 #include <windows.h> 34 #include <winioctl.h> 35 #include <io.h> 36 #include <process.h> 37 #include <sys/stat.h> 38 #else 39 #include <pthread.h> 40 #include <sys/types.h> 41 #include <sys/ioctl.h> 42 #include <unistd.h> 43 #endif 44 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <stdarg.h> 48 #include <signal.h> 49 #include <time.h> 50 #include <errno.h> 51 #include "defs.h" 52 53 #define VER_STR "v1.4.2" 54 #define BLKGETSIZE _IO(0x12,96) /* IOCTL for getting the device size */ 55 #define BLKSSZGET _IO(0x12,104) /* ALT IOCTL for getting the device size */ 56 57 #define DEV_NAME_LEN 80 /* max character for target name */ 58 #define MAX_ARG_LEN 160 /* max length of command line arguments for startarg display */ 59 #define HOSTNAME_SIZE 16 /* number of hostname characters used in mark header */ 60 #define BLK_SIZE 512 /* default size of an LBA in bytes */ 61 #define ALIGNSIZE 4096 /* memory alignment size in bytes */ 62 #define DEFAULT_IO_TIMEOUT 120 /* the default number of seconds before IO timeout */ 63 64 /* the new way we align */ 65 #define ALIGN(x, y) (((long long unsigned)x/(long long unsigned)y)*(long long unsigned)y) 66 67 #if __WORDSIZE == 64 68 /* the old way we use to align */ 69 /* #define ALIGN(x, bs) (((OFF_T)x + ((OFF_T)bs - 1)) & ~((OFF_T)bs - 1)) */ 70 #define BUFALIGN(x) (void *) (((unsigned long)x + (OFF_T)(ALIGNSIZE - 1)) & (OFF_T)~(ALIGNSIZE - 1)) 71 #else 72 /* the old way we use to align */ 73 /* #define ALIGN(x, bs) ((x + (bs - 1)) & ~(bs - 1)) */ 74 #define BUFALIGN(x) (void *) (((unsigned long)x + (ALIGNSIZE - 1)) & ~(ALIGNSIZE - 1)) 75 #endif 76 77 #define MASK(x,y) (x & y) 78 79 /* each is a 64b number. offsets are in 8B*offset placement */ 80 #define OFF_RLBA 0 /* offset in memseg of current read LBA */ 81 #define OFF_WLBA 1 /* offset in memseg of current write LBA */ 82 83 #define BMP_OFFSET 2*sizeof(OFF_T) /* bitmap starts here */ 84 85 #define TST_STS(x) (x & 0x1) /* current testing status */ 86 #define SET_STS_PASS(x) (x | 0x01) 87 #define SET_STS_FAIL(x) (x & ~0x01) 88 #define TST_wFST_TIME(x) (x & 0x02) /* first write lba access */ 89 #define SET_wFST_TIME(x) (x | 0x02) 90 #define CLR_wFST_TIME(x) (x & ~0x02) 91 #define TST_rFST_TIME(x) (x & 0x04) /* first read lba access */ 92 #define SET_rFST_TIME(x) (x | 0x04) 93 #define CLR_rFST_TIME(x) (x & ~0x04) 94 #define TST_DIRCTN(x) (x & 0x08) /* lba inc/dec 1 is inc, 0 is dec */ 95 #define DIRCT_INC(x) (x | 0x08) 96 #define DIRCT_DEC(x) (x & ~0x08) 97 #define DIRCT_CNG(x) (x & 0x08) ? (x & ~0x08) : (x | 0x08) 98 #define TST_OPER(x) (short) ((x & 0x10) >> 4) /* last transfer operation (write = 0, read = 1) */ 99 #define SET_OPER_R(x) (x | 0x10) 100 #define SET_OPER_W(x) (x & ~0x10) 101 #define CNG_OPER(x) (x & 0x10) ? (x & ~0x10) : (x | 0x10) 102 103 #define CLD_FLG_CMPR 0x0000000000000001ULL /* will cause readers to compare data read */ 104 #define CLD_FLG_MBLK 0x0000000000000002ULL /* will add header info to first block, fc lun, lba, etc */ 105 #define CLD_FLG_OFFSET 0x0000000000000004ULL /* specifies that an offset up to 2^31 LBAs has been given */ 106 #define CLD_FLG_RTRSIZ 0x0000000000000008ULL /* Ignore weither a block has been written */ 107 108 /* Perforamnce Flags */ 109 #define CLD_FLG_XFERS 0x0000000000000010ULL /* reports # of transfers */ 110 #define CLD_FLG_TPUTS 0x0000000000000020ULL /* reports calculated throughtput */ 111 #define CLD_FLG_RUNT 0x0000000000000040ULL /* reports run time */ 112 #define CLD_FLG_PCYC 0x0000000000000080ULL /* report cycle data */ 113 #define CLD_FLG_PRFTYPS (CLD_FLG_XFERS|CLD_FLG_TPUTS|CLD_FLG_RUNT|CLD_FLG_PCYC) 114 115 /* Seek Flags */ 116 #define CLD_FLG_RANDOM 0x0000000000000100ULL /* child seeks are random */ 117 #define CLD_FLG_LINEAR 0x0000000000000200ULL /* child seeks are linear */ 118 #define CLD_FLG_NTRLVD 0x0000000000000400ULL /* reads and writes are interleaved */ 119 #define CLD_FLG_SKTYPS (CLD_FLG_RANDOM|CLD_FLG_LINEAR) 120 121 #define CLD_FLG_VSIZ 0x0000000000000800ULL /* Volume size is user specified */ 122 123 /* IO Type Flags */ 124 #define CLD_FLG_RAW 0x0000000000001000ULL /* child IO is to a raw/character device */ 125 #define CLD_FLG_BLK 0x0000000000002000ULL /* child IO is to a block device */ 126 #define CLD_FLG_FILE 0x0000000000004000ULL /* child IO is to a file */ 127 #define CLD_FLG_DIRECT 0x0000000000008000ULL /* child IO has direct disk access */ 128 #define CLD_FLG_IOTYPS (CLD_FLG_RAW|CLD_FLG_BLK|CLD_FLG_FILE|CLD_FLG_DIRECT) 129 130 /* Pattern Flags */ 131 #define CLD_FLG_RPTYPE 0x0000000000010000ULL /* random pattern */ 132 #define CLD_FLG_FPTYPE 0x0000000000020000ULL /* fixed pattern */ 133 #define CLD_FLG_CPTYPE 0x0000000000040000ULL /* counting pattern */ 134 #define CLD_FLG_LPTYPE 0x0000000000080000ULL /* lba pattern */ 135 #define CLD_FLG_PTYPS (CLD_FLG_RPTYPE|CLD_FLG_FPTYPE|CLD_FLG_CPTYPE|CLD_FLG_LPTYPE) 136 137 /* Duration Flags */ 138 #define CLD_FLG_TMD 0x0000000000100000ULL /* set if using time */ 139 #define CLD_FLG_SKS 0x0000000000200000ULL /* set if seeks are used */ 140 #define CLD_FLG_CYC 0x0000000000400000ULL /* set if cycles are used */ 141 #define CLD_FLG_DUTY 0x0000000000800000ULL /* set if a duty cycle is used while running */ 142 143 #define CLD_FLG_LBA_RNG 0x0000000001000000ULL /* write multipule read multipule, must define multiple */ 144 #define CLD_FLG_BLK_RNG 0x0000000002000000ULL /* write once read multiple, must define multiple */ 145 #define CLD_FLG_ALLDIE 0x0000000004000000ULL /* will force all children to die on any error if set */ 146 #define CLD_FLG_DUMP 0x0000000008000000ULL /* will dump formatted data */ 147 148 #define CLD_FLG_LUNU 0x0000000010000000ULL /* seek start/end and then start/end */ 149 #define CLD_FLG_LUND 0x0000000020000000ULL /* seek start/end and then end/start */ 150 #define CLD_FLG_W 0x0000000040000000ULL /* there are child writers */ 151 #define CLD_FLG_R 0x0000000080000000ULL /* there are child readers */ 152 153 #define CLD_FLG_FSLIST 0x0000000100000000ULL /* the filespec is a list of targets */ 154 #define CLD_FLG_HBEAT 0x0000000200000000ULL /* if performance heartbeat is being used */ 155 #define CLD_FLG_WFSYNC 0x0000000400000000ULL /* do an fsync on write for file IO */ 156 #define FLAG_NOT_DEFINED 0x0000000800000000ULL /* NOT DEFINED */ 157 158 #define CLD_FLG_WRITE_ONCE 0x0000001000000000ULL /* only write once to each LBA */ 159 #define CLD_FLG_ERR_REREAD 0x0000002000000000ULL /* On miscompare, reread the miscompare transfer */ 160 #define CLD_FLG_LBA_SYNC 0x0000004000000000ULL /* LBA syncronizion */ 161 #define CLD_FLG_IO_SERIAL 0x0000008000000000ULL /* serialize IO at the IO operation level */ 162 163 #define CLD_FLG_MRK_LBA 0x0000010000000000ULL /* enable adding LBA to mark data */ 164 #define CLD_FLG_MRK_PASS 0x0000020000000000ULL /* enable adding pass count to mark data */ 165 #define CLD_FLG_MRK_TIME 0x0000040000000000ULL /* enable adding start time to mark data */ 166 #define CLD_FLG_MRK_SEED 0x0000080000000000ULL /* enable adding seed to mark data */ 167 #define CLD_FLG_MRK_HOST 0x0000100000000000ULL /* enable adding hostname to mark data */ 168 #define CLD_FLG_MRK_TARGET 0x0000200000000000ULL /* enable adding target name to mark data */ 169 #define CLD_FLG_MRK_ALL (CLD_FLG_MRK_LBA|CLD_FLG_MRK_PASS|CLD_FLG_MRK_TIME|CLD_FLG_MRK_SEED|CLD_FLG_MRK_HOST|CLD_FLG_MRK_TARGET) 170 171 #define CLD_FLG_ALT_MARK 0x0000400000000000ULL /* override time marker, with data in alt_mark, in mark header */ 172 #define CLD_FLG_ERR_MARK 0x0000800000000000ULL /* On error, write a special MARKER to LBA 0 on the target */ 173 174 #define CLD_FLG_TMO_ERROR 0x0001000000000000ULL /* make an IO TIMEOUT warning, fail the IO test */ 175 #define CLD_FLG_UNIQ_WRT 0x0002000000000000ULL /* garentees that every write is unique */ 176 177 /* startup defaults */ 178 #define TRSIZ 1 /* default transfer size in blocks */ 179 #define VSIZ 2000 /* default volume capacity in LBAs */ 180 #define SEEKS 1000 /* default seeks */ 181 #define KIDS 4 /* default number of children */ 182 183 #ifdef WINDOWS 184 typedef HANDLE hThread_t; 185 #else 186 typedef pthread_t hThread_t; 187 #endif 188 189 typedef struct thread_struct { 190 hThread_t hThread; 191 BOOL bCanBeJoined; 192 struct thread_struct *next; /* pointer to next thread */ 193 } thread_struct_t; 194 195 typedef struct stats { 196 OFF_T wcount; 197 OFF_T rcount; 198 OFF_T wbytes; 199 OFF_T rbytes; 200 time_t wtime; 201 time_t rtime; 202 } stats_t; 203 204 typedef struct child_args { 205 char device[DEV_NAME_LEN]; /* device name */ 206 char argstr[MAX_ARG_LEN]; /* human readable argument string /w assumtions */ 207 OFF_T vsiz; /* volume size in blocks */ 208 unsigned long ltrsiz; /* low bound of transfer size in blocks */ 209 unsigned long htrsiz; /* high bound of transfer size in blocks */ 210 long offset; /* the lba offset to shift IO alignment by */ 211 OFF_T pattern; /* pattern data */ 212 time_t run_time; /* run time in seconds */ 213 OFF_T seeks; /* number of seeks */ 214 unsigned long cycles; /* number of cycles */ 215 OFF_T start_blk; /* starting transfer block */ 216 OFF_T stop_blk; /* ending transfer block */ 217 OFF_T start_lba; /* starting LBA */ 218 OFF_T stop_lba; /* ending LBA */ 219 unsigned int retries; /* number of retries */ 220 time_t hbeat; /* Statistics will be reported every hbeats seconds */ 221 unsigned long long flags; /* common flags that a child uses */ 222 unsigned long rcount; /* number of reads a child should perform, 0 is unbound */ 223 unsigned long wcount; /* number of writes a child should perform, 0 is unbound */ 224 short rperc; /* percent of IO that should be reads */ 225 short wperc; /* percent of IO that should be write */ 226 unsigned short t_kids; /* total children, max is 64k */ 227 unsigned int cmp_lng; /* how much of the data should be compared */ 228 OFF_T test_state; /* current test state */ 229 unsigned int seed; /* test seed */ 230 pid_t pid; /* the process_id used for this environment */ 231 OFF_T alt_mark; /* alternate marker the start time */ 232 unsigned long delayTimeMin; /* the minimum time (msec) to delay on each IO */ 233 unsigned long delayTimeMax; /* the maximum time (msec) to delay on each IO */ 234 time_t ioTimeout; /* the time (sec) before failure do to possible hung IO */ 235 unsigned long sync_interval;/* number of write IOs before issuing a sync */ 236 long retry_delay; /* number of msec to wait before retrying an IO */ 237 } child_args_t; 238 239 typedef struct mutexs { 240 #ifdef WINDOWS 241 HANDLE MutexACTION; /* mutex for the entire target device */ 242 HANDLE MutexIO; /* mutex for the IO to the device */ 243 #else 244 pthread_mutex_t MutexACTION; /* mutex for the entire target device */ 245 pthread_mutex_t MutexIO; /* mutex for the IO to the device */ 246 #endif 247 } mutexs_t; 248 249 typedef struct test_env { 250 void *shared_mem; /* global pointer to shared memory */ 251 unsigned char *data_buffer; /* global data buffer */ 252 size_t bmp_siz; /* size of bitmask */ 253 BOOL bContinue; /* global that when set to false will force exit for this environment */ 254 OFF_T pass_count; /* pass counters */ 255 stats_t hbeat_stats; /* per heartbeat statistics */ 256 stats_t cycle_stats; /* per cycle statistics */ 257 stats_t global_stats; /* per env statistics */ 258 OFF_T rcount; /* number of read IO operations */ 259 OFF_T wcount; /* number of write IO operations */ 260 unsigned short kids; /* number of test child processes */ 261 thread_struct_t *pThreads; /* List of child test processes */ 262 time_t start_time; /* overall start time of test */ 263 time_t end_time; /* overall end time of test */ 264 action_t lastAction; /* when interleaving tests, tells the threads whcih action was last */ 265 action_t *action_list; /* pointer to list of actions that are currently in use */ 266 int action_list_entry; /* where in the action_list we are */ 267 mutexs_t mutexs; 268 } test_env_t; 269 270 typedef struct test_ll { 271 test_env_t *env; /* pointer to the environment structure */ 272 child_args_t *args; /* pointer to the argument structure */ 273 hThread_t hThread; 274 struct test_ll *next; /* pointer to the next test */ 275 } test_ll_t; 276 277 #endif /* _DISKTEST_H */ 278