1 5184 ek110237 /* 2 5184 ek110237 * CDDL HEADER START 3 5184 ek110237 * 4 5184 ek110237 * The contents of this file are subject to the terms of the 5 5184 ek110237 * Common Development and Distribution License (the "License"). 6 5184 ek110237 * You may not use this file except in compliance with the License. 7 5184 ek110237 * 8 5184 ek110237 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 5184 ek110237 * or http://www.opensolaris.org/os/licensing. 10 5184 ek110237 * See the License for the specific language governing permissions 11 5184 ek110237 * and limitations under the License. 12 5184 ek110237 * 13 5184 ek110237 * When distributing Covered Code, include this CDDL HEADER in each 14 5184 ek110237 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 5184 ek110237 * If applicable, add the following below this CDDL HEADER, with the 16 5184 ek110237 * fields enclosed by brackets "[]" replaced with your own identifying 17 5184 ek110237 * information: Portions Copyright [yyyy] [name of copyright owner] 18 5184 ek110237 * 19 5184 ek110237 * CDDL HEADER END 20 5184 ek110237 */ 21 5184 ek110237 /* 22 9801 Andrew * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 5184 ek110237 * Use is subject to license terms. 24 6613 ek110237 * 25 6613 ek110237 * Portions Copyright 2008 Denis Cheng 26 5184 ek110237 */ 27 5184 ek110237 28 5184 ek110237 #include <stdlib.h> 29 5184 ek110237 #include <stdio.h> 30 5184 ek110237 #include <string.h> 31 5184 ek110237 #include <errno.h> 32 5184 ek110237 33 6613 ek110237 #include "filebench.h" 34 5184 ek110237 #include "vars.h" 35 5184 ek110237 #include "misc.h" 36 5184 ek110237 #include "utils.h" 37 5184 ek110237 #include "stats.h" 38 5184 ek110237 #include "eventgen.h" 39 6212 aw148015 #include "fb_random.h" 40 5184 ek110237 41 5184 ek110237 static var_t *var_find_dynamic(char *name); 42 9801 Andrew static boolean_t var_get_bool(var_t *var); 43 9801 Andrew static fbint_t var_get_int(var_t *var); 44 9801 Andrew static double var_get_dbl(var_t *var); 45 5184 ek110237 46 5184 ek110237 /* 47 6212 aw148015 * The filebench variables system has attribute value descriptors (avd_t) 48 6212 aw148015 * where an avd contains a boolean, integer, double, string, random 49 6212 aw148015 * distribution object ptr, boolean ptr, integer ptr, double ptr, 50 6212 aw148015 * string ptr, or variable ptr. The system also has the variables 51 6212 aw148015 * themselves, (var_t), which are named, typed entities which can be 52 6212 aw148015 * allocated, selected and changed using the "set" command and used in 53 6212 aw148015 * attribute assignments. The variables contain either a boolean, an 54 6212 aw148015 * integer, a double, a string or pointer to an associated random 55 6212 aw148015 * distribution object. Both avd_t and var_t entities are allocated 56 5184 ek110237 * from interprocess shared memory space. 57 5184 ek110237 * 58 6212 aw148015 * The attribute descriptors implement delayed binding to variable values, 59 6212 aw148015 * which is necessary because the values of variables may be changed 60 6212 aw148015 * between the time the workload file is loaded and it is actually run, 61 6212 aw148015 * either by further "set" commands in the file or from the command line 62 6212 aw148015 * interface. For random variables, they actually point to the random 63 6212 aw148015 * distribution object, allowing FileBench to invoke the appropriate 64 6212 aw148015 * random distribution function on each access to the attribute. However, 65 6212 aw148015 * for static attributes, the value is just loaded in the descriptor 66 6212 aw148015 * directly, avoiding the need to allocate a variable to hold the static 67 6212 aw148015 * value. 68 6212 aw148015 * 69 5184 ek110237 * The routines in this module are used to allocate, locate, and 70 6212 aw148015 * manipulate the attribute descriptors, and vars. Routines are 71 6212 aw148015 * also included to convert between the component strings, doubles 72 6212 aw148015 * and integers of vars, and said components of avd_t. 73 5184 ek110237 */ 74 6550 aw148015 75 5184 ek110237 76 5184 ek110237 /* 77 6212 aw148015 * returns a pointer to a string indicating the type of data contained 78 6212 aw148015 * in the supplied attribute variable descriptor. 79 5184 ek110237 */ 80 6212 aw148015 static char * 81 6212 aw148015 avd_get_type_string(avd_t avd) 82 5184 ek110237 { 83 6212 aw148015 switch (avd->avd_type) { 84 6212 aw148015 case AVD_INVALID: 85 6212 aw148015 return ("uninitialized"); 86 5184 ek110237 87 6212 aw148015 case AVD_VAL_BOOL: 88 6212 aw148015 return ("boolean value"); 89 6212 aw148015 90 6212 aw148015 case AVD_VARVAL_BOOL: 91 6212 aw148015 return ("points to boolean in var_t"); 92 6212 aw148015 93 6212 aw148015 case AVD_VAL_INT: 94 6212 aw148015 return ("integer value"); 95 6212 aw148015 96 6212 aw148015 case AVD_VARVAL_INT: 97 6212 aw148015 return ("points to integer in var_t"); 98 6212 aw148015 99 6212 aw148015 case AVD_VAL_STR: 100 6212 aw148015 return ("string"); 101 6212 aw148015 102 6212 aw148015 case AVD_VARVAL_STR: 103 6212 aw148015 return ("points to string in var_t"); 104 6212 aw148015 105 6212 aw148015 case AVD_VAL_DBL: 106 6212 aw148015 return ("double float value"); 107 6212 aw148015 108 6212 aw148015 case AVD_VARVAL_DBL: 109 6212 aw148015 return ("points to double float in var_t"); 110 6212 aw148015 111 6212 aw148015 case AVD_IND_VAR: 112 6212 aw148015 return ("points to a var_t"); 113 6212 aw148015 114 6212 aw148015 case AVD_IND_RANDVAR: 115 6212 aw148015 return ("points to var_t's random distribution object"); 116 6212 aw148015 117 6212 aw148015 default: 118 6212 aw148015 return ("illegal avd type"); 119 6212 aw148015 } 120 5184 ek110237 } 121 5184 ek110237 122 5184 ek110237 /* 123 6212 aw148015 * returns a pointer to a string indicating the type of data contained 124 6212 aw148015 * in the supplied variable. 125 5184 ek110237 */ 126 6212 aw148015 static char * 127 6212 aw148015 var_get_type_string(var_t *ivp) 128 5184 ek110237 { 129 6212 aw148015 switch (ivp->var_type & VAR_TYPE_SET_MASK) { 130 6212 aw148015 case VAR_TYPE_BOOL_SET: 131 6212 aw148015 return ("boolean"); 132 5184 ek110237 133 6212 aw148015 case VAR_TYPE_INT_SET: 134 6212 aw148015 return ("integer"); 135 6212 aw148015 136 6212 aw148015 case VAR_TYPE_STR_SET: 137 6212 aw148015 return ("string"); 138 6212 aw148015 139 6212 aw148015 case VAR_TYPE_DBL_SET: 140 6212 aw148015 return ("double float"); 141 6212 aw148015 142 6212 aw148015 case VAR_TYPE_RAND_SET: 143 6212 aw148015 return ("random"); 144 6212 aw148015 145 6212 aw148015 default: 146 6212 aw148015 return ("empty"); 147 6212 aw148015 } 148 6212 aw148015 } 149 6212 aw148015 150 6212 aw148015 /* 151 6212 aw148015 * Returns the fbint_t pointed to by the supplied avd_t "avd". 152 6212 aw148015 */ 153 6212 aw148015 fbint_t 154 6212 aw148015 avd_get_int(avd_t avd) 155 6212 aw148015 { 156 6212 aw148015 randdist_t *rndp; 157 6212 aw148015 158 6212 aw148015 if (avd == NULL) 159 6212 aw148015 return (0); 160 6212 aw148015 161 6212 aw148015 switch (avd->avd_type) { 162 6212 aw148015 case AVD_VAL_INT: 163 6212 aw148015 return (avd->avd_val.intval); 164 6212 aw148015 165 6212 aw148015 case AVD_VARVAL_INT: 166 6212 aw148015 if (avd->avd_val.intptr) 167 6212 aw148015 return (*(avd->avd_val.intptr)); 168 6212 aw148015 else 169 6212 aw148015 return (0); 170 6212 aw148015 171 6212 aw148015 case AVD_IND_VAR: 172 9801 Andrew return (var_get_int(avd->avd_val.varptr)); 173 6212 aw148015 174 6212 aw148015 case AVD_IND_RANDVAR: 175 6212 aw148015 if ((rndp = avd->avd_val.randptr) == NULL) 176 6212 aw148015 return (0); 177 6212 aw148015 else 178 6212 aw148015 return ((fbint_t)rndp->rnd_get(rndp)); 179 6212 aw148015 180 6212 aw148015 default: 181 6212 aw148015 filebench_log(LOG_ERROR, 182 6212 aw148015 "Attempt to get integer from %s avd", 183 6212 aw148015 avd_get_type_string(avd)); 184 6212 aw148015 return (0); 185 6212 aw148015 } 186 6212 aw148015 } 187 6212 aw148015 188 6212 aw148015 /* 189 6212 aw148015 * Returns the floating point value of a variable pointed to by the 190 6212 aw148015 * supplied avd_t "avd". Intended to get the actual (double) value 191 6212 aw148015 * supplied by the random variable. 192 6212 aw148015 */ 193 6212 aw148015 double 194 6212 aw148015 avd_get_dbl(avd_t avd) 195 6212 aw148015 { 196 6212 aw148015 randdist_t *rndp; 197 6212 aw148015 198 6212 aw148015 if (avd == NULL) 199 6212 aw148015 return (0.0); 200 6212 aw148015 201 6212 aw148015 switch (avd->avd_type) { 202 6212 aw148015 case AVD_VAL_INT: 203 6212 aw148015 return ((double)avd->avd_val.intval); 204 6212 aw148015 205 6212 aw148015 case AVD_VAL_DBL: 206 6212 aw148015 return (avd->avd_val.dblval); 207 6212 aw148015 208 6212 aw148015 case AVD_VARVAL_INT: 209 6212 aw148015 if (avd->avd_val.intptr) 210 6212 aw148015 return ((double)(*(avd->avd_val.intptr))); 211 6212 aw148015 else 212 6212 aw148015 return (0.0); 213 6212 aw148015 214 6212 aw148015 case AVD_VARVAL_DBL: 215 6212 aw148015 if (avd->avd_val.dblptr) 216 6212 aw148015 return (*(avd->avd_val.dblptr)); 217 6212 aw148015 else 218 6212 aw148015 return (0.0); 219 6212 aw148015 220 6212 aw148015 case AVD_IND_VAR: 221 9801 Andrew return (var_get_dbl(avd->avd_val.varptr)); 222 6212 aw148015 223 6212 aw148015 case AVD_IND_RANDVAR: 224 6212 aw148015 if ((rndp = avd->avd_val.randptr) == NULL) { 225 6212 aw148015 return (0.0); 226 6212 aw148015 } else 227 6212 aw148015 return (rndp->rnd_get(rndp)); 228 6212 aw148015 229 6212 aw148015 default: 230 6212 aw148015 filebench_log(LOG_ERROR, 231 6212 aw148015 "Attempt to get floating point from %s avd", 232 6212 aw148015 avd_get_type_string(avd)); 233 6212 aw148015 return (0.0); 234 6212 aw148015 } 235 6212 aw148015 } 236 6212 aw148015 237 6212 aw148015 /* 238 6212 aw148015 * Returns the boolean pointed to by the supplied avd_t "avd". 239 6212 aw148015 */ 240 6212 aw148015 boolean_t 241 6212 aw148015 avd_get_bool(avd_t avd) 242 6212 aw148015 { 243 6212 aw148015 if (avd == NULL) 244 6212 aw148015 return (0); 245 6212 aw148015 246 6212 aw148015 switch (avd->avd_type) { 247 6212 aw148015 case AVD_VAL_BOOL: 248 6212 aw148015 return (avd->avd_val.boolval); 249 6212 aw148015 250 6212 aw148015 case AVD_VARVAL_BOOL: 251 6212 aw148015 if (avd->avd_val.boolptr) 252 6212 aw148015 return (*(avd->avd_val.boolptr)); 253 6212 aw148015 else 254 6212 aw148015 return (FALSE); 255 6212 aw148015 256 6212 aw148015 /* for backwards compatibility with old workloads */ 257 6212 aw148015 case AVD_VAL_INT: 258 6212 aw148015 if (avd->avd_val.intval != 0) 259 6212 aw148015 return (TRUE); 260 6212 aw148015 else 261 6212 aw148015 return (FALSE); 262 6212 aw148015 263 6212 aw148015 case AVD_VARVAL_INT: 264 6212 aw148015 if (avd->avd_val.intptr) 265 6212 aw148015 if (*(avd->avd_val.intptr) != 0) 266 6212 aw148015 return (TRUE); 267 6212 aw148015 268 6212 aw148015 return (FALSE); 269 6212 aw148015 270 6212 aw148015 case AVD_IND_VAR: 271 9801 Andrew return (var_get_bool(avd->avd_val.varptr)); 272 6212 aw148015 273 6212 aw148015 default: 274 6212 aw148015 filebench_log(LOG_ERROR, 275 6212 aw148015 "Attempt to get boolean from %s avd", 276 6212 aw148015 avd_get_type_string(avd)); 277 6212 aw148015 return (FALSE); 278 6212 aw148015 } 279 6212 aw148015 } 280 6212 aw148015 281 6212 aw148015 /* 282 6212 aw148015 * Returns the string pointed to by the supplied avd_t "avd". 283 6212 aw148015 */ 284 6212 aw148015 char * 285 6212 aw148015 avd_get_str(avd_t avd) 286 6212 aw148015 { 287 6212 aw148015 var_t *ivp; 288 6212 aw148015 289 6212 aw148015 if (avd == NULL) 290 6212 aw148015 return (NULL); 291 6212 aw148015 292 6212 aw148015 switch (avd->avd_type) { 293 6212 aw148015 case AVD_VAL_STR: 294 6212 aw148015 return (avd->avd_val.strval); 295 6212 aw148015 296 6212 aw148015 case AVD_VARVAL_STR: 297 6212 aw148015 if (avd->avd_val.strptr) 298 6212 aw148015 return (*avd->avd_val.strptr); 299 6212 aw148015 else 300 6212 aw148015 return (NULL); 301 6212 aw148015 302 6212 aw148015 case AVD_IND_VAR: 303 6212 aw148015 ivp = avd->avd_val.varptr; 304 6212 aw148015 305 6212 aw148015 if (ivp && VAR_HAS_STRING(ivp)) 306 6212 aw148015 return (ivp->var_val.string); 307 6212 aw148015 308 6212 aw148015 filebench_log(LOG_ERROR, 309 6212 aw148015 "Attempt to get string from %s var $%s", 310 6212 aw148015 var_get_type_string(ivp), ivp->var_name); 311 6212 aw148015 return (NULL); 312 6212 aw148015 313 6212 aw148015 default: 314 6212 aw148015 filebench_log(LOG_ERROR, 315 6212 aw148015 "Attempt to get string from %s avd", 316 6212 aw148015 avd_get_type_string(avd)); 317 5184 ek110237 return (NULL); 318 5184 ek110237 } 319 6212 aw148015 } 320 5184 ek110237 321 6212 aw148015 /* 322 6212 aw148015 * Allocates a avd_t from ipc memory space. 323 6212 aw148015 * logs an error and returns NULL on failure. 324 6212 aw148015 */ 325 6212 aw148015 static avd_t 326 6212 aw148015 avd_alloc_cmn(void) 327 6212 aw148015 { 328 6212 aw148015 avd_t rtn; 329 5184 ek110237 330 6212 aw148015 if ((rtn = (avd_t)ipc_malloc(FILEBENCH_AVD)) == NULL) 331 6212 aw148015 filebench_log(LOG_ERROR, "Avd alloc failed"); 332 5184 ek110237 333 5184 ek110237 return (rtn); 334 5184 ek110237 } 335 5184 ek110237 336 5184 ek110237 /* 337 6212 aw148015 * pre-loads the allocated avd_t with the boolean_t "bool". 338 6212 aw148015 * Returns the avd_t on success, NULL on failure. 339 5184 ek110237 */ 340 6212 aw148015 avd_t 341 6212 aw148015 avd_bool_alloc(boolean_t bool) 342 5184 ek110237 { 343 6212 aw148015 avd_t avd; 344 5184 ek110237 345 6212 aw148015 if ((avd = avd_alloc_cmn()) == NULL) 346 6212 aw148015 return (NULL); 347 6212 aw148015 348 6212 aw148015 avd->avd_type = AVD_VAL_BOOL; 349 6212 aw148015 avd->avd_val.boolval = bool; 350 6212 aw148015 351 6212 aw148015 filebench_log(LOG_DEBUG_IMPL, "Alloc boolean %d", bool); 352 6212 aw148015 353 6212 aw148015 return (avd); 354 6212 aw148015 } 355 6212 aw148015 356 6212 aw148015 /* 357 6212 aw148015 * pre-loads the allocated avd_t with the fbint_t "integer". 358 6212 aw148015 * Returns the avd_t on success, NULL on failure. 359 6212 aw148015 */ 360 6212 aw148015 avd_t 361 6212 aw148015 avd_int_alloc(fbint_t integer) 362 6212 aw148015 { 363 6212 aw148015 avd_t avd; 364 6212 aw148015 365 6212 aw148015 if ((avd = avd_alloc_cmn()) == NULL) 366 6212 aw148015 return (NULL); 367 6212 aw148015 368 6212 aw148015 avd->avd_type = AVD_VAL_INT; 369 6212 aw148015 avd->avd_val.intval = integer; 370 6212 aw148015 371 6286 aw148015 filebench_log(LOG_DEBUG_IMPL, "Alloc integer %llu", 372 6286 aw148015 (u_longlong_t)integer); 373 6212 aw148015 374 6212 aw148015 return (avd); 375 6212 aw148015 } 376 6212 aw148015 377 6212 aw148015 /* 378 6212 aw148015 * Gets a avd_t and points it to the var that 379 6212 aw148015 * it will eventually be filled from 380 6212 aw148015 */ 381 6212 aw148015 static avd_t 382 6212 aw148015 avd_alloc_var_ptr(var_t *var) 383 6212 aw148015 { 384 6212 aw148015 avd_t avd; 385 6212 aw148015 386 6212 aw148015 if (var == NULL) 387 6212 aw148015 return (NULL); 388 6212 aw148015 389 6212 aw148015 if ((avd = avd_alloc_cmn()) == NULL) 390 6212 aw148015 return (NULL); 391 6212 aw148015 392 6212 aw148015 switch (var->var_type & VAR_TYPE_SET_MASK) { 393 6212 aw148015 case VAR_TYPE_BOOL_SET: 394 6212 aw148015 avd->avd_type = AVD_VARVAL_BOOL; 395 6212 aw148015 avd->avd_val.boolptr = (&var->var_val.boolean); 396 6212 aw148015 break; 397 6212 aw148015 398 6212 aw148015 case VAR_TYPE_INT_SET: 399 6212 aw148015 avd->avd_type = AVD_VARVAL_INT; 400 6212 aw148015 avd->avd_val.intptr = (&var->var_val.integer); 401 6212 aw148015 break; 402 6212 aw148015 403 6212 aw148015 case VAR_TYPE_STR_SET: 404 6212 aw148015 avd->avd_type = AVD_VARVAL_STR; 405 6212 aw148015 avd->avd_val.strptr = &(var->var_val.string); 406 6212 aw148015 break; 407 6212 aw148015 408 6212 aw148015 case VAR_TYPE_DBL_SET: 409 6212 aw148015 avd->avd_type = AVD_VARVAL_DBL; 410 6212 aw148015 avd->avd_val.dblptr = &(var->var_val.dbl_flt); 411 6212 aw148015 break; 412 6212 aw148015 413 6212 aw148015 case VAR_TYPE_RAND_SET: 414 6212 aw148015 avd->avd_type = AVD_IND_RANDVAR; 415 6212 aw148015 avd->avd_val.randptr = var->var_val.randptr; 416 6212 aw148015 break; 417 6212 aw148015 418 6550 aw148015 case VAR_TYPE_INDVAR_SET: 419 6550 aw148015 avd->avd_type = AVD_IND_VAR; 420 9801 Andrew if ((var->var_type & VAR_INDVAR_MASK) == VAR_IND_ASSIGN) 421 9801 Andrew avd->avd_val.varptr = var->var_varptr1; 422 9801 Andrew else 423 9801 Andrew avd->avd_val.varptr = var; 424 9801 Andrew 425 6550 aw148015 break; 426 6550 aw148015 427 6212 aw148015 default: 428 6212 aw148015 avd->avd_type = AVD_IND_VAR; 429 6212 aw148015 avd->avd_val.varptr = var; 430 6212 aw148015 break; 431 6212 aw148015 } 432 6212 aw148015 return (avd); 433 6212 aw148015 } 434 6212 aw148015 435 6212 aw148015 /* 436 6212 aw148015 * Gets a avd_t, then allocates and initializes a piece of 437 6212 aw148015 * shared string memory, putting the pointer to it into the just 438 6212 aw148015 * allocated string pointer location. The routine returns a pointer 439 6212 aw148015 * to the string pointer location or returns NULL on error. 440 6212 aw148015 */ 441 6212 aw148015 avd_t 442 6212 aw148015 avd_str_alloc(char *string) 443 6212 aw148015 { 444 6212 aw148015 avd_t avd; 445 6212 aw148015 446 6212 aw148015 if (string == NULL) { 447 6212 aw148015 filebench_log(LOG_ERROR, "No string supplied\n"); 448 5184 ek110237 return (NULL); 449 5184 ek110237 } 450 5184 ek110237 451 6212 aw148015 if ((avd = avd_alloc_cmn()) == NULL) 452 6212 aw148015 return (NULL); 453 6212 aw148015 454 6212 aw148015 avd->avd_type = AVD_VAL_STR; 455 6212 aw148015 avd->avd_val.strval = ipc_stralloc(string); 456 5184 ek110237 457 5184 ek110237 filebench_log(LOG_DEBUG_IMPL, 458 5184 ek110237 "Alloc string %s ptr %zx", 459 6212 aw148015 string, avd); 460 5184 ek110237 461 6212 aw148015 return (avd); 462 5184 ek110237 } 463 5184 ek110237 464 5184 ek110237 /* 465 5184 ek110237 * Allocates a var (var_t) from interprocess shared memory. 466 5184 ek110237 * Places the allocated var on the end of the globally shared 467 6550 aw148015 * shm_var_list. Finally, the routine allocates a string containing 468 5184 ek110237 * a copy of the supplied "name" string. If any allocations 469 5184 ek110237 * fails, returns NULL, otherwise it returns a pointer to the 470 5184 ek110237 * newly allocated var. 471 5184 ek110237 */ 472 5184 ek110237 static var_t * 473 6212 aw148015 var_alloc_cmn(char *name, int var_type) 474 5184 ek110237 { 475 6212 aw148015 var_t **var_listp; 476 5184 ek110237 var_t *var = NULL; 477 5184 ek110237 var_t *prev = NULL; 478 5184 ek110237 var_t *newvar; 479 5184 ek110237 480 5184 ek110237 if ((newvar = (var_t *)ipc_malloc(FILEBENCH_VARIABLE)) == NULL) { 481 5184 ek110237 filebench_log(LOG_ERROR, "Out of memory for variables"); 482 5184 ek110237 return (NULL); 483 5184 ek110237 } 484 5184 ek110237 (void) memset(newvar, 0, sizeof (newvar)); 485 6212 aw148015 newvar->var_type = var_type; 486 5184 ek110237 487 5184 ek110237 if ((newvar->var_name = ipc_stralloc(name)) == NULL) { 488 5184 ek110237 filebench_log(LOG_ERROR, "Out of memory for variables"); 489 5184 ek110237 return (NULL); 490 5184 ek110237 } 491 5184 ek110237 492 6212 aw148015 switch (var_type & VAR_TYPE_MASK) { 493 6212 aw148015 case VAR_TYPE_RANDOM: 494 6212 aw148015 case VAR_TYPE_GLOBAL: 495 6391 aw148015 var_listp = &filebench_shm->shm_var_list; 496 6212 aw148015 break; 497 6212 aw148015 498 6212 aw148015 case VAR_TYPE_DYNAMIC: 499 6391 aw148015 var_listp = &filebench_shm->shm_var_dyn_list; 500 6212 aw148015 break; 501 6212 aw148015 502 6550 aw148015 case VAR_TYPE_LOCAL: 503 6550 aw148015 /* place on head of shared local list */ 504 6550 aw148015 newvar->var_next = filebench_shm->shm_var_loc_list; 505 6550 aw148015 filebench_shm->shm_var_loc_list = newvar; 506 6550 aw148015 return (newvar); 507 6550 aw148015 508 6212 aw148015 default: 509 6391 aw148015 var_listp = &filebench_shm->shm_var_list; 510 6212 aw148015 break; 511 6212 aw148015 } 512 6212 aw148015 513 6212 aw148015 /* add to the end of list */ 514 6212 aw148015 for (var = *var_listp; var != NULL; var = var->var_next) 515 6212 aw148015 prev = var; /* Find end of list */ 516 6212 aw148015 if (prev != NULL) 517 6212 aw148015 prev->var_next = newvar; 518 6212 aw148015 else 519 6212 aw148015 *var_listp = newvar; 520 6212 aw148015 521 5184 ek110237 return (newvar); 522 6212 aw148015 } 523 6212 aw148015 524 6212 aw148015 /* 525 6550 aw148015 * Allocates a var (var_t) from interprocess shared memory after 526 6550 aw148015 * first adjusting the name to elminate the leading $. Places the 527 6550 aw148015 * allocated var temporarily on the end of the globally 528 6550 aw148015 * shared var_loc_list. If the allocation fails, returns NULL, 529 6550 aw148015 * otherwise it returns a pointer to the newly allocated var. 530 6550 aw148015 */ 531 6550 aw148015 var_t * 532 6550 aw148015 var_lvar_alloc_local(char *name) 533 6550 aw148015 { 534 6550 aw148015 if (name[0] == '$') 535 6550 aw148015 name += 1; 536 6550 aw148015 537 6550 aw148015 return (var_alloc_cmn(name, VAR_TYPE_LOCAL)); 538 6550 aw148015 } 539 6550 aw148015 540 6550 aw148015 /* 541 6212 aw148015 * Allocates a var (var_t) from interprocess shared memory and 542 6212 aw148015 * places the allocated var on the end of the globally shared 543 6550 aw148015 * shm_var_list. If the allocation fails, returns NULL, otherwise 544 6212 aw148015 * it returns a pointer to the newly allocated var. 545 6212 aw148015 */ 546 6212 aw148015 static var_t * 547 6212 aw148015 var_alloc(char *name) 548 6212 aw148015 { 549 6212 aw148015 return (var_alloc_cmn(name, VAR_TYPE_GLOBAL)); 550 5184 ek110237 } 551 5184 ek110237 552 5184 ek110237 /* 553 5184 ek110237 * Allocates a var (var_t) from interprocess shared memory. 554 5184 ek110237 * Places the allocated var on the end of the globally shared 555 6550 aw148015 * shm_var_dyn_list. If the allocation fails, returns NULL, otherwise 556 6212 aw148015 * it returns a pointer to the newly allocated var. 557 5184 ek110237 */ 558 5184 ek110237 static var_t * 559 5184 ek110237 var_alloc_dynamic(char *name) 560 5184 ek110237 { 561 6212 aw148015 return (var_alloc_cmn(name, VAR_TYPE_DYNAMIC)); 562 5184 ek110237 } 563 5184 ek110237 564 5184 ek110237 /* 565 6550 aw148015 * Searches for var_t with name "name" in the shm_var_loc_list, 566 6550 aw148015 * then, if not found, in the global shm_var_list. If a matching 567 6550 aw148015 * local or global var is found, returns a pointer to the var_t, 568 6550 aw148015 * otherwise returns NULL. 569 5184 ek110237 */ 570 5184 ek110237 static var_t * 571 5184 ek110237 var_find(char *name) 572 5184 ek110237 { 573 5184 ek110237 var_t *var; 574 6550 aw148015 575 6550 aw148015 for (var = filebench_shm->shm_var_loc_list; var != NULL; 576 6550 aw148015 var = var->var_next) { 577 6550 aw148015 if (strcmp(var->var_name, name) == 0) 578 6550 aw148015 return (var); 579 6550 aw148015 } 580 5184 ek110237 581 6391 aw148015 for (var = filebench_shm->shm_var_list; var != NULL; 582 6391 aw148015 var = var->var_next) { 583 5184 ek110237 if (strcmp(var->var_name, name) == 0) 584 5184 ek110237 return (var); 585 5184 ek110237 } 586 5184 ek110237 587 5184 ek110237 return (NULL); 588 6550 aw148015 } 589 6550 aw148015 590 6550 aw148015 /* 591 6550 aw148015 * Searches for var_t with name "name" in the supplied shm_var_list. 592 6550 aw148015 * If not found there, checks the global list. If still 593 6550 aw148015 * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t. 594 6550 aw148015 */ 595 6550 aw148015 static var_t * 596 6550 aw148015 var_find_list_only(char *name, var_t *var_list) 597 6550 aw148015 { 598 6550 aw148015 var_t *var; 599 6550 aw148015 600 6550 aw148015 for (var = var_list; var != NULL; var = var->var_next) { 601 6550 aw148015 if (strcmp(var->var_name, name) == 0) 602 6550 aw148015 return (var); 603 6550 aw148015 } 604 6550 aw148015 605 6550 aw148015 return (NULL); 606 6550 aw148015 } 607 6550 aw148015 608 6550 aw148015 /* 609 6550 aw148015 * Searches for var_t with name "name" in the supplied shm_var_list. 610 6550 aw148015 * If not found there, checks the global list. If still 611 6550 aw148015 * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t. 612 6550 aw148015 */ 613 6550 aw148015 static var_t * 614 6550 aw148015 var_find_list(char *name, var_t *var_list) 615 6550 aw148015 { 616 6550 aw148015 var_t *var; 617 6550 aw148015 618 6550 aw148015 if ((var = var_find_list_only(name, var_list)) != NULL) 619 6550 aw148015 return (var); 620 6550 aw148015 else 621 6550 aw148015 return (var_find(name)); 622 5184 ek110237 } 623 5184 ek110237 624 5184 ek110237 /* 625 9801 Andrew * Searches for the named var and returns it if found. If not 626 9801 Andrew * found it allocates a new variable 627 9801 Andrew */ 628 9801 Andrew static var_t * 629 9801 Andrew var_find_alloc(char *name) 630 9801 Andrew { 631 9801 Andrew var_t *var; 632 9801 Andrew 633 9801 Andrew if (name == NULL) { 634 9801 Andrew filebench_log(LOG_ERROR, 635 9801 Andrew "var_find_alloc: Var name not supplied"); 636 9801 Andrew return (NULL); 637 9801 Andrew } 638 9801 Andrew 639 9801 Andrew name += 1; 640 9801 Andrew 641 9801 Andrew if ((var = var_find(name)) == NULL) { 642 9801 Andrew var = var_alloc(name); 643 9801 Andrew } 644 9801 Andrew return (var); 645 9801 Andrew } 646 9801 Andrew 647 9801 Andrew /* 648 5184 ek110237 * Searches for the named var, and, if found, sets its 649 6212 aw148015 * var_val.boolean's value to that of the supplied boolean. 650 5184 ek110237 * If not found, the routine allocates a new var and sets 651 6212 aw148015 * its var_val.boolean's value to that of the supplied 652 6212 aw148015 * boolean. If the named var cannot be found or allocated 653 6212 aw148015 * the routine returns -1, otherwise it returns 0. 654 5184 ek110237 */ 655 5184 ek110237 int 656 6212 aw148015 var_assign_boolean(char *name, boolean_t bool) 657 5184 ek110237 { 658 5184 ek110237 var_t *var; 659 5184 ek110237 660 9801 Andrew if ((var = var_find_alloc(name)) == NULL) { 661 5184 ek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 662 5184 ek110237 name); 663 5184 ek110237 return (-1); 664 5184 ek110237 } 665 5184 ek110237 666 6212 aw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 667 6212 aw148015 filebench_log(LOG_ERROR, 668 6212 aw148015 "Cannot assign integer to random variable %s", name); 669 6212 aw148015 return (-1); 670 6212 aw148015 } 671 6212 aw148015 672 6212 aw148015 VAR_SET_BOOL(var, bool); 673 6212 aw148015 674 6212 aw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign boolean %s=%d", 675 6212 aw148015 name, bool); 676 6212 aw148015 677 6212 aw148015 return (0); 678 6212 aw148015 } 679 6212 aw148015 680 6212 aw148015 /* 681 6212 aw148015 * Searches for the named var, and, if found, sets its 682 6212 aw148015 * var_integer's value to that of the supplied integer. 683 6212 aw148015 * If not found, the routine allocates a new var and sets 684 6212 aw148015 * its var_integers's value to that of the supplied 685 6212 aw148015 * integer. If the named var cannot be found or allocated 686 6212 aw148015 * the routine returns -1, otherwise it returns 0. 687 6212 aw148015 */ 688 6212 aw148015 int 689 6212 aw148015 var_assign_integer(char *name, fbint_t integer) 690 6212 aw148015 { 691 6212 aw148015 var_t *var; 692 6212 aw148015 693 9801 Andrew if ((var = var_find_alloc(name)) == NULL) { 694 6212 aw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 695 6212 aw148015 name); 696 6212 aw148015 return (-1); 697 6212 aw148015 } 698 6212 aw148015 699 6212 aw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 700 6212 aw148015 filebench_log(LOG_ERROR, 701 6212 aw148015 "Cannot assign integer to random variable %s", name); 702 6212 aw148015 return (-1); 703 6212 aw148015 } 704 6212 aw148015 705 6212 aw148015 VAR_SET_INT(var, integer); 706 5184 ek110237 707 6286 aw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu", 708 6286 aw148015 name, (u_longlong_t)integer); 709 5184 ek110237 710 5184 ek110237 return (0); 711 9801 Andrew } 712 9801 Andrew 713 9801 Andrew /* 714 9801 Andrew * Add, subtract, multiply or divide two integers based on optype 715 9801 Andrew * passed from caller. 716 9801 Andrew */ 717 9801 Andrew static fbint_t 718 9801 Andrew var_binary_integer_op(var_t *var) 719 9801 Andrew { 720 9801 Andrew fbint_t result; 721 9801 Andrew fbint_t src1, src2; 722 9801 Andrew 723 9801 Andrew if (var == NULL) 724 9801 Andrew return (0); 725 9801 Andrew 726 9801 Andrew switch (var->var_type & VAR_INDBINOP_MASK) { 727 9801 Andrew case VAR_IND_BINOP_INT: 728 9801 Andrew src2 = var->var_val.integer; 729 9801 Andrew break; 730 9801 Andrew 731 9801 Andrew case VAR_IND_BINOP_DBL: 732 9801 Andrew src2 = (fbint_t)var->var_val.dbl_flt; 733 9801 Andrew break; 734 9801 Andrew 735 9801 Andrew case VAR_IND_BINOP_VAR: 736 9801 Andrew if (var->var_val.varptr2 != NULL) 737 9801 Andrew src2 = var_get_int(var->var_val.varptr2); 738 9801 Andrew else 739 9801 Andrew src2 = 0; 740 9801 Andrew break; 741 9801 Andrew } 742 9801 Andrew 743 9801 Andrew if (var->var_varptr1 != NULL) 744 9801 Andrew src1 = var_get_int(var->var_varptr1); 745 9801 Andrew else 746 9801 Andrew src1 = 0; 747 9801 Andrew 748 9801 Andrew switch (var->var_type & VAR_INDVAR_MASK) { 749 9801 Andrew case VAR_IND_VAR_SUM_VC: 750 9801 Andrew result = src1 + src2; 751 9801 Andrew break; 752 9801 Andrew 753 9801 Andrew case VAR_IND_VAR_DIF_VC: 754 9801 Andrew result = src1 - src2; 755 9801 Andrew break; 756 9801 Andrew 757 9801 Andrew case VAR_IND_C_DIF_VAR: 758 9801 Andrew result = src2 - src1; 759 9801 Andrew break; 760 9801 Andrew 761 9801 Andrew case VAR_IND_VAR_MUL_VC: 762 9801 Andrew result = src1 * src2; 763 9801 Andrew break; 764 9801 Andrew 765 9801 Andrew case VAR_IND_VAR_DIV_VC: 766 9801 Andrew result = src1 / src2; 767 9801 Andrew break; 768 9801 Andrew 769 9801 Andrew case VAR_IND_C_DIV_VAR: 770 9801 Andrew result = src2 / src1; 771 9801 Andrew break; 772 9801 Andrew 773 9801 Andrew default: 774 9801 Andrew filebench_log(LOG_DEBUG_IMPL, 775 9801 Andrew "var_binary_integer_op: Called with unknown IND_TYPE"); 776 9801 Andrew result = 0; 777 9801 Andrew break; 778 9801 Andrew } 779 9801 Andrew return (result); 780 9801 Andrew } 781 9801 Andrew 782 9801 Andrew /* 783 9801 Andrew * Add, subtract, multiply or divide two double precision floating point 784 9801 Andrew * numbers based on optype passed from caller. 785 9801 Andrew */ 786 9801 Andrew static double 787 9801 Andrew var_binary_dbl_flt_op(var_t *var) 788 9801 Andrew { 789 9801 Andrew double result; 790 9801 Andrew double src1, src2; 791 9801 Andrew 792 9801 Andrew if (var == NULL) 793 9801 Andrew return (0.0); 794 9801 Andrew 795 9801 Andrew switch (var->var_type & VAR_INDBINOP_MASK) { 796 9801 Andrew case VAR_IND_BINOP_INT: 797 9801 Andrew src2 = (double)var->var_val.integer; 798 9801 Andrew break; 799 9801 Andrew 800 9801 Andrew case VAR_IND_BINOP_DBL: 801 9801 Andrew src2 = var->var_val.dbl_flt; 802 9801 Andrew break; 803 9801 Andrew 804 9801 Andrew case VAR_IND_BINOP_VAR: 805 9801 Andrew if (var->var_val.varptr2 != NULL) 806 9801 Andrew src2 = var_get_dbl(var->var_val.varptr2); 807 9801 Andrew else 808 9801 Andrew src2 = 0; 809 9801 Andrew break; 810 9801 Andrew } 811 9801 Andrew 812 9801 Andrew if (var->var_varptr1 != NULL) 813 9801 Andrew src1 = var_get_dbl(var->var_varptr1); 814 9801 Andrew else 815 9801 Andrew src1 = 0; 816 9801 Andrew 817 9801 Andrew switch (var->var_type & VAR_INDVAR_MASK) { 818 9801 Andrew case VAR_IND_VAR_SUM_VC: 819 9801 Andrew result = src1 + src2; 820 9801 Andrew break; 821 9801 Andrew 822 9801 Andrew case VAR_IND_VAR_DIF_VC: 823 9801 Andrew result = src1 - src2; 824 9801 Andrew break; 825 9801 Andrew 826 9801 Andrew case VAR_IND_C_DIF_VAR: 827 9801 Andrew result = src2 - src1; 828 9801 Andrew break; 829 9801 Andrew 830 9801 Andrew case VAR_IND_VAR_MUL_VC: 831 9801 Andrew result = src1 * src2; 832 9801 Andrew break; 833 9801 Andrew 834 9801 Andrew case VAR_IND_C_DIV_VAR: 835 9801 Andrew result = src2 / src1; 836 9801 Andrew break; 837 9801 Andrew 838 9801 Andrew case VAR_IND_VAR_DIV_VC: 839 9801 Andrew result = src1 / src2; 840 9801 Andrew break; 841 9801 Andrew 842 9801 Andrew default: 843 9801 Andrew filebench_log(LOG_DEBUG_IMPL, 844 9801 Andrew "var_binary_dbl_flt_op: Called with unknown IND_TYPE"); 845 9801 Andrew result = 0; 846 9801 Andrew break; 847 9801 Andrew } 848 9801 Andrew return (result); 849 9801 Andrew } 850 9801 Andrew 851 9801 Andrew /* 852 9801 Andrew * Perform a binary operation on a variable and an integer 853 9801 Andrew */ 854 9801 Andrew int 855 9801 Andrew var_assign_op_var_int(char *name, int optype, char *src1, fbint_t src2) 856 9801 Andrew { 857 9801 Andrew var_t *var; 858 9801 Andrew var_t *var_src1; 859 9801 Andrew 860 9801 Andrew if ((var_src1 = var_find(src1+1)) == NULL) 861 9801 Andrew return (FILEBENCH_ERROR); 862 9801 Andrew 863 9801 Andrew if ((var = var_find_alloc(name)) == NULL) 864 9801 Andrew return (FILEBENCH_ERROR); 865 9801 Andrew 866 9801 Andrew if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 867 9801 Andrew filebench_log(LOG_ERROR, 868 9801 Andrew "Cannot assign integer to random variable %s", name); 869 9801 Andrew return (FILEBENCH_ERROR); 870 9801 Andrew } 871 9801 Andrew 872 9801 Andrew VAR_SET_BINOP_INDVAR(var, var_src1, optype); 873 9801 Andrew 874 9801 Andrew var->var_val.integer = src2; 875 9801 Andrew 876 9801 Andrew return (FILEBENCH_OK); 877 9801 Andrew } 878 9801 Andrew 879 9801 Andrew int 880 9801 Andrew var_assign_op_var_var(char *name, int optype, char *src1, char *src2) 881 9801 Andrew { 882 9801 Andrew var_t *var; 883 9801 Andrew var_t *var_src1; 884 9801 Andrew var_t *var_src2; 885 9801 Andrew 886 9801 Andrew if ((var_src1 = var_find(src1+1)) == NULL) 887 9801 Andrew return (FILEBENCH_ERROR); 888 9801 Andrew 889 9801 Andrew if ((var_src2 = var_find(src2+1)) == NULL) 890 9801 Andrew return (FILEBENCH_ERROR); 891 9801 Andrew 892 9801 Andrew if ((var = var_find_alloc(name)) == NULL) 893 9801 Andrew return (FILEBENCH_ERROR); 894 9801 Andrew 895 9801 Andrew if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 896 9801 Andrew filebench_log(LOG_ERROR, 897 9801 Andrew "Cannot assign integer to random variable %s", name); 898 9801 Andrew return (FILEBENCH_ERROR); 899 9801 Andrew } 900 9801 Andrew 901 9801 Andrew VAR_SET_BINOP_INDVAR(var, var_src1, optype); 902 9801 Andrew 903 9801 Andrew var->var_val.varptr2 = var_src2; 904 9801 Andrew 905 9801 Andrew return (FILEBENCH_OK); 906 5184 ek110237 } 907 5184 ek110237 908 5184 ek110237 /* 909 6212 aw148015 * Find a variable, and set it to random type. 910 6212 aw148015 * If it does not have a random extension, allocate one 911 6212 aw148015 */ 912 6212 aw148015 var_t * 913 6212 aw148015 var_find_randvar(char *name) 914 6212 aw148015 { 915 6212 aw148015 var_t *newvar; 916 6212 aw148015 917 6212 aw148015 name += 1; 918 6212 aw148015 919 6212 aw148015 if ((newvar = var_find(name)) == NULL) { 920 6212 aw148015 filebench_log(LOG_ERROR, 921 6212 aw148015 "failed to locate random variable $%s\n", name); 922 6212 aw148015 return (NULL); 923 6212 aw148015 } 924 6212 aw148015 925 6212 aw148015 /* set randdist pointer unless it is already set */ 926 6212 aw148015 if (((newvar->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) || 927 6212 aw148015 !VAR_HAS_RANDDIST(newvar)) { 928 6212 aw148015 filebench_log(LOG_ERROR, 929 6212 aw148015 "Found variable $%s not random\n", name); 930 6212 aw148015 return (NULL); 931 6212 aw148015 } 932 6212 aw148015 933 6212 aw148015 return (newvar); 934 6212 aw148015 } 935 6212 aw148015 936 6212 aw148015 /* 937 6212 aw148015 * Allocate a variable, and set it to random type. Then 938 6212 aw148015 * allocate a random extension. 939 6212 aw148015 */ 940 6212 aw148015 var_t * 941 6212 aw148015 var_define_randvar(char *name) 942 6212 aw148015 { 943 6212 aw148015 var_t *newvar; 944 6212 aw148015 randdist_t *rndp = NULL; 945 6212 aw148015 946 6212 aw148015 name += 1; 947 6212 aw148015 948 6212 aw148015 /* make sure variable doesn't already exist */ 949 6212 aw148015 if (var_find(name) != NULL) { 950 6212 aw148015 filebench_log(LOG_ERROR, 951 6212 aw148015 "variable name already in use\n"); 952 6212 aw148015 return (NULL); 953 6212 aw148015 } 954 6212 aw148015 955 6212 aw148015 /* allocate a random variable */ 956 6212 aw148015 if ((newvar = var_alloc_cmn(name, VAR_TYPE_RANDOM)) == NULL) { 957 6212 aw148015 filebench_log(LOG_ERROR, 958 6212 aw148015 "failed to alloc random variable\n"); 959 6212 aw148015 return (NULL); 960 6212 aw148015 } 961 6212 aw148015 962 6212 aw148015 /* set randdist pointer */ 963 6212 aw148015 if ((rndp = randdist_alloc()) == NULL) { 964 6212 aw148015 filebench_log(LOG_ERROR, 965 6212 aw148015 "failed to alloc random distribution object\n"); 966 6212 aw148015 return (NULL); 967 6212 aw148015 } 968 6212 aw148015 969 6212 aw148015 rndp->rnd_var = newvar; 970 6212 aw148015 VAR_SET_RAND(newvar, rndp); 971 6212 aw148015 972 6212 aw148015 return (newvar); 973 6212 aw148015 } 974 6212 aw148015 975 6212 aw148015 /* 976 6212 aw148015 * Searches for the named var, and if found returns an avd_t 977 6212 aw148015 * pointing to the var's var_integer, var_string or var_double 978 6212 aw148015 * as appropriate. If not found, attempts to allocate 979 6212 aw148015 * a var named "name" and returns an avd_t to it with 980 6212 aw148015 * no value set. If the var cannot be found or allocated, an 981 5184 ek110237 * error is logged and the run is terminated. 982 5184 ek110237 */ 983 6212 aw148015 avd_t 984 6212 aw148015 var_ref_attr(char *name) 985 5184 ek110237 { 986 5184 ek110237 var_t *var; 987 5184 ek110237 988 5184 ek110237 name += 1; 989 5184 ek110237 990 5184 ek110237 if ((var = var_find(name)) == NULL) 991 5184 ek110237 var = var_find_dynamic(name); 992 5184 ek110237 993 5184 ek110237 if (var == NULL) 994 5184 ek110237 var = var_alloc(name); 995 5184 ek110237 996 5184 ek110237 if (var == NULL) { 997 5184 ek110237 filebench_log(LOG_ERROR, "Invalid variable $%s", 998 5184 ek110237 name); 999 5184 ek110237 filebench_shutdown(1); 1000 5184 ek110237 } 1001 5184 ek110237 1002 6212 aw148015 /* allocate pointer to var and return */ 1003 6212 aw148015 return (avd_alloc_var_ptr(var)); 1004 5184 ek110237 } 1005 5184 ek110237 1006 5184 ek110237 /* 1007 9801 Andrew * Converts the contents of a var to a string 1008 5184 ek110237 */ 1009 9801 Andrew static char * 1010 9801 Andrew var_get_string(var_t *var) 1011 5184 ek110237 { 1012 5184 ek110237 1013 6212 aw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 1014 6212 aw148015 switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) { 1015 6212 aw148015 case RAND_TYPE_UNIFORM: 1016 6212 aw148015 return (fb_stralloc("uniform random var")); 1017 6212 aw148015 case RAND_TYPE_GAMMA: 1018 6212 aw148015 return (fb_stralloc("gamma random var")); 1019 6212 aw148015 case RAND_TYPE_TABLE: 1020 6212 aw148015 return (fb_stralloc("tabular random var")); 1021 6212 aw148015 default: 1022 6212 aw148015 return (fb_stralloc("unitialized random var")); 1023 6212 aw148015 } 1024 6212 aw148015 } 1025 5184 ek110237 1026 6212 aw148015 if (VAR_HAS_STRING(var) && var->var_val.string) 1027 6212 aw148015 return (fb_stralloc(var->var_val.string)); 1028 5184 ek110237 1029 6212 aw148015 if (VAR_HAS_BOOLEAN(var)) { 1030 6212 aw148015 if (var->var_val.boolean) 1031 6212 aw148015 return (fb_stralloc("true")); 1032 6212 aw148015 else 1033 6212 aw148015 return (fb_stralloc("false")); 1034 6212 aw148015 } 1035 6212 aw148015 1036 6212 aw148015 if (VAR_HAS_INTEGER(var)) { 1037 9801 Andrew char tmp[128]; 1038 9801 Andrew 1039 6286 aw148015 (void) snprintf(tmp, sizeof (tmp), "%llu", 1040 6286 aw148015 (u_longlong_t)var->var_val.integer); 1041 6212 aw148015 return (fb_stralloc(tmp)); 1042 6212 aw148015 } 1043 6212 aw148015 1044 9801 Andrew if (VAR_HAS_INDVAR(var)) { 1045 9801 Andrew var_t *ivp; 1046 9801 Andrew 1047 9801 Andrew if ((ivp = var->var_varptr1) != NULL) { 1048 9801 Andrew return (var_get_string(ivp)); 1049 9801 Andrew } 1050 9801 Andrew } 1051 9801 Andrew 1052 9801 Andrew if (VAR_HAS_BINOP(var)) { 1053 9801 Andrew char tmp[128]; 1054 9801 Andrew 1055 9801 Andrew (void) snprintf(tmp, sizeof (tmp), "%llu", 1056 9801 Andrew var_binary_integer_op(var)); 1057 9801 Andrew return (fb_stralloc(tmp)); 1058 9801 Andrew } 1059 9801 Andrew 1060 6212 aw148015 return (fb_stralloc("No default")); 1061 9801 Andrew } 1062 9801 Andrew 1063 9801 Andrew /* 1064 9801 Andrew * Searches for the named var, and if found copies the var_val.string, 1065 9801 Andrew * if it exists, a decimal number string representation of 1066 9801 Andrew * var_val.integer, the state of var_val.boolean, or the type of random 1067 9801 Andrew * distribution employed, into a malloc'd bit of memory using fb_stralloc(). 1068 9801 Andrew * Returns a pointer to the created string, or NULL on failure. 1069 9801 Andrew */ 1070 9801 Andrew char * 1071 9801 Andrew var_to_string(char *name) 1072 9801 Andrew { 1073 9801 Andrew var_t *var; 1074 9801 Andrew 1075 9801 Andrew name += 1; 1076 9801 Andrew 1077 9801 Andrew if ((var = var_find(name)) == NULL) 1078 9801 Andrew var = var_find_dynamic(name); 1079 9801 Andrew 1080 9801 Andrew if (var == NULL) 1081 9801 Andrew return (NULL); 1082 9801 Andrew 1083 9801 Andrew return (var_get_string(var)); 1084 9801 Andrew } 1085 9801 Andrew 1086 9801 Andrew /* 1087 9801 Andrew * Returns the boolean from the supplied var_t "var". 1088 9801 Andrew */ 1089 9801 Andrew static boolean_t 1090 9801 Andrew var_get_bool(var_t *var) 1091 9801 Andrew { 1092 9801 Andrew if (var == NULL) 1093 9801 Andrew return (0); 1094 9801 Andrew 1095 9801 Andrew if (VAR_HAS_BOOLEAN(var)) 1096 9801 Andrew return (var->var_val.boolean); 1097 9801 Andrew 1098 9801 Andrew if (VAR_HAS_INTEGER(var)) { 1099 9801 Andrew if (var->var_val.integer == 0) 1100 9801 Andrew return (FALSE); 1101 9801 Andrew else 1102 9801 Andrew return (TRUE); 1103 9801 Andrew } 1104 9801 Andrew 1105 9801 Andrew filebench_log(LOG_ERROR, 1106 9801 Andrew "Attempt to get boolean from %s var $%s", 1107 9801 Andrew var_get_type_string(var), var->var_name); 1108 9801 Andrew return (FALSE); 1109 9801 Andrew } 1110 9801 Andrew 1111 9801 Andrew /* 1112 9801 Andrew * Returns the fbint_t from the supplied var_t "var". 1113 9801 Andrew */ 1114 9801 Andrew static fbint_t 1115 9801 Andrew var_get_int(var_t *var) 1116 9801 Andrew { 1117 9801 Andrew randdist_t *rndp; 1118 9801 Andrew 1119 9801 Andrew if (var == NULL) 1120 9801 Andrew return (0); 1121 9801 Andrew 1122 9801 Andrew if (VAR_HAS_INTEGER(var)) 1123 9801 Andrew return (var->var_val.integer); 1124 9801 Andrew 1125 9801 Andrew if (VAR_HAS_RANDDIST(var)) { 1126 9801 Andrew if ((rndp = var->var_val.randptr) != NULL) 1127 9801 Andrew return ((fbint_t)rndp->rnd_get(rndp)); 1128 9801 Andrew } 1129 9801 Andrew 1130 9801 Andrew if (VAR_HAS_BINOP(var)) 1131 9801 Andrew return (var_binary_integer_op(var)); 1132 9801 Andrew 1133 9801 Andrew filebench_log(LOG_ERROR, 1134 9801 Andrew "Attempt to get integer from %s var $%s", 1135 9801 Andrew var_get_type_string(var), var->var_name); 1136 9801 Andrew return (0); 1137 9801 Andrew } 1138 9801 Andrew 1139 9801 Andrew /* 1140 9801 Andrew * Returns the floating point value of a variable pointed to by the 1141 9801 Andrew * supplied var_t "var". Intended to get the actual (double) value 1142 9801 Andrew * supplied by the random variable. 1143 9801 Andrew */ 1144 9801 Andrew static double 1145 9801 Andrew var_get_dbl(var_t *var) 1146 9801 Andrew { 1147 9801 Andrew randdist_t *rndp; 1148 9801 Andrew 1149 9801 Andrew if (var == NULL) 1150 9801 Andrew return (0.0); 1151 9801 Andrew 1152 9801 Andrew if (VAR_HAS_INTEGER(var)) 1153 9801 Andrew return ((double)var->var_val.integer); 1154 9801 Andrew 1155 9801 Andrew if (VAR_HAS_DOUBLE(var)) 1156 9801 Andrew return (var->var_val.dbl_flt); 1157 9801 Andrew 1158 9801 Andrew if (VAR_HAS_RANDDIST(var)) { 1159 9801 Andrew if ((rndp = var->var_val.randptr) != NULL) 1160 9801 Andrew return (rndp->rnd_get(rndp)); 1161 9801 Andrew } 1162 9801 Andrew 1163 9801 Andrew if (VAR_HAS_BINOP(var)) 1164 9801 Andrew return (var_binary_dbl_flt_op(var)); 1165 9801 Andrew 1166 9801 Andrew filebench_log(LOG_ERROR, 1167 9801 Andrew "Attempt to get double float from %s var $%s", 1168 9801 Andrew var_get_type_string(var), var->var_name); 1169 9801 Andrew return (0.0); 1170 5184 ek110237 } 1171 5184 ek110237 1172 5184 ek110237 /* 1173 5184 ek110237 * Searches for the named var, and if found returns the value, 1174 6212 aw148015 * of var_val.boolean. If the var is not found, or a boolean 1175 6212 aw148015 * value has not been set, logs an error and returns 0. 1176 5184 ek110237 */ 1177 6212 aw148015 boolean_t 1178 6212 aw148015 var_to_boolean(char *name) 1179 6212 aw148015 { 1180 6212 aw148015 var_t *var; 1181 6212 aw148015 1182 6212 aw148015 name += 1; 1183 6212 aw148015 1184 6212 aw148015 if ((var = var_find(name)) == NULL) 1185 6212 aw148015 var = var_find_dynamic(name); 1186 6212 aw148015 1187 9801 Andrew if (var != NULL) 1188 9801 Andrew return (var_get_bool(var)); 1189 6212 aw148015 1190 6212 aw148015 filebench_log(LOG_ERROR, 1191 6212 aw148015 "Variable %s referenced before set", name); 1192 6212 aw148015 1193 9801 Andrew return (FALSE); 1194 6212 aw148015 } 1195 6212 aw148015 1196 6212 aw148015 /* 1197 6212 aw148015 * Searches for the named var, and if found returns the value, 1198 6212 aw148015 * of var_val.integer. If the var is not found, or the an 1199 6212 aw148015 * integer value has not been set, logs an error and returns 0. 1200 6212 aw148015 */ 1201 6212 aw148015 fbint_t 1202 5184 ek110237 var_to_integer(char *name) 1203 5184 ek110237 { 1204 5184 ek110237 var_t *var; 1205 5184 ek110237 1206 5184 ek110237 name += 1; 1207 5184 ek110237 1208 5184 ek110237 if ((var = var_find(name)) == NULL) 1209 5184 ek110237 var = var_find_dynamic(name); 1210 5184 ek110237 1211 9801 Andrew if (var != NULL) 1212 9801 Andrew return (var_get_int(var)); 1213 5184 ek110237 1214 5184 ek110237 filebench_log(LOG_ERROR, 1215 5184 ek110237 "Variable %s referenced before set", name); 1216 5184 ek110237 1217 5184 ek110237 return (0); 1218 9801 Andrew } 1219 9801 Andrew 1220 9801 Andrew /* 1221 9801 Andrew * Searches for the named var, and if found returns the value, 1222 9801 Andrew * of var_val.dbl_flt. If the var is not found, or the 1223 9801 Andrew * floating value has not been set, logs an error and returns 0.0. 1224 9801 Andrew */ 1225 9801 Andrew double 1226 9801 Andrew var_to_double(char *name) 1227 9801 Andrew { 1228 9801 Andrew var_t *var; 1229 9801 Andrew 1230 9801 Andrew name += 1; 1231 9801 Andrew 1232 9801 Andrew if ((var = var_find(name)) == NULL) 1233 9801 Andrew var = var_find_dynamic(name); 1234 9801 Andrew 1235 9801 Andrew if (var != NULL) 1236 9801 Andrew return (var_get_dbl(var)); 1237 9801 Andrew 1238 9801 Andrew filebench_log(LOG_ERROR, 1239 9801 Andrew "Variable %s referenced before set", name); 1240 9801 Andrew 1241 9801 Andrew return (0.0); 1242 6212 aw148015 } 1243 6212 aw148015 1244 6212 aw148015 /* 1245 6212 aw148015 * Searches for the named random var, and if found, converts the 1246 6212 aw148015 * requested parameter into a string or a decimal number string 1247 6212 aw148015 * representation, into a malloc'd bit of memory using fb_stralloc(). 1248 6212 aw148015 * Returns a pointer to the created string, or calls var_to_string() 1249 6212 aw148015 * if a random variable isn't found. 1250 6212 aw148015 */ 1251 6212 aw148015 char * 1252 6212 aw148015 var_randvar_to_string(char *name, int param_name) 1253 6212 aw148015 { 1254 6212 aw148015 var_t *var; 1255 6212 aw148015 fbint_t value; 1256 6212 aw148015 1257 6212 aw148015 if ((var = var_find(name + 1)) == NULL) 1258 6212 aw148015 return (var_to_string(name)); 1259 6212 aw148015 1260 6212 aw148015 if (((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) || 1261 6212 aw148015 !VAR_HAS_RANDDIST(var)) 1262 6212 aw148015 return (var_to_string(name)); 1263 6212 aw148015 1264 6212 aw148015 switch (param_name) { 1265 6212 aw148015 case RAND_PARAM_TYPE: 1266 6212 aw148015 switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) { 1267 6212 aw148015 case RAND_TYPE_UNIFORM: 1268 6212 aw148015 return (fb_stralloc("uniform")); 1269 6212 aw148015 case RAND_TYPE_GAMMA: 1270 6212 aw148015 return (fb_stralloc("gamma")); 1271 6212 aw148015 case RAND_TYPE_TABLE: 1272 6212 aw148015 return (fb_stralloc("tabular")); 1273 6212 aw148015 default: 1274 6212 aw148015 return (fb_stralloc("uninitialized")); 1275 6212 aw148015 } 1276 6212 aw148015 1277 6212 aw148015 case RAND_PARAM_SRC: 1278 6212 aw148015 if (var->var_val.randptr->rnd_type & RAND_SRC_GENERATOR) 1279 6212 aw148015 return (fb_stralloc("rand48")); 1280 6212 aw148015 else 1281 6212 aw148015 return (fb_stralloc("urandom")); 1282 6212 aw148015 1283 6212 aw148015 case RAND_PARAM_SEED: 1284 6212 aw148015 value = avd_get_int(var->var_val.randptr->rnd_seed); 1285 6212 aw148015 break; 1286 6212 aw148015 1287 6212 aw148015 case RAND_PARAM_MIN: 1288 6212 aw148015 value = avd_get_int(var->var_val.randptr->rnd_min); 1289 6212 aw148015 break; 1290 6212 aw148015 1291 6212 aw148015 case RAND_PARAM_MEAN: 1292 6212 aw148015 value = avd_get_int(var->var_val.randptr->rnd_mean); 1293 6212 aw148015 break; 1294 6212 aw148015 1295 6212 aw148015 case RAND_PARAM_GAMMA: 1296 6212 aw148015 value = avd_get_int(var->var_val.randptr->rnd_gamma); 1297 6212 aw148015 break; 1298 6212 aw148015 1299 6212 aw148015 case RAND_PARAM_ROUND: 1300 6212 aw148015 value = avd_get_int(var->var_val.randptr->rnd_round); 1301 6212 aw148015 break; 1302 6212 aw148015 1303 6212 aw148015 default: 1304 6212 aw148015 return (NULL); 1305 6212 aw148015 1306 6212 aw148015 } 1307 6212 aw148015 1308 6212 aw148015 /* just an integer value if we got here */ 1309 6212 aw148015 { 1310 6212 aw148015 char tmp[128]; 1311 6212 aw148015 1312 6286 aw148015 (void) snprintf(tmp, sizeof (tmp), "%llu", 1313 6286 aw148015 (u_longlong_t)value); 1314 6212 aw148015 return (fb_stralloc(tmp)); 1315 6212 aw148015 } 1316 5184 ek110237 } 1317 5184 ek110237 1318 5184 ek110237 /* 1319 6550 aw148015 * Copies the value stored in the source string into the destination 1320 6550 aw148015 * string. Returns -1 if any problems encountered, 0 otherwise. 1321 6550 aw148015 */ 1322 6550 aw148015 static int 1323 6550 aw148015 var_copy(var_t *dst_var, var_t *src_var) { 1324 6550 aw148015 1325 6550 aw148015 if (VAR_HAS_BOOLEAN(src_var)) { 1326 6550 aw148015 VAR_SET_BOOL(dst_var, src_var->var_val.boolean); 1327 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1328 6550 aw148015 "Assign var %s=%s", dst_var->var_name, 1329 6550 aw148015 dst_var->var_val.boolean?"true":"false"); 1330 6550 aw148015 } 1331 6550 aw148015 1332 6550 aw148015 if (VAR_HAS_INTEGER(src_var)) { 1333 6550 aw148015 VAR_SET_INT(dst_var, src_var->var_val.integer); 1334 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1335 6550 aw148015 "Assign var %s=%llu", dst_var->var_name, 1336 6550 aw148015 (u_longlong_t)dst_var->var_val.integer); 1337 6550 aw148015 } 1338 6550 aw148015 1339 6550 aw148015 if (VAR_HAS_DOUBLE(src_var)) { 1340 6550 aw148015 VAR_SET_DBL(dst_var, src_var->var_val.dbl_flt); 1341 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1342 6550 aw148015 "Assign var %s=%lf", dst_var->var_name, 1343 6550 aw148015 dst_var->var_val.dbl_flt); 1344 6550 aw148015 } 1345 6550 aw148015 1346 6550 aw148015 if (VAR_HAS_STRING(src_var)) { 1347 6550 aw148015 char *strptr; 1348 6550 aw148015 1349 6550 aw148015 if ((strptr = 1350 6550 aw148015 ipc_stralloc(src_var->var_val.string)) == NULL) { 1351 6550 aw148015 filebench_log(LOG_ERROR, 1352 6550 aw148015 "Cannot assign string for variable %s", 1353 6550 aw148015 dst_var->var_name); 1354 6550 aw148015 return (-1); 1355 6550 aw148015 } 1356 6550 aw148015 VAR_SET_STR(dst_var, strptr); 1357 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1358 6550 aw148015 "Assign var %s=%s", dst_var->var_name, 1359 6550 aw148015 dst_var->var_val.string); 1360 6550 aw148015 } 1361 6550 aw148015 1362 6550 aw148015 if (VAR_HAS_INDVAR(src_var)) { 1363 9801 Andrew VAR_SET_INDVAR(dst_var, src_var->var_varptr1); 1364 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1365 6550 aw148015 "Assign var %s to var %s", dst_var->var_name, 1366 6550 aw148015 src_var->var_name); 1367 6550 aw148015 } 1368 6550 aw148015 return (0); 1369 6550 aw148015 } 1370 6550 aw148015 1371 6550 aw148015 /* 1372 5184 ek110237 * Searches for the var named "name", and if not found 1373 6550 aw148015 * allocates it. The then copies the value from 1374 6550 aw148015 * the src_var into the destination var "name" 1375 6550 aw148015 * If the var "name" cannot be found or allocated, or the var "src_name" 1376 6550 aw148015 * cannot be found, the routine returns -1, otherwise it returns 0. 1377 5184 ek110237 */ 1378 5184 ek110237 int 1379 6212 aw148015 var_assign_var(char *name, char *src_name) 1380 5184 ek110237 { 1381 6212 aw148015 var_t *dst_var, *src_var; 1382 5184 ek110237 1383 5184 ek110237 name += 1; 1384 6212 aw148015 src_name += 1; 1385 5184 ek110237 1386 6212 aw148015 if ((src_var = var_find(src_name)) == NULL) { 1387 6212 aw148015 filebench_log(LOG_ERROR, 1388 6212 aw148015 "Cannot find source variable %s", src_name); 1389 6212 aw148015 return (-1); 1390 6212 aw148015 } 1391 5184 ek110237 1392 6212 aw148015 if ((dst_var = var_find(name)) == NULL) 1393 6212 aw148015 dst_var = var_alloc(name); 1394 6212 aw148015 1395 6212 aw148015 if (dst_var == NULL) { 1396 5184 ek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1397 5184 ek110237 name); 1398 5184 ek110237 return (-1); 1399 5184 ek110237 } 1400 5184 ek110237 1401 6212 aw148015 if ((dst_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 1402 6212 aw148015 filebench_log(LOG_ERROR, 1403 6212 aw148015 "Cannot assign var to Random variable %s", name); 1404 5184 ek110237 return (-1); 1405 5184 ek110237 } 1406 6212 aw148015 1407 6550 aw148015 return (var_copy(dst_var, src_var)); 1408 5184 ek110237 } 1409 5184 ek110237 1410 5184 ek110237 /* 1411 5184 ek110237 * Like var_assign_integer, only this routine copies the 1412 5184 ek110237 * supplied "string" into the var named "name". If the var 1413 5184 ek110237 * named "name" cannot be found then it is first allocated 1414 5184 ek110237 * before the copy. Space for the string in the var comes 1415 5184 ek110237 * from interprocess shared memory. If the var "name" 1416 5184 ek110237 * cannot be found or allocated, or the memory for the 1417 6550 aw148015 * var_val.string copy of "string" cannot be allocated, the 1418 5184 ek110237 * routine returns -1, otherwise it returns 0. 1419 5184 ek110237 */ 1420 5184 ek110237 int 1421 5184 ek110237 var_assign_string(char *name, char *string) 1422 5184 ek110237 { 1423 5184 ek110237 var_t *var; 1424 6212 aw148015 char *strptr; 1425 5184 ek110237 1426 5184 ek110237 name += 1; 1427 5184 ek110237 1428 5184 ek110237 if ((var = var_find(name)) == NULL) 1429 5184 ek110237 var = var_alloc(name); 1430 5184 ek110237 1431 5184 ek110237 if (var == NULL) { 1432 5184 ek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1433 5184 ek110237 name); 1434 5184 ek110237 return (-1); 1435 5184 ek110237 } 1436 5184 ek110237 1437 6212 aw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 1438 6212 aw148015 filebench_log(LOG_ERROR, 1439 6212 aw148015 "Cannot assign string to random variable %s", name); 1440 6212 aw148015 return (-1); 1441 6212 aw148015 } 1442 6212 aw148015 1443 6212 aw148015 if ((strptr = ipc_stralloc(string)) == NULL) { 1444 5184 ek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1445 5184 ek110237 name); 1446 5184 ek110237 return (-1); 1447 5184 ek110237 } 1448 6212 aw148015 VAR_SET_STR(var, strptr); 1449 5184 ek110237 1450 6212 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1451 6212 aw148015 "Var assign string $%s=%s", name, string); 1452 5184 ek110237 1453 5184 ek110237 return (0); 1454 6550 aw148015 } 1455 6550 aw148015 1456 6550 aw148015 /* 1457 6550 aw148015 * Allocates a local var. The then extracts the var_string from 1458 6550 aw148015 * the var named "string" and copies it into the var_string 1459 6550 aw148015 * of the var "name", after first allocating a piece of 1460 6550 aw148015 * interprocess shared string memory. Returns a pointer to the 1461 6550 aw148015 * newly allocated local var or NULL on error. 1462 6550 aw148015 */ 1463 6550 aw148015 var_t * 1464 6550 aw148015 var_lvar_assign_var(char *name, char *src_name) 1465 6550 aw148015 { 1466 6550 aw148015 var_t *dst_var, *src_var; 1467 6550 aw148015 1468 6550 aw148015 src_name += 1; 1469 6550 aw148015 1470 6550 aw148015 if ((src_var = var_find(src_name)) == NULL) { 1471 6550 aw148015 filebench_log(LOG_ERROR, 1472 6550 aw148015 "Cannot find source variable %s", src_name); 1473 6550 aw148015 return (NULL); 1474 6550 aw148015 } 1475 6550 aw148015 1476 6550 aw148015 dst_var = var_lvar_alloc_local(name); 1477 6550 aw148015 1478 6550 aw148015 if (dst_var == NULL) { 1479 6550 aw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1480 6550 aw148015 name); 1481 6550 aw148015 return (NULL); 1482 6550 aw148015 } 1483 6550 aw148015 1484 6550 aw148015 /* 1485 6550 aw148015 * if referencing another local var which is currently 1486 6550 aw148015 * empty, indirect to it 1487 6550 aw148015 */ 1488 6550 aw148015 if ((src_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_LOCAL) { 1489 6550 aw148015 VAR_SET_INDVAR(dst_var, src_var); 1490 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1491 6550 aw148015 "Assign local var %s to %s", name, src_name); 1492 6550 aw148015 return (dst_var); 1493 6550 aw148015 } 1494 6550 aw148015 1495 6550 aw148015 if (VAR_HAS_BOOLEAN(src_var)) { 1496 6550 aw148015 VAR_SET_BOOL(dst_var, src_var->var_val.boolean); 1497 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1498 6550 aw148015 "Assign var (%s, %p)=%s", name, 1499 6550 aw148015 dst_var, src_var->var_val.boolean?"true":"false"); 1500 6550 aw148015 } else if (VAR_HAS_INTEGER(src_var)) { 1501 6550 aw148015 VAR_SET_INT(dst_var, src_var->var_val.integer); 1502 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1503 6550 aw148015 "Assign var (%s, %p)=%llu", name, 1504 6550 aw148015 dst_var, (u_longlong_t)src_var->var_val.integer); 1505 6550 aw148015 } else if (VAR_HAS_STRING(src_var)) { 1506 6550 aw148015 char *strptr; 1507 6550 aw148015 1508 6550 aw148015 if ((strptr = ipc_stralloc(src_var->var_val.string)) == NULL) { 1509 6550 aw148015 filebench_log(LOG_ERROR, 1510 6550 aw148015 "Cannot assign variable %s", 1511 6550 aw148015 name); 1512 6550 aw148015 return (NULL); 1513 6550 aw148015 } 1514 6550 aw148015 VAR_SET_STR(dst_var, strptr); 1515 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1516 6550 aw148015 "Assign var (%s, %p)=%s", name, 1517 6550 aw148015 dst_var, src_var->var_val.string); 1518 6550 aw148015 } else if (VAR_HAS_DOUBLE(src_var)) { 1519 6550 aw148015 /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */ 1520 6550 aw148015 VAR_SET_INT(dst_var, src_var->var_val.dbl_flt); 1521 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1522 6550 aw148015 "Assign var (%s, %p)=%8.2f", name, 1523 6550 aw148015 dst_var, src_var->var_val.dbl_flt); 1524 6550 aw148015 } else if (VAR_HAS_RANDDIST(src_var)) { 1525 6550 aw148015 VAR_SET_RAND(dst_var, src_var->var_val.randptr); 1526 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1527 6550 aw148015 "Assign var (%s, %p)=%llu", name, 1528 6550 aw148015 dst_var, (u_longlong_t)src_var->var_val.integer); 1529 6550 aw148015 } 1530 6550 aw148015 1531 6550 aw148015 return (dst_var); 1532 6550 aw148015 } 1533 6550 aw148015 1534 6550 aw148015 /* 1535 6550 aw148015 * the routine allocates a new local var and sets 1536 6550 aw148015 * its var_boolean's value to that of the supplied 1537 6550 aw148015 * boolean. It returns a pointer to the new local var 1538 6550 aw148015 */ 1539 6550 aw148015 var_t * 1540 6550 aw148015 var_lvar_assign_boolean(char *name, boolean_t bool) 1541 6550 aw148015 { 1542 6550 aw148015 var_t *var; 1543 6550 aw148015 1544 6550 aw148015 var = var_lvar_alloc_local(name); 1545 6550 aw148015 1546 6550 aw148015 if (var == NULL) { 1547 6550 aw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1548 6550 aw148015 name); 1549 6550 aw148015 return (NULL); 1550 6550 aw148015 } 1551 6550 aw148015 1552 6550 aw148015 VAR_SET_BOOL(var, bool); 1553 6550 aw148015 1554 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%s", 1555 6550 aw148015 name, bool ? "true" : "false"); 1556 6550 aw148015 1557 6550 aw148015 return (var); 1558 6550 aw148015 } 1559 6550 aw148015 1560 6550 aw148015 /* 1561 6550 aw148015 * the routine allocates a new local var and sets 1562 6550 aw148015 * its var_integers's value to that of the supplied 1563 6550 aw148015 * integer. It returns a pointer to the new local var 1564 6550 aw148015 */ 1565 6550 aw148015 var_t * 1566 6550 aw148015 var_lvar_assign_integer(char *name, fbint_t integer) 1567 6550 aw148015 { 1568 6550 aw148015 var_t *var; 1569 6550 aw148015 1570 6550 aw148015 var = var_lvar_alloc_local(name); 1571 6550 aw148015 1572 6550 aw148015 if (var == NULL) { 1573 6550 aw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1574 6550 aw148015 name); 1575 6550 aw148015 return (NULL); 1576 6550 aw148015 } 1577 6550 aw148015 1578 6550 aw148015 VAR_SET_INT(var, integer); 1579 6550 aw148015 1580 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu", 1581 6550 aw148015 name, (u_longlong_t)integer); 1582 6550 aw148015 1583 6550 aw148015 return (var); 1584 6550 aw148015 } 1585 6550 aw148015 1586 6550 aw148015 /* 1587 6550 aw148015 * the routine allocates a new local var and sets 1588 6550 aw148015 * its var_dbl_flt value to that of the supplied 1589 6550 aw148015 * double precission floating point number. It returns 1590 6550 aw148015 * a pointer to the new local var 1591 6550 aw148015 */ 1592 6550 aw148015 var_t * 1593 6550 aw148015 var_lvar_assign_double(char *name, double dbl) 1594 6550 aw148015 { 1595 6550 aw148015 var_t *var; 1596 6550 aw148015 1597 6550 aw148015 var = var_lvar_alloc_local(name); 1598 6550 aw148015 1599 6550 aw148015 if (var == NULL) { 1600 6550 aw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1601 6550 aw148015 name); 1602 6550 aw148015 return (NULL); 1603 6550 aw148015 } 1604 6550 aw148015 1605 6550 aw148015 VAR_SET_DBL(var, dbl); 1606 6550 aw148015 1607 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%8.2f", name, dbl); 1608 6550 aw148015 1609 6550 aw148015 return (var); 1610 6550 aw148015 } 1611 6550 aw148015 1612 6550 aw148015 /* 1613 6550 aw148015 * Like var_lvar_assign_integer, only this routine copies the 1614 6550 aw148015 * supplied "string" into the var named "name". If the var 1615 6550 aw148015 * named "name" cannot be found then it is first allocated 1616 6550 aw148015 * before the copy. Space for the string in the var comes 1617 6550 aw148015 * from interprocess shared memory. The allocated local var 1618 6550 aw148015 * is returned at as a char *, or NULL on error. 1619 6550 aw148015 */ 1620 6550 aw148015 var_t * 1621 6550 aw148015 var_lvar_assign_string(char *name, char *string) 1622 6550 aw148015 { 1623 6550 aw148015 var_t *var; 1624 6550 aw148015 char *strptr; 1625 6550 aw148015 1626 6550 aw148015 var = var_lvar_alloc_local(name); 1627 6550 aw148015 1628 6550 aw148015 if (var == NULL) { 1629 6550 aw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1630 6550 aw148015 name); 1631 6550 aw148015 return (NULL); 1632 6550 aw148015 } 1633 6550 aw148015 1634 6550 aw148015 if ((strptr = ipc_stralloc(string)) == NULL) { 1635 6550 aw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1636 6550 aw148015 name); 1637 6550 aw148015 return (NULL); 1638 6550 aw148015 } 1639 6550 aw148015 VAR_SET_STR(var, strptr); 1640 6550 aw148015 1641 6550 aw148015 filebench_log(LOG_DEBUG_SCRIPT, 1642 6550 aw148015 "Lvar_assign_string (%s, %p)=%s", name, var, string); 1643 6550 aw148015 1644 6550 aw148015 return (var); 1645 5184 ek110237 } 1646 5184 ek110237 1647 5184 ek110237 /* 1648 6212 aw148015 * Tests to see if the supplied variable name without the portion after 1649 6212 aw148015 * the last period is that of a random variable. If it is, it returns 1650 6212 aw148015 * the number of characters to backspace to skip the period and field 1651 6212 aw148015 * name. Otherwise it returns 0. 1652 5184 ek110237 */ 1653 6212 aw148015 int 1654 6212 aw148015 var_is_set4_randvar(char *name) 1655 5184 ek110237 { 1656 5184 ek110237 var_t *var; 1657 6212 aw148015 char varname[128]; 1658 6212 aw148015 int namelength; 1659 6212 aw148015 char *sp; 1660 5184 ek110237 1661 6212 aw148015 (void) strncpy(varname, name, 128); 1662 6212 aw148015 namelength = strlen(varname); 1663 6212 aw148015 sp = varname + namelength; 1664 5184 ek110237 1665 6212 aw148015 while (sp != varname) { 1666 6212 aw148015 int c = *sp; 1667 5184 ek110237 1668 6212 aw148015 *sp = 0; 1669 6212 aw148015 if (c == '.') 1670 6212 aw148015 break; 1671 5184 ek110237 1672 6212 aw148015 sp--; 1673 5184 ek110237 } 1674 5184 ek110237 1675 6212 aw148015 /* not a variable name + field? */ 1676 6212 aw148015 if (sp == varname) 1677 6212 aw148015 return (0); 1678 6212 aw148015 1679 6212 aw148015 /* first part not a variable name? */ 1680 6212 aw148015 if ((var = var_find(varname+1)) == NULL) 1681 6212 aw148015 return (0); 1682 6212 aw148015 1683 6212 aw148015 /* Make sure it is a random variable */ 1684 6212 aw148015 if ((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) 1685 6212 aw148015 return (0); 1686 6212 aw148015 1687 6212 aw148015 /* calculate offset from end of random variable name */ 1688 6212 aw148015 return (namelength - (sp - varname)); 1689 5184 ek110237 } 1690 5184 ek110237 1691 5184 ek110237 /* 1692 5184 ek110237 * Implements a simple path name like scheme for finding values 1693 5184 ek110237 * to place in certain specially named vars. The first part of 1694 5184 ek110237 * the name is interpreted as a category of either: stats, 1695 5184 ek110237 * eventgen, date, script, or host var. If a match is found, 1696 5184 ek110237 * the appropriate routine is called to fill in the requested 1697 5184 ek110237 * value in the provided var_t, and a pointer to the supplied 1698 5184 ek110237 * var_t is returned. If the requested value is not found, NULL 1699 5184 ek110237 * is returned. 1700 5184 ek110237 */ 1701 5184 ek110237 static var_t * 1702 5184 ek110237 var_find_internal(var_t *var) 1703 5184 ek110237 { 1704 5184 ek110237 char *n = fb_stralloc(var->var_name); 1705 5184 ek110237 char *name = n; 1706 5184 ek110237 var_t *rtn = NULL; 1707 5184 ek110237 1708 5184 ek110237 name++; 1709 5184 ek110237 if (name[strlen(name) - 1] != '}') 1710 5184 ek110237 return (NULL); 1711 5184 ek110237 name[strlen(name) - 1] = 0; 1712 5184 ek110237 1713 5184 ek110237 if (strncmp(name, STATS_VAR, strlen(STATS_VAR)) == 0) 1714 5184 ek110237 rtn = stats_findvar(var, name + strlen(STATS_VAR)); 1715 5184 ek110237 1716 5184 ek110237 if (strcmp(name, EVENTGEN_VAR) == 0) 1717 5184 ek110237 rtn = eventgen_ratevar(var); 1718 5184 ek110237 1719 5184 ek110237 if (strcmp(name, DATE_VAR) == 0) 1720 5184 ek110237 rtn = date_var(var); 1721 5184 ek110237 1722 5184 ek110237 if (strcmp(name, SCRIPT_VAR) == 0) 1723 5184 ek110237 rtn = script_var(var); 1724 5184 ek110237 1725 5184 ek110237 if (strcmp(name, HOST_VAR) == 0) 1726 5184 ek110237 rtn = host_var(var); 1727 5184 ek110237 1728 5184 ek110237 free(n); 1729 5184 ek110237 1730 5184 ek110237 return (rtn); 1731 5184 ek110237 } 1732 5184 ek110237 1733 5184 ek110237 /* 1734 5184 ek110237 * Calls the C library routine getenv() to obtain the value 1735 5184 ek110237 * for the environment variable specified by var->var_name. 1736 6212 aw148015 * If found, the value string is returned in var->var_val.string. 1737 5184 ek110237 * If the requested value is not found, NULL is returned. 1738 5184 ek110237 */ 1739 5184 ek110237 static var_t * 1740 5184 ek110237 var_find_environment(var_t *var) 1741 5184 ek110237 { 1742 5184 ek110237 char *n = fb_stralloc(var->var_name); 1743 5184 ek110237 char *name = n; 1744 6212 aw148015 char *strptr; 1745 5184 ek110237 1746 5184 ek110237 name++; 1747 6212 aw148015 if (name[strlen(name) - 1] != ')') { 1748 6212 aw148015 free(n); 1749 5184 ek110237 return (NULL); 1750 6212 aw148015 } 1751 5184 ek110237 name[strlen(name) - 1] = 0; 1752 5184 ek110237 1753 6212 aw148015 if ((strptr = getenv(name)) != NULL) { 1754 5184 ek110237 free(n); 1755 6212 aw148015 VAR_SET_STR(var, strptr); 1756 5184 ek110237 return (var); 1757 5184 ek110237 } else { 1758 5184 ek110237 free(n); 1759 5184 ek110237 return (NULL); 1760 5184 ek110237 } 1761 5184 ek110237 } 1762 5184 ek110237 1763 5184 ek110237 /* 1764 5184 ek110237 * Look up special variables. The "name" argument is used to find 1765 5184 ek110237 * the desired special var and fill it with an appropriate string 1766 5184 ek110237 * value. Looks for an already allocated var of the same name on 1767 6550 aw148015 * the shm_var_dyn_list. If not found a new dynamic var is allocated. 1768 5184 ek110237 * if the name begins with '{', it is an internal variable, and 1769 5184 ek110237 * var_find_internal() is called. If the name begins with '(' it 1770 5184 ek110237 * is an environment varable, and var_find_environment() is 1771 5184 ek110237 * called. On success, a pointer to the var_t is returned, 1772 5184 ek110237 * otherwise, NULL is returned. 1773 5184 ek110237 */ 1774 5184 ek110237 static var_t * 1775 5184 ek110237 var_find_dynamic(char *name) 1776 5184 ek110237 { 1777 5184 ek110237 var_t *var = NULL; 1778 6391 aw148015 var_t *v = filebench_shm->shm_var_dyn_list; 1779 5184 ek110237 var_t *rtn; 1780 5184 ek110237 1781 5184 ek110237 /* 1782 5184 ek110237 * Lookup a reference to the var handle for this 1783 5184 ek110237 * special var 1784 5184 ek110237 */ 1785 6391 aw148015 for (v = filebench_shm->shm_var_dyn_list; v != NULL; v = v->var_next) { 1786 5184 ek110237 if (strcmp(v->var_name, name) == 0) { 1787 5184 ek110237 var = v; 1788 5184 ek110237 break; 1789 5184 ek110237 } 1790 5184 ek110237 } 1791 5184 ek110237 1792 5184 ek110237 if (var == NULL) 1793 5184 ek110237 var = var_alloc_dynamic(name); 1794 5184 ek110237 1795 5184 ek110237 /* Internal system control variable */ 1796 5184 ek110237 if (*name == '{') { 1797 5184 ek110237 rtn = var_find_internal(var); 1798 5184 ek110237 if (rtn == NULL) 1799 5184 ek110237 filebench_log(LOG_ERROR, 1800 5184 ek110237 "Cannot find internal variable %s", 1801 5184 ek110237 var->var_name); 1802 5184 ek110237 return (rtn); 1803 5184 ek110237 } 1804 5184 ek110237 1805 5184 ek110237 /* Lookup variable in environment */ 1806 5184 ek110237 if (*name == '(') { 1807 5184 ek110237 rtn = var_find_environment(var); 1808 5184 ek110237 if (rtn == NULL) 1809 5184 ek110237 filebench_log(LOG_ERROR, 1810 5184 ek110237 "Cannot find environment variable %s", 1811 5184 ek110237 var->var_name); 1812 5184 ek110237 return (rtn); 1813 5184 ek110237 } 1814 5184 ek110237 1815 5184 ek110237 return (NULL); 1816 5184 ek110237 } 1817 6550 aw148015 1818 6550 aw148015 /* 1819 6550 aw148015 * replace the avd_t attribute value descriptor in the new FLOW_MASTER flowop 1820 6550 aw148015 * that points to a local variable with a new avd_t containing 1821 6550 aw148015 * the actual value from the local variable. 1822 6550 aw148015 */ 1823 6550 aw148015 void 1824 6550 aw148015 avd_update(avd_t *avdp, var_t *lvar_list) 1825 6550 aw148015 { 1826 6550 aw148015 var_t *old_lvar, *new_lvar; 1827 6550 aw148015 1828 6550 aw148015 if ((*avdp)->avd_type == AVD_IND_VAR) { 1829 6550 aw148015 1830 6550 aw148015 /* Make sure there is a local var */ 1831 6550 aw148015 if ((old_lvar = (*avdp)->avd_val.varptr) == NULL) { 1832 6550 aw148015 filebench_log(LOG_ERROR, 1833 6550 aw148015 "avd_update: local var not found"); 1834 6550 aw148015 return; 1835 6550 aw148015 } 1836 6550 aw148015 } else { 1837 6550 aw148015 /* Empty or not indirect, so no update needed */ 1838 6550 aw148015 return; 1839 6550 aw148015 } 1840 6550 aw148015 1841 6550 aw148015 /* allocate a new avd using the new or old lvar contents */ 1842 6550 aw148015 if ((new_lvar = 1843 6550 aw148015 var_find_list(old_lvar->var_name, lvar_list)) != NULL) 1844 6550 aw148015 (*avdp) = avd_alloc_var_ptr(new_lvar); 1845 6550 aw148015 else 1846 6550 aw148015 (*avdp) = avd_alloc_var_ptr(old_lvar); 1847 6550 aw148015 } 1848 6550 aw148015 1849 6550 aw148015 void 1850 6550 aw148015 var_update_comp_lvars(var_t *newlvar, var_t *proto_comp_vars, 1851 6550 aw148015 var_t *mstr_lvars) 1852 6550 aw148015 { 1853 6550 aw148015 var_t *proto_lvar; 1854 6550 aw148015 1855 6550 aw148015 /* find the prototype lvar from the inherited list */ 1856 6550 aw148015 proto_lvar = var_find_list_only(newlvar->var_name, proto_comp_vars); 1857 6550 aw148015 1858 6550 aw148015 if (proto_lvar == NULL) 1859 6550 aw148015 return; 1860 6550 aw148015 1861 6550 aw148015 /* 1862 6550 aw148015 * if the new local variable has not already been assigned 1863 6550 aw148015 * a value, try to copy a value from the prototype local variable 1864 6550 aw148015 */ 1865 6550 aw148015 if ((newlvar->var_type & VAR_TYPE_SET_MASK) == 0) { 1866 6550 aw148015 1867 6550 aw148015 /* copy value from prototype lvar to new lvar */ 1868 6550 aw148015 (void) var_copy(newlvar, proto_lvar); 1869 6550 aw148015 } 1870 6550 aw148015 1871 6550 aw148015 /* If proto lvar is indirect, see if we can colapse indirection */ 1872 6550 aw148015 if (VAR_HAS_INDVAR(proto_lvar)) { 1873 6550 aw148015 var_t *uplvp; 1874 6550 aw148015 1875 9801 Andrew uplvp = (var_t *)proto_lvar->var_varptr1; 1876 6550 aw148015 1877 6550 aw148015 /* search for more current uplvar on comp master list */ 1878 6550 aw148015 if (mstr_lvars) { 1879 6550 aw148015 uplvp = var_find_list_only( 1880 6550 aw148015 uplvp->var_name, mstr_lvars); 1881 6550 aw148015 VAR_SET_INDVAR(newlvar, uplvp); 1882 6550 aw148015 } 1883 6550 aw148015 1884 6550 aw148015 if (VAR_HAS_INDVAR(uplvp)) 1885 9801 Andrew VAR_SET_INDVAR(newlvar, uplvp->var_varptr1); 1886 6550 aw148015 } 1887 6550 aw148015 } 1888