15184Sek110237 /* 25184Sek110237 * CDDL HEADER START 35184Sek110237 * 45184Sek110237 * The contents of this file are subject to the terms of the 55184Sek110237 * Common Development and Distribution License (the "License"). 65184Sek110237 * You may not use this file except in compliance with the License. 75184Sek110237 * 85184Sek110237 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95184Sek110237 * or http://www.opensolaris.org/os/licensing. 105184Sek110237 * See the License for the specific language governing permissions 115184Sek110237 * and limitations under the License. 125184Sek110237 * 135184Sek110237 * When distributing Covered Code, include this CDDL HEADER in each 145184Sek110237 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155184Sek110237 * If applicable, add the following below this CDDL HEADER, with the 165184Sek110237 * fields enclosed by brackets "[]" replaced with your own identifying 175184Sek110237 * information: Portions Copyright [yyyy] [name of copyright owner] 185184Sek110237 * 195184Sek110237 * CDDL HEADER END 205184Sek110237 */ 215184Sek110237 /* 226212Saw148015 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235184Sek110237 * Use is subject to license terms. 245184Sek110237 */ 255184Sek110237 265184Sek110237 #pragma ident "%Z%%M% %I% %E% SMI" 275184Sek110237 285184Sek110237 #include <stdlib.h> 295184Sek110237 #include <stdio.h> 305184Sek110237 #include <string.h> 315184Sek110237 #include <errno.h> 325184Sek110237 335184Sek110237 #include "vars.h" 345184Sek110237 #include "misc.h" 355184Sek110237 #include "utils.h" 365184Sek110237 #include "stats.h" 375184Sek110237 #include "eventgen.h" 385184Sek110237 #include "filebench.h" 396212Saw148015 #include "fb_random.h" 405184Sek110237 415184Sek110237 static var_t *var_find_dynamic(char *name); 425184Sek110237 435184Sek110237 /* 446212Saw148015 * The filebench variables system has attribute value descriptors (avd_t) 456212Saw148015 * where an avd contains a boolean, integer, double, string, random 466212Saw148015 * distribution object ptr, boolean ptr, integer ptr, double ptr, 476212Saw148015 * string ptr, or variable ptr. The system also has the variables 486212Saw148015 * themselves, (var_t), which are named, typed entities which can be 496212Saw148015 * allocated, selected and changed using the "set" command and used in 506212Saw148015 * attribute assignments. The variables contain either a boolean, an 516212Saw148015 * integer, a double, a string or pointer to an associated random 526212Saw148015 * distribution object. Both avd_t and var_t entities are allocated 535184Sek110237 * from interprocess shared memory space. 545184Sek110237 * 556212Saw148015 * The attribute descriptors implement delayed binding to variable values, 566212Saw148015 * which is necessary because the values of variables may be changed 576212Saw148015 * between the time the workload file is loaded and it is actually run, 586212Saw148015 * either by further "set" commands in the file or from the command line 596212Saw148015 * interface. For random variables, they actually point to the random 606212Saw148015 * distribution object, allowing FileBench to invoke the appropriate 616212Saw148015 * random distribution function on each access to the attribute. However, 626212Saw148015 * for static attributes, the value is just loaded in the descriptor 636212Saw148015 * directly, avoiding the need to allocate a variable to hold the static 646212Saw148015 * value. 656212Saw148015 * 665184Sek110237 * The routines in this module are used to allocate, locate, and 676212Saw148015 * manipulate the attribute descriptors, and vars. Routines are 686212Saw148015 * also included to convert between the component strings, doubles 696212Saw148015 * and integers of vars, and said components of avd_t. 705184Sek110237 */ 715184Sek110237 72*6550Saw148015 735184Sek110237 /* 746212Saw148015 * returns a pointer to a string indicating the type of data contained 756212Saw148015 * in the supplied attribute variable descriptor. 765184Sek110237 */ 776212Saw148015 static char * 786212Saw148015 avd_get_type_string(avd_t avd) 795184Sek110237 { 806212Saw148015 switch (avd->avd_type) { 816212Saw148015 case AVD_INVALID: 826212Saw148015 return ("uninitialized"); 836212Saw148015 846212Saw148015 case AVD_VAL_BOOL: 856212Saw148015 return ("boolean value"); 866212Saw148015 876212Saw148015 case AVD_VARVAL_BOOL: 886212Saw148015 return ("points to boolean in var_t"); 896212Saw148015 906212Saw148015 case AVD_VAL_INT: 916212Saw148015 return ("integer value"); 926212Saw148015 936212Saw148015 case AVD_VARVAL_INT: 946212Saw148015 return ("points to integer in var_t"); 956212Saw148015 966212Saw148015 case AVD_VAL_STR: 976212Saw148015 return ("string"); 986212Saw148015 996212Saw148015 case AVD_VARVAL_STR: 1006212Saw148015 return ("points to string in var_t"); 1016212Saw148015 1026212Saw148015 case AVD_VAL_DBL: 1036212Saw148015 return ("double float value"); 1046212Saw148015 1056212Saw148015 case AVD_VARVAL_DBL: 1066212Saw148015 return ("points to double float in var_t"); 1076212Saw148015 1086212Saw148015 case AVD_IND_VAR: 1096212Saw148015 return ("points to a var_t"); 1106212Saw148015 1116212Saw148015 case AVD_IND_RANDVAR: 1126212Saw148015 return ("points to var_t's random distribution object"); 1136212Saw148015 1146212Saw148015 default: 1156212Saw148015 return ("illegal avd type"); 1166212Saw148015 } 1176212Saw148015 } 1186212Saw148015 1196212Saw148015 /* 1206212Saw148015 * returns a pointer to a string indicating the type of data contained 1216212Saw148015 * in the supplied variable. 1226212Saw148015 */ 1236212Saw148015 static char * 1246212Saw148015 var_get_type_string(var_t *ivp) 1256212Saw148015 { 1266212Saw148015 switch (ivp->var_type & VAR_TYPE_SET_MASK) { 1276212Saw148015 case VAR_TYPE_BOOL_SET: 1286212Saw148015 return ("boolean"); 1296212Saw148015 1306212Saw148015 case VAR_TYPE_INT_SET: 1316212Saw148015 return ("integer"); 1326212Saw148015 1336212Saw148015 case VAR_TYPE_STR_SET: 1346212Saw148015 return ("string"); 1356212Saw148015 1366212Saw148015 case VAR_TYPE_DBL_SET: 1376212Saw148015 return ("double float"); 1386212Saw148015 1396212Saw148015 case VAR_TYPE_RAND_SET: 1406212Saw148015 return ("random"); 1416212Saw148015 1426212Saw148015 default: 1436212Saw148015 return ("empty"); 1446212Saw148015 } 1456212Saw148015 } 1466212Saw148015 1476212Saw148015 /* 1486212Saw148015 * Returns the fbint_t pointed to by the supplied avd_t "avd". 1496212Saw148015 */ 1506212Saw148015 fbint_t 1516212Saw148015 avd_get_int(avd_t avd) 1526212Saw148015 { 1536212Saw148015 var_t *ivp; 1546212Saw148015 randdist_t *rndp; 1556212Saw148015 1566212Saw148015 if (avd == NULL) 1575184Sek110237 return (0); 1585184Sek110237 1596212Saw148015 switch (avd->avd_type) { 1606212Saw148015 case AVD_VAL_INT: 1616212Saw148015 return (avd->avd_val.intval); 1626212Saw148015 1636212Saw148015 case AVD_VARVAL_INT: 1646212Saw148015 if (avd->avd_val.intptr) 1656212Saw148015 return (*(avd->avd_val.intptr)); 1666212Saw148015 else 1676212Saw148015 return (0); 1686212Saw148015 1696212Saw148015 case AVD_IND_VAR: 1706212Saw148015 if ((ivp = avd->avd_val.varptr) == NULL) 1716212Saw148015 return (0); 1726212Saw148015 1736212Saw148015 if (VAR_HAS_INTEGER(ivp)) 1746212Saw148015 return (ivp->var_val.integer); 1756212Saw148015 1766212Saw148015 if (VAR_HAS_RANDDIST(ivp)) { 1776212Saw148015 if ((rndp = ivp->var_val.randptr) != NULL) 1786212Saw148015 return ((fbint_t)rndp->rnd_get(rndp)); 1796212Saw148015 } 1806212Saw148015 1816212Saw148015 filebench_log(LOG_ERROR, 1826212Saw148015 "Attempt to get integer from %s var $%s", 1836212Saw148015 var_get_type_string(ivp), ivp->var_name); 1846212Saw148015 return (0); 1856212Saw148015 1866212Saw148015 case AVD_IND_RANDVAR: 1876212Saw148015 if ((rndp = avd->avd_val.randptr) == NULL) 1886212Saw148015 return (0); 1896212Saw148015 else 1906212Saw148015 return ((fbint_t)rndp->rnd_get(rndp)); 1916212Saw148015 1926212Saw148015 default: 1936212Saw148015 filebench_log(LOG_ERROR, 1946212Saw148015 "Attempt to get integer from %s avd", 1956212Saw148015 avd_get_type_string(avd)); 1966212Saw148015 return (0); 1976212Saw148015 } 1985184Sek110237 } 1995184Sek110237 2005184Sek110237 /* 2016212Saw148015 * Returns the floating point value of a variable pointed to by the 2026212Saw148015 * supplied avd_t "avd". Intended to get the actual (double) value 2036212Saw148015 * supplied by the random variable. 2046212Saw148015 */ 2056212Saw148015 double 2066212Saw148015 avd_get_dbl(avd_t avd) 2076212Saw148015 { 2086212Saw148015 var_t *ivp; 2096212Saw148015 randdist_t *rndp; 2106212Saw148015 2116212Saw148015 if (avd == NULL) 2126212Saw148015 return (0.0); 2136212Saw148015 2146212Saw148015 switch (avd->avd_type) { 2156212Saw148015 case AVD_VAL_INT: 2166212Saw148015 return ((double)avd->avd_val.intval); 2176212Saw148015 2186212Saw148015 case AVD_VAL_DBL: 2196212Saw148015 return (avd->avd_val.dblval); 2206212Saw148015 2216212Saw148015 case AVD_VARVAL_INT: 2226212Saw148015 if (avd->avd_val.intptr) 2236212Saw148015 return ((double)(*(avd->avd_val.intptr))); 2246212Saw148015 else 2256212Saw148015 return (0.0); 2266212Saw148015 2276212Saw148015 case AVD_VARVAL_DBL: 2286212Saw148015 if (avd->avd_val.dblptr) 2296212Saw148015 return (*(avd->avd_val.dblptr)); 2306212Saw148015 else 2316212Saw148015 return (0.0); 2326212Saw148015 2336212Saw148015 case AVD_IND_VAR: 2346212Saw148015 ivp = avd->avd_val.varptr; 2356212Saw148015 2366212Saw148015 if (ivp && VAR_HAS_INTEGER(ivp)) 2376212Saw148015 return ((double)ivp->var_val.integer); 2386212Saw148015 2396212Saw148015 if (ivp && VAR_HAS_DOUBLE(ivp)) 2406212Saw148015 return (ivp->var_val.dbl_flt); 2416212Saw148015 2426212Saw148015 if (ivp && VAR_HAS_RANDDIST(ivp)) { 2436212Saw148015 if ((rndp = ivp->var_val.randptr) != NULL) 2446212Saw148015 return (rndp->rnd_get(rndp)); 2456212Saw148015 } 2466212Saw148015 filebench_log(LOG_ERROR, 2476212Saw148015 "Attempt to get double float from %s var $%s", 2486212Saw148015 var_get_type_string(ivp), ivp->var_name); 2496212Saw148015 return (0.0); 2506212Saw148015 2516212Saw148015 case AVD_IND_RANDVAR: 2526212Saw148015 if ((rndp = avd->avd_val.randptr) == NULL) { 2536212Saw148015 return (0.0); 2546212Saw148015 } else 2556212Saw148015 return (rndp->rnd_get(rndp)); 2566212Saw148015 2576212Saw148015 default: 2586212Saw148015 filebench_log(LOG_ERROR, 2596212Saw148015 "Attempt to get floating point from %s avd", 2606212Saw148015 avd_get_type_string(avd)); 2616212Saw148015 return (0.0); 2626212Saw148015 } 2636212Saw148015 } 2646212Saw148015 2656212Saw148015 /* 2666212Saw148015 * Returns the boolean pointed to by the supplied avd_t "avd". 2675184Sek110237 */ 2686212Saw148015 boolean_t 2696212Saw148015 avd_get_bool(avd_t avd) 2705184Sek110237 { 2716212Saw148015 var_t *ivp; 2726212Saw148015 2736212Saw148015 if (avd == NULL) 2746212Saw148015 return (0); 2756212Saw148015 2766212Saw148015 switch (avd->avd_type) { 2776212Saw148015 case AVD_VAL_BOOL: 2786212Saw148015 return (avd->avd_val.boolval); 2796212Saw148015 2806212Saw148015 case AVD_VARVAL_BOOL: 2816212Saw148015 if (avd->avd_val.boolptr) 2826212Saw148015 return (*(avd->avd_val.boolptr)); 2836212Saw148015 else 2846212Saw148015 return (FALSE); 2856212Saw148015 2866212Saw148015 /* for backwards compatibility with old workloads */ 2876212Saw148015 case AVD_VAL_INT: 2886212Saw148015 if (avd->avd_val.intval != 0) 2896212Saw148015 return (TRUE); 2906212Saw148015 else 2916212Saw148015 return (FALSE); 2926212Saw148015 2936212Saw148015 case AVD_VARVAL_INT: 2946212Saw148015 if (avd->avd_val.intptr) 2956212Saw148015 if (*(avd->avd_val.intptr) != 0) 2966212Saw148015 return (TRUE); 2976212Saw148015 2986212Saw148015 return (FALSE); 2996212Saw148015 3006212Saw148015 case AVD_IND_VAR: 3016212Saw148015 if ((ivp = avd->avd_val.varptr) == NULL) 3026212Saw148015 return (0); 3036212Saw148015 3046212Saw148015 if (VAR_HAS_BOOLEAN(ivp)) 3056212Saw148015 return (ivp->var_val.boolean); 3066212Saw148015 3076212Saw148015 if (VAR_HAS_INTEGER(ivp)) { 3086212Saw148015 if (ivp->var_val.boolean) 3096212Saw148015 return (TRUE); 3106212Saw148015 else 3116212Saw148015 return (FALSE); 3126212Saw148015 } 3135184Sek110237 3146212Saw148015 filebench_log(LOG_ERROR, 3156212Saw148015 "Attempt to get boolean from %s var $%s", 3166212Saw148015 var_get_type_string(ivp), ivp->var_name); 3176212Saw148015 return (FALSE); 3186212Saw148015 3196212Saw148015 default: 3206212Saw148015 filebench_log(LOG_ERROR, 3216212Saw148015 "Attempt to get boolean from %s avd", 3226212Saw148015 avd_get_type_string(avd)); 3236212Saw148015 return (FALSE); 3246212Saw148015 } 3256212Saw148015 } 3266212Saw148015 3276212Saw148015 /* 3286212Saw148015 * Returns the string pointed to by the supplied avd_t "avd". 3296212Saw148015 */ 3306212Saw148015 char * 3316212Saw148015 avd_get_str(avd_t avd) 3326212Saw148015 { 3336212Saw148015 var_t *ivp; 3346212Saw148015 3356212Saw148015 if (avd == NULL) 3366212Saw148015 return (NULL); 3376212Saw148015 3386212Saw148015 switch (avd->avd_type) { 3396212Saw148015 case AVD_VAL_STR: 3406212Saw148015 return (avd->avd_val.strval); 3416212Saw148015 3426212Saw148015 case AVD_VARVAL_STR: 3436212Saw148015 if (avd->avd_val.strptr) 3446212Saw148015 return (*avd->avd_val.strptr); 3456212Saw148015 else 3466212Saw148015 return (NULL); 3476212Saw148015 3486212Saw148015 case AVD_IND_VAR: 3496212Saw148015 ivp = avd->avd_val.varptr; 3506212Saw148015 3516212Saw148015 if (ivp && VAR_HAS_STRING(ivp)) 3526212Saw148015 return (ivp->var_val.string); 3536212Saw148015 3546212Saw148015 filebench_log(LOG_ERROR, 3556212Saw148015 "Attempt to get string from %s var $%s", 3566212Saw148015 var_get_type_string(ivp), ivp->var_name); 3576212Saw148015 return (NULL); 3586212Saw148015 3596212Saw148015 default: 3606212Saw148015 filebench_log(LOG_ERROR, 3616212Saw148015 "Attempt to get string from %s avd", 3626212Saw148015 avd_get_type_string(avd)); 3635184Sek110237 return (NULL); 3645184Sek110237 } 3656212Saw148015 } 3665184Sek110237 3676212Saw148015 /* 3686212Saw148015 * Allocates a avd_t from ipc memory space. 3696212Saw148015 * logs an error and returns NULL on failure. 3706212Saw148015 */ 3716212Saw148015 static avd_t 3726212Saw148015 avd_alloc_cmn(void) 3736212Saw148015 { 3746212Saw148015 avd_t rtn; 3755184Sek110237 3766212Saw148015 if ((rtn = (avd_t)ipc_malloc(FILEBENCH_AVD)) == NULL) 3776212Saw148015 filebench_log(LOG_ERROR, "Avd alloc failed"); 3785184Sek110237 3795184Sek110237 return (rtn); 3805184Sek110237 } 3815184Sek110237 3825184Sek110237 /* 3836212Saw148015 * pre-loads the allocated avd_t with the boolean_t "bool". 3846212Saw148015 * Returns the avd_t on success, NULL on failure. 3856212Saw148015 */ 3866212Saw148015 avd_t 3876212Saw148015 avd_bool_alloc(boolean_t bool) 3886212Saw148015 { 3896212Saw148015 avd_t avd; 3906212Saw148015 3916212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 3926212Saw148015 return (NULL); 3936212Saw148015 3946212Saw148015 avd->avd_type = AVD_VAL_BOOL; 3956212Saw148015 avd->avd_val.boolval = bool; 3966212Saw148015 3976212Saw148015 filebench_log(LOG_DEBUG_IMPL, "Alloc boolean %d", bool); 3986212Saw148015 3996212Saw148015 return (avd); 4006212Saw148015 } 4016212Saw148015 4026212Saw148015 /* 4036212Saw148015 * pre-loads the allocated avd_t with the fbint_t "integer". 4046212Saw148015 * Returns the avd_t on success, NULL on failure. 4056212Saw148015 */ 4066212Saw148015 avd_t 4076212Saw148015 avd_int_alloc(fbint_t integer) 4086212Saw148015 { 4096212Saw148015 avd_t avd; 4106212Saw148015 4116212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 4126212Saw148015 return (NULL); 4136212Saw148015 4146212Saw148015 avd->avd_type = AVD_VAL_INT; 4156212Saw148015 avd->avd_val.intval = integer; 4166212Saw148015 4176286Saw148015 filebench_log(LOG_DEBUG_IMPL, "Alloc integer %llu", 4186286Saw148015 (u_longlong_t)integer); 4196212Saw148015 4206212Saw148015 return (avd); 4216212Saw148015 } 4226212Saw148015 4236212Saw148015 /* 4246212Saw148015 * Gets a avd_t and points it to the var that 4256212Saw148015 * it will eventually be filled from 4265184Sek110237 */ 4276212Saw148015 static avd_t 4286212Saw148015 avd_alloc_var_ptr(var_t *var) 4295184Sek110237 { 4306212Saw148015 avd_t avd; 4316212Saw148015 4326212Saw148015 if (var == NULL) 4336212Saw148015 return (NULL); 4346212Saw148015 4356212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 4366212Saw148015 return (NULL); 4376212Saw148015 4386212Saw148015 switch (var->var_type & VAR_TYPE_SET_MASK) { 4396212Saw148015 case VAR_TYPE_BOOL_SET: 4406212Saw148015 avd->avd_type = AVD_VARVAL_BOOL; 4416212Saw148015 avd->avd_val.boolptr = (&var->var_val.boolean); 4426212Saw148015 break; 4436212Saw148015 4446212Saw148015 case VAR_TYPE_INT_SET: 4456212Saw148015 avd->avd_type = AVD_VARVAL_INT; 4466212Saw148015 avd->avd_val.intptr = (&var->var_val.integer); 4476212Saw148015 break; 4486212Saw148015 4496212Saw148015 case VAR_TYPE_STR_SET: 4506212Saw148015 avd->avd_type = AVD_VARVAL_STR; 4516212Saw148015 avd->avd_val.strptr = &(var->var_val.string); 4526212Saw148015 break; 4535184Sek110237 4546212Saw148015 case VAR_TYPE_DBL_SET: 4556212Saw148015 avd->avd_type = AVD_VARVAL_DBL; 4566212Saw148015 avd->avd_val.dblptr = &(var->var_val.dbl_flt); 4576212Saw148015 break; 4586212Saw148015 4596212Saw148015 case VAR_TYPE_RAND_SET: 4606212Saw148015 avd->avd_type = AVD_IND_RANDVAR; 4616212Saw148015 avd->avd_val.randptr = var->var_val.randptr; 4626212Saw148015 break; 4636212Saw148015 464*6550Saw148015 case VAR_TYPE_INDVAR_SET: 465*6550Saw148015 avd->avd_type = AVD_IND_VAR; 466*6550Saw148015 avd->avd_val.varptr = var->var_val.varptr; 467*6550Saw148015 break; 468*6550Saw148015 4696212Saw148015 default: 4706212Saw148015 avd->avd_type = AVD_IND_VAR; 4716212Saw148015 avd->avd_val.varptr = var; 4726212Saw148015 break; 4736212Saw148015 } 4746212Saw148015 return (avd); 4756212Saw148015 } 4766212Saw148015 4776212Saw148015 /* 4786212Saw148015 * Gets a avd_t, then allocates and initializes a piece of 4796212Saw148015 * shared string memory, putting the pointer to it into the just 4806212Saw148015 * allocated string pointer location. The routine returns a pointer 4816212Saw148015 * to the string pointer location or returns NULL on error. 4826212Saw148015 */ 4836212Saw148015 avd_t 4846212Saw148015 avd_str_alloc(char *string) 4856212Saw148015 { 4866212Saw148015 avd_t avd; 4876212Saw148015 4886212Saw148015 if (string == NULL) { 4896212Saw148015 filebench_log(LOG_ERROR, "No string supplied\n"); 4905184Sek110237 return (NULL); 4915184Sek110237 } 4925184Sek110237 4936212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 4946212Saw148015 return (NULL); 4956212Saw148015 4966212Saw148015 avd->avd_type = AVD_VAL_STR; 4976212Saw148015 avd->avd_val.strval = ipc_stralloc(string); 4985184Sek110237 4995184Sek110237 filebench_log(LOG_DEBUG_IMPL, 5005184Sek110237 "Alloc string %s ptr %zx", 5016212Saw148015 string, avd); 5025184Sek110237 5036212Saw148015 return (avd); 5045184Sek110237 } 5055184Sek110237 5065184Sek110237 /* 5075184Sek110237 * Allocates a var (var_t) from interprocess shared memory. 5085184Sek110237 * Places the allocated var on the end of the globally shared 509*6550Saw148015 * shm_var_list. Finally, the routine allocates a string containing 5105184Sek110237 * a copy of the supplied "name" string. If any allocations 5115184Sek110237 * fails, returns NULL, otherwise it returns a pointer to the 5125184Sek110237 * newly allocated var. 5135184Sek110237 */ 5145184Sek110237 static var_t * 5156212Saw148015 var_alloc_cmn(char *name, int var_type) 5165184Sek110237 { 5176212Saw148015 var_t **var_listp; 5185184Sek110237 var_t *var = NULL; 5195184Sek110237 var_t *prev = NULL; 5205184Sek110237 var_t *newvar; 5215184Sek110237 5225184Sek110237 if ((newvar = (var_t *)ipc_malloc(FILEBENCH_VARIABLE)) == NULL) { 5235184Sek110237 filebench_log(LOG_ERROR, "Out of memory for variables"); 5245184Sek110237 return (NULL); 5255184Sek110237 } 5265184Sek110237 (void) memset(newvar, 0, sizeof (newvar)); 5276212Saw148015 newvar->var_type = var_type; 5285184Sek110237 5295184Sek110237 if ((newvar->var_name = ipc_stralloc(name)) == NULL) { 5305184Sek110237 filebench_log(LOG_ERROR, "Out of memory for variables"); 5315184Sek110237 return (NULL); 5325184Sek110237 } 5335184Sek110237 5346212Saw148015 switch (var_type & VAR_TYPE_MASK) { 5356212Saw148015 case VAR_TYPE_RANDOM: 5366212Saw148015 case VAR_TYPE_GLOBAL: 5376391Saw148015 var_listp = &filebench_shm->shm_var_list; 5386212Saw148015 break; 5396212Saw148015 5406212Saw148015 case VAR_TYPE_DYNAMIC: 5416391Saw148015 var_listp = &filebench_shm->shm_var_dyn_list; 5426212Saw148015 break; 5436212Saw148015 544*6550Saw148015 case VAR_TYPE_LOCAL: 545*6550Saw148015 /* place on head of shared local list */ 546*6550Saw148015 newvar->var_next = filebench_shm->shm_var_loc_list; 547*6550Saw148015 filebench_shm->shm_var_loc_list = newvar; 548*6550Saw148015 return (newvar); 549*6550Saw148015 5506212Saw148015 default: 5516391Saw148015 var_listp = &filebench_shm->shm_var_list; 5526212Saw148015 break; 5536212Saw148015 } 5546212Saw148015 5556212Saw148015 /* add to the end of list */ 5566212Saw148015 for (var = *var_listp; var != NULL; var = var->var_next) 5576212Saw148015 prev = var; /* Find end of list */ 5586212Saw148015 if (prev != NULL) 5596212Saw148015 prev->var_next = newvar; 5606212Saw148015 else 5616212Saw148015 *var_listp = newvar; 5626212Saw148015 5635184Sek110237 return (newvar); 5645184Sek110237 } 5655184Sek110237 5665184Sek110237 /* 567*6550Saw148015 * Allocates a var (var_t) from interprocess shared memory after 568*6550Saw148015 * first adjusting the name to elminate the leading $. Places the 569*6550Saw148015 * allocated var temporarily on the end of the globally 570*6550Saw148015 * shared var_loc_list. If the allocation fails, returns NULL, 571*6550Saw148015 * otherwise it returns a pointer to the newly allocated var. 572*6550Saw148015 */ 573*6550Saw148015 var_t * 574*6550Saw148015 var_lvar_alloc_local(char *name) 575*6550Saw148015 { 576*6550Saw148015 if (name[0] == '$') 577*6550Saw148015 name += 1; 578*6550Saw148015 579*6550Saw148015 return (var_alloc_cmn(name, VAR_TYPE_LOCAL)); 580*6550Saw148015 } 581*6550Saw148015 582*6550Saw148015 /* 5836212Saw148015 * Allocates a var (var_t) from interprocess shared memory and 5846212Saw148015 * places the allocated var on the end of the globally shared 585*6550Saw148015 * shm_var_list. If the allocation fails, returns NULL, otherwise 5866212Saw148015 * it returns a pointer to the newly allocated var. 5876212Saw148015 */ 5886212Saw148015 static var_t * 5896212Saw148015 var_alloc(char *name) 5906212Saw148015 { 5916212Saw148015 return (var_alloc_cmn(name, VAR_TYPE_GLOBAL)); 5926212Saw148015 } 5936212Saw148015 5946212Saw148015 /* 5955184Sek110237 * Allocates a var (var_t) from interprocess shared memory. 5965184Sek110237 * Places the allocated var on the end of the globally shared 597*6550Saw148015 * shm_var_dyn_list. If the allocation fails, returns NULL, otherwise 5986212Saw148015 * it returns a pointer to the newly allocated var. 5995184Sek110237 */ 6005184Sek110237 static var_t * 6015184Sek110237 var_alloc_dynamic(char *name) 6025184Sek110237 { 6036212Saw148015 return (var_alloc_cmn(name, VAR_TYPE_DYNAMIC)); 6045184Sek110237 } 6055184Sek110237 6065184Sek110237 /* 607*6550Saw148015 * Searches for var_t with name "name" in the shm_var_loc_list, 608*6550Saw148015 * then, if not found, in the global shm_var_list. If a matching 609*6550Saw148015 * local or global var is found, returns a pointer to the var_t, 610*6550Saw148015 * otherwise returns NULL. 6115184Sek110237 */ 6125184Sek110237 static var_t * 6135184Sek110237 var_find(char *name) 6145184Sek110237 { 6155184Sek110237 var_t *var; 6165184Sek110237 617*6550Saw148015 for (var = filebench_shm->shm_var_loc_list; var != NULL; 618*6550Saw148015 var = var->var_next) { 619*6550Saw148015 if (strcmp(var->var_name, name) == 0) 620*6550Saw148015 return (var); 621*6550Saw148015 } 622*6550Saw148015 6236391Saw148015 for (var = filebench_shm->shm_var_list; var != NULL; 6246391Saw148015 var = var->var_next) { 6255184Sek110237 if (strcmp(var->var_name, name) == 0) 6265184Sek110237 return (var); 6275184Sek110237 } 6285184Sek110237 6295184Sek110237 return (NULL); 6305184Sek110237 } 6315184Sek110237 6325184Sek110237 /* 633*6550Saw148015 * Searches for var_t with name "name" in the supplied shm_var_list. 634*6550Saw148015 * If not found there, checks the global list. If still 635*6550Saw148015 * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t. 636*6550Saw148015 */ 637*6550Saw148015 static var_t * 638*6550Saw148015 var_find_list_only(char *name, var_t *var_list) 639*6550Saw148015 { 640*6550Saw148015 var_t *var; 641*6550Saw148015 642*6550Saw148015 for (var = var_list; var != NULL; var = var->var_next) { 643*6550Saw148015 if (strcmp(var->var_name, name) == 0) 644*6550Saw148015 return (var); 645*6550Saw148015 } 646*6550Saw148015 647*6550Saw148015 return (NULL); 648*6550Saw148015 } 649*6550Saw148015 650*6550Saw148015 /* 651*6550Saw148015 * Searches for var_t with name "name" in the supplied shm_var_list. 652*6550Saw148015 * If not found there, checks the global list. If still 653*6550Saw148015 * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t. 654*6550Saw148015 */ 655*6550Saw148015 static var_t * 656*6550Saw148015 var_find_list(char *name, var_t *var_list) 657*6550Saw148015 { 658*6550Saw148015 var_t *var; 659*6550Saw148015 660*6550Saw148015 if ((var = var_find_list_only(name, var_list)) != NULL) 661*6550Saw148015 return (var); 662*6550Saw148015 else 663*6550Saw148015 return (var_find(name)); 664*6550Saw148015 } 665*6550Saw148015 666*6550Saw148015 /* 6675184Sek110237 * Searches for the named var, and, if found, sets its 6686212Saw148015 * var_val.boolean's value to that of the supplied boolean. 6695184Sek110237 * If not found, the routine allocates a new var and sets 6706212Saw148015 * its var_val.boolean's value to that of the supplied 6716212Saw148015 * boolean. If the named var cannot be found or allocated 6726212Saw148015 * the routine returns -1, otherwise it returns 0. 6735184Sek110237 */ 6745184Sek110237 int 6756212Saw148015 var_assign_boolean(char *name, boolean_t bool) 6765184Sek110237 { 6775184Sek110237 var_t *var; 6785184Sek110237 6796212Saw148015 if (name == NULL) { 6806212Saw148015 filebench_log(LOG_ERROR, 6816212Saw148015 "var_assign_boolean: Name not supplied"); 6826212Saw148015 return (0); 6836212Saw148015 } 6846212Saw148015 6855184Sek110237 name += 1; 6865184Sek110237 6876212Saw148015 if ((var = var_find(name)) == NULL) { 6886212Saw148015 var = var_alloc(name); 6896212Saw148015 } 6905184Sek110237 6915184Sek110237 if (var == NULL) { 6925184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 6935184Sek110237 name); 6945184Sek110237 return (-1); 6955184Sek110237 } 6965184Sek110237 6976212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 6986212Saw148015 filebench_log(LOG_ERROR, 6996212Saw148015 "Cannot assign integer to random variable %s", name); 7006212Saw148015 return (-1); 7016212Saw148015 } 7026212Saw148015 7036212Saw148015 VAR_SET_BOOL(var, bool); 7046212Saw148015 7056212Saw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign boolean %s=%d", 7066212Saw148015 name, bool); 7076212Saw148015 7086212Saw148015 return (0); 7096212Saw148015 } 7106212Saw148015 7116212Saw148015 /* 7126212Saw148015 * Searches for the named var, and, if found, sets its 7136212Saw148015 * var_integer's value to that of the supplied integer. 7146212Saw148015 * If not found, the routine allocates a new var and sets 7156212Saw148015 * its var_integers's value to that of the supplied 7166212Saw148015 * integer. If the named var cannot be found or allocated 7176212Saw148015 * the routine returns -1, otherwise it returns 0. 7186212Saw148015 */ 7196212Saw148015 int 7206212Saw148015 var_assign_integer(char *name, fbint_t integer) 7216212Saw148015 { 7226212Saw148015 var_t *var; 7236212Saw148015 7246212Saw148015 if (name == NULL) { 7256212Saw148015 filebench_log(LOG_ERROR, 7266212Saw148015 "var_assign_integer: Name not supplied"); 7276212Saw148015 return (0); 7286212Saw148015 } 7296212Saw148015 7306212Saw148015 name += 1; 7316212Saw148015 7326212Saw148015 if ((var = var_find(name)) == NULL) { 7336212Saw148015 var = var_alloc(name); 7346212Saw148015 } 7356212Saw148015 7366212Saw148015 if (var == NULL) { 7376212Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 7386212Saw148015 name); 7396212Saw148015 return (-1); 7406212Saw148015 } 7416212Saw148015 7426212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 7436212Saw148015 filebench_log(LOG_ERROR, 7446212Saw148015 "Cannot assign integer to random variable %s", name); 7456212Saw148015 return (-1); 7466212Saw148015 } 7476212Saw148015 7486212Saw148015 VAR_SET_INT(var, integer); 7495184Sek110237 7506286Saw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu", 7516286Saw148015 name, (u_longlong_t)integer); 7525184Sek110237 7535184Sek110237 return (0); 7545184Sek110237 } 7555184Sek110237 7565184Sek110237 /* 7576212Saw148015 * Find a variable, and set it to random type. 7586212Saw148015 * If it does not have a random extension, allocate one 7596212Saw148015 */ 7606212Saw148015 var_t * 7616212Saw148015 var_find_randvar(char *name) 7626212Saw148015 { 7636212Saw148015 var_t *newvar; 7646212Saw148015 7656212Saw148015 name += 1; 7666212Saw148015 7676212Saw148015 if ((newvar = var_find(name)) == NULL) { 7686212Saw148015 filebench_log(LOG_ERROR, 7696212Saw148015 "failed to locate random variable $%s\n", name); 7706212Saw148015 return (NULL); 7716212Saw148015 } 7726212Saw148015 7736212Saw148015 /* set randdist pointer unless it is already set */ 7746212Saw148015 if (((newvar->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) || 7756212Saw148015 !VAR_HAS_RANDDIST(newvar)) { 7766212Saw148015 filebench_log(LOG_ERROR, 7776212Saw148015 "Found variable $%s not random\n", name); 7786212Saw148015 return (NULL); 7796212Saw148015 } 7806212Saw148015 7816212Saw148015 return (newvar); 7826212Saw148015 } 7836212Saw148015 7846212Saw148015 /* 7856212Saw148015 * Allocate a variable, and set it to random type. Then 7866212Saw148015 * allocate a random extension. 7876212Saw148015 */ 7886212Saw148015 var_t * 7896212Saw148015 var_define_randvar(char *name) 7906212Saw148015 { 7916212Saw148015 var_t *newvar; 7926212Saw148015 randdist_t *rndp = NULL; 7936212Saw148015 7946212Saw148015 name += 1; 7956212Saw148015 7966212Saw148015 /* make sure variable doesn't already exist */ 7976212Saw148015 if (var_find(name) != NULL) { 7986212Saw148015 filebench_log(LOG_ERROR, 7996212Saw148015 "variable name already in use\n"); 8006212Saw148015 return (NULL); 8016212Saw148015 } 8026212Saw148015 8036212Saw148015 /* allocate a random variable */ 8046212Saw148015 if ((newvar = var_alloc_cmn(name, VAR_TYPE_RANDOM)) == NULL) { 8056212Saw148015 filebench_log(LOG_ERROR, 8066212Saw148015 "failed to alloc random variable\n"); 8076212Saw148015 return (NULL); 8086212Saw148015 } 8096212Saw148015 8106212Saw148015 /* set randdist pointer */ 8116212Saw148015 if ((rndp = randdist_alloc()) == NULL) { 8126212Saw148015 filebench_log(LOG_ERROR, 8136212Saw148015 "failed to alloc random distribution object\n"); 8146212Saw148015 return (NULL); 8156212Saw148015 } 8166212Saw148015 8176212Saw148015 rndp->rnd_var = newvar; 8186212Saw148015 VAR_SET_RAND(newvar, rndp); 8196212Saw148015 8206212Saw148015 return (newvar); 8216212Saw148015 } 8226212Saw148015 8236212Saw148015 /* 8246212Saw148015 * Searches for the named var, and if found returns an avd_t 8256212Saw148015 * pointing to the var's var_integer, var_string or var_double 8266212Saw148015 * as appropriate. If not found, attempts to allocate 8276212Saw148015 * a var named "name" and returns an avd_t to it with 8286212Saw148015 * no value set. If the var cannot be found or allocated, an 8295184Sek110237 * error is logged and the run is terminated. 8305184Sek110237 */ 8316212Saw148015 avd_t 8326212Saw148015 var_ref_attr(char *name) 8335184Sek110237 { 8345184Sek110237 var_t *var; 8355184Sek110237 8365184Sek110237 name += 1; 8375184Sek110237 8385184Sek110237 if ((var = var_find(name)) == NULL) 8395184Sek110237 var = var_find_dynamic(name); 8405184Sek110237 8415184Sek110237 if (var == NULL) 8425184Sek110237 var = var_alloc(name); 8435184Sek110237 8445184Sek110237 if (var == NULL) { 8455184Sek110237 filebench_log(LOG_ERROR, "Invalid variable $%s", 8465184Sek110237 name); 8475184Sek110237 filebench_shutdown(1); 8485184Sek110237 } 8495184Sek110237 8506212Saw148015 /* allocate pointer to var and return */ 8516212Saw148015 return (avd_alloc_var_ptr(var)); 8525184Sek110237 } 8535184Sek110237 8546212Saw148015 8555184Sek110237 /* 8566212Saw148015 * Searches for the named var, and if found copies the var_val.string, 8576212Saw148015 * if it exists, a decimal number string representation of 8586212Saw148015 * var_val.integer, the state of var_val.boolean, or the type of random 8596212Saw148015 * distribution employed, into a malloc'd bit of memory using fb_stralloc(). 8605184Sek110237 * Returns a pointer to the created string, or NULL on failure. 8615184Sek110237 */ 8625184Sek110237 char * 8635184Sek110237 var_to_string(char *name) 8645184Sek110237 { 8655184Sek110237 var_t *var; 8665184Sek110237 char tmp[128]; 8675184Sek110237 8685184Sek110237 name += 1; 8695184Sek110237 8705184Sek110237 if ((var = var_find(name)) == NULL) 8715184Sek110237 var = var_find_dynamic(name); 8725184Sek110237 8735184Sek110237 if (var == NULL) 8745184Sek110237 return (NULL); 8755184Sek110237 8766212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 8776212Saw148015 switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) { 8786212Saw148015 case RAND_TYPE_UNIFORM: 8796212Saw148015 return (fb_stralloc("uniform random var")); 8806212Saw148015 case RAND_TYPE_GAMMA: 8816212Saw148015 return (fb_stralloc("gamma random var")); 8826212Saw148015 case RAND_TYPE_TABLE: 8836212Saw148015 return (fb_stralloc("tabular random var")); 8846212Saw148015 default: 8856212Saw148015 return (fb_stralloc("unitialized random var")); 8866212Saw148015 } 8876212Saw148015 } 8885184Sek110237 8896212Saw148015 if (VAR_HAS_STRING(var) && var->var_val.string) 8906212Saw148015 return (fb_stralloc(var->var_val.string)); 8915184Sek110237 8926212Saw148015 if (VAR_HAS_BOOLEAN(var)) { 8936212Saw148015 if (var->var_val.boolean) 8946212Saw148015 return (fb_stralloc("true")); 8956212Saw148015 else 8966212Saw148015 return (fb_stralloc("false")); 8976212Saw148015 } 8986212Saw148015 8996212Saw148015 if (VAR_HAS_INTEGER(var)) { 9006286Saw148015 (void) snprintf(tmp, sizeof (tmp), "%llu", 9016286Saw148015 (u_longlong_t)var->var_val.integer); 9026212Saw148015 return (fb_stralloc(tmp)); 9036212Saw148015 } 9046212Saw148015 9056212Saw148015 return (fb_stralloc("No default")); 9065184Sek110237 } 9075184Sek110237 9085184Sek110237 /* 9095184Sek110237 * Searches for the named var, and if found returns the value, 9106212Saw148015 * of var_val.boolean. If the var is not found, or a boolean 9116212Saw148015 * value has not been set, logs an error and returns 0. 9125184Sek110237 */ 9136212Saw148015 boolean_t 9146212Saw148015 var_to_boolean(char *name) 9156212Saw148015 { 9166212Saw148015 var_t *var; 9176212Saw148015 9186212Saw148015 name += 1; 9196212Saw148015 9206212Saw148015 if ((var = var_find(name)) == NULL) 9216212Saw148015 var = var_find_dynamic(name); 9226212Saw148015 9236212Saw148015 if ((var != NULL) && VAR_HAS_BOOLEAN(var)) 9246212Saw148015 return (var->var_val.boolean); 9256212Saw148015 9266212Saw148015 filebench_log(LOG_ERROR, 9276212Saw148015 "Variable %s referenced before set", name); 9286212Saw148015 9296212Saw148015 return (0); 9306212Saw148015 } 9316212Saw148015 9326212Saw148015 /* 9336212Saw148015 * Searches for the named var, and if found returns the value, 9346212Saw148015 * of var_val.integer. If the var is not found, or the an 9356212Saw148015 * integer value has not been set, logs an error and returns 0. 9366212Saw148015 */ 9376212Saw148015 fbint_t 9385184Sek110237 var_to_integer(char *name) 9395184Sek110237 { 9405184Sek110237 var_t *var; 9415184Sek110237 9425184Sek110237 name += 1; 9435184Sek110237 9445184Sek110237 if ((var = var_find(name)) == NULL) 9455184Sek110237 var = var_find_dynamic(name); 9465184Sek110237 9476212Saw148015 if ((var != NULL) && VAR_HAS_INTEGER(var)) 9486212Saw148015 return (var->var_val.integer); 9495184Sek110237 9505184Sek110237 filebench_log(LOG_ERROR, 9515184Sek110237 "Variable %s referenced before set", name); 9525184Sek110237 9535184Sek110237 return (0); 9545184Sek110237 } 9555184Sek110237 9565184Sek110237 /* 9576212Saw148015 * Searches for the named random var, and if found, converts the 9586212Saw148015 * requested parameter into a string or a decimal number string 9596212Saw148015 * representation, into a malloc'd bit of memory using fb_stralloc(). 9606212Saw148015 * Returns a pointer to the created string, or calls var_to_string() 9616212Saw148015 * if a random variable isn't found. 9626212Saw148015 */ 9636212Saw148015 char * 9646212Saw148015 var_randvar_to_string(char *name, int param_name) 9656212Saw148015 { 9666212Saw148015 var_t *var; 9676212Saw148015 fbint_t value; 9686212Saw148015 9696212Saw148015 if ((var = var_find(name + 1)) == NULL) 9706212Saw148015 return (var_to_string(name)); 9716212Saw148015 9726212Saw148015 if (((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) || 9736212Saw148015 !VAR_HAS_RANDDIST(var)) 9746212Saw148015 return (var_to_string(name)); 9756212Saw148015 9766212Saw148015 switch (param_name) { 9776212Saw148015 case RAND_PARAM_TYPE: 9786212Saw148015 switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) { 9796212Saw148015 case RAND_TYPE_UNIFORM: 9806212Saw148015 return (fb_stralloc("uniform")); 9816212Saw148015 case RAND_TYPE_GAMMA: 9826212Saw148015 return (fb_stralloc("gamma")); 9836212Saw148015 case RAND_TYPE_TABLE: 9846212Saw148015 return (fb_stralloc("tabular")); 9856212Saw148015 default: 9866212Saw148015 return (fb_stralloc("uninitialized")); 9876212Saw148015 } 9886212Saw148015 9896212Saw148015 case RAND_PARAM_SRC: 9906212Saw148015 if (var->var_val.randptr->rnd_type & RAND_SRC_GENERATOR) 9916212Saw148015 return (fb_stralloc("rand48")); 9926212Saw148015 else 9936212Saw148015 return (fb_stralloc("urandom")); 9946212Saw148015 9956212Saw148015 case RAND_PARAM_SEED: 9966212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_seed); 9976212Saw148015 break; 9986212Saw148015 9996212Saw148015 case RAND_PARAM_MIN: 10006212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_min); 10016212Saw148015 break; 10026212Saw148015 10036212Saw148015 case RAND_PARAM_MEAN: 10046212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_mean); 10056212Saw148015 break; 10066212Saw148015 10076212Saw148015 case RAND_PARAM_GAMMA: 10086212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_gamma); 10096212Saw148015 break; 10106212Saw148015 10116212Saw148015 case RAND_PARAM_ROUND: 10126212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_round); 10136212Saw148015 break; 10146212Saw148015 10156212Saw148015 default: 10166212Saw148015 return (NULL); 10176212Saw148015 10186212Saw148015 } 10196212Saw148015 10206212Saw148015 /* just an integer value if we got here */ 10216212Saw148015 { 10226212Saw148015 char tmp[128]; 10236212Saw148015 10246286Saw148015 (void) snprintf(tmp, sizeof (tmp), "%llu", 10256286Saw148015 (u_longlong_t)value); 10266212Saw148015 return (fb_stralloc(tmp)); 10276212Saw148015 } 10286212Saw148015 } 10296212Saw148015 10306212Saw148015 /* 1031*6550Saw148015 * Copies the value stored in the source string into the destination 1032*6550Saw148015 * string. Returns -1 if any problems encountered, 0 otherwise. 1033*6550Saw148015 */ 1034*6550Saw148015 static int 1035*6550Saw148015 var_copy(var_t *dst_var, var_t *src_var) { 1036*6550Saw148015 1037*6550Saw148015 if (VAR_HAS_BOOLEAN(src_var)) { 1038*6550Saw148015 VAR_SET_BOOL(dst_var, src_var->var_val.boolean); 1039*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1040*6550Saw148015 "Assign var %s=%s", dst_var->var_name, 1041*6550Saw148015 dst_var->var_val.boolean?"true":"false"); 1042*6550Saw148015 } 1043*6550Saw148015 1044*6550Saw148015 if (VAR_HAS_INTEGER(src_var)) { 1045*6550Saw148015 VAR_SET_INT(dst_var, src_var->var_val.integer); 1046*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1047*6550Saw148015 "Assign var %s=%llu", dst_var->var_name, 1048*6550Saw148015 (u_longlong_t)dst_var->var_val.integer); 1049*6550Saw148015 } 1050*6550Saw148015 1051*6550Saw148015 if (VAR_HAS_DOUBLE(src_var)) { 1052*6550Saw148015 VAR_SET_DBL(dst_var, src_var->var_val.dbl_flt); 1053*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1054*6550Saw148015 "Assign var %s=%lf", dst_var->var_name, 1055*6550Saw148015 dst_var->var_val.dbl_flt); 1056*6550Saw148015 } 1057*6550Saw148015 1058*6550Saw148015 if (VAR_HAS_STRING(src_var)) { 1059*6550Saw148015 char *strptr; 1060*6550Saw148015 1061*6550Saw148015 if ((strptr = 1062*6550Saw148015 ipc_stralloc(src_var->var_val.string)) == NULL) { 1063*6550Saw148015 filebench_log(LOG_ERROR, 1064*6550Saw148015 "Cannot assign string for variable %s", 1065*6550Saw148015 dst_var->var_name); 1066*6550Saw148015 return (-1); 1067*6550Saw148015 } 1068*6550Saw148015 VAR_SET_STR(dst_var, strptr); 1069*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1070*6550Saw148015 "Assign var %s=%s", dst_var->var_name, 1071*6550Saw148015 dst_var->var_val.string); 1072*6550Saw148015 } 1073*6550Saw148015 1074*6550Saw148015 if (VAR_HAS_INDVAR(src_var)) { 1075*6550Saw148015 VAR_SET_INDVAR(dst_var, src_var->var_val.varptr); 1076*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1077*6550Saw148015 "Assign var %s to var %s", dst_var->var_name, 1078*6550Saw148015 src_var->var_name); 1079*6550Saw148015 } 1080*6550Saw148015 return (0); 1081*6550Saw148015 } 1082*6550Saw148015 1083*6550Saw148015 /* 10845184Sek110237 * Searches for the var named "name", and if not found 1085*6550Saw148015 * allocates it. The then copies the value from 1086*6550Saw148015 * the src_var into the destination var "name" 1087*6550Saw148015 * If the var "name" cannot be found or allocated, or the var "src_name" 1088*6550Saw148015 * cannot be found, the routine returns -1, otherwise it returns 0. 10895184Sek110237 */ 10905184Sek110237 int 10916212Saw148015 var_assign_var(char *name, char *src_name) 10925184Sek110237 { 10936212Saw148015 var_t *dst_var, *src_var; 10945184Sek110237 10955184Sek110237 name += 1; 10966212Saw148015 src_name += 1; 10975184Sek110237 10986212Saw148015 if ((src_var = var_find(src_name)) == NULL) { 10996212Saw148015 filebench_log(LOG_ERROR, 11006212Saw148015 "Cannot find source variable %s", src_name); 11016212Saw148015 return (-1); 11026212Saw148015 } 11035184Sek110237 11046212Saw148015 if ((dst_var = var_find(name)) == NULL) 11056212Saw148015 dst_var = var_alloc(name); 11066212Saw148015 11076212Saw148015 if (dst_var == NULL) { 11085184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 11095184Sek110237 name); 11105184Sek110237 return (-1); 11115184Sek110237 } 11125184Sek110237 11136212Saw148015 if ((dst_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 11146212Saw148015 filebench_log(LOG_ERROR, 11156212Saw148015 "Cannot assign var to Random variable %s", name); 11165184Sek110237 return (-1); 11175184Sek110237 } 11186212Saw148015 1119*6550Saw148015 return (var_copy(dst_var, src_var)); 11205184Sek110237 } 11215184Sek110237 11225184Sek110237 /* 11235184Sek110237 * Like var_assign_integer, only this routine copies the 11245184Sek110237 * supplied "string" into the var named "name". If the var 11255184Sek110237 * named "name" cannot be found then it is first allocated 11265184Sek110237 * before the copy. Space for the string in the var comes 11275184Sek110237 * from interprocess shared memory. If the var "name" 11285184Sek110237 * cannot be found or allocated, or the memory for the 1129*6550Saw148015 * var_val.string copy of "string" cannot be allocated, the 11305184Sek110237 * routine returns -1, otherwise it returns 0. 11315184Sek110237 */ 11325184Sek110237 int 11335184Sek110237 var_assign_string(char *name, char *string) 11345184Sek110237 { 11355184Sek110237 var_t *var; 11366212Saw148015 char *strptr; 11375184Sek110237 11385184Sek110237 name += 1; 11395184Sek110237 11405184Sek110237 if ((var = var_find(name)) == NULL) 11415184Sek110237 var = var_alloc(name); 11425184Sek110237 11435184Sek110237 if (var == NULL) { 11445184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 11455184Sek110237 name); 11465184Sek110237 return (-1); 11475184Sek110237 } 11485184Sek110237 11496212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 11506212Saw148015 filebench_log(LOG_ERROR, 11516212Saw148015 "Cannot assign string to random variable %s", name); 11526212Saw148015 return (-1); 11536212Saw148015 } 11546212Saw148015 11556212Saw148015 if ((strptr = ipc_stralloc(string)) == NULL) { 11565184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 11575184Sek110237 name); 11585184Sek110237 return (-1); 11595184Sek110237 } 11606212Saw148015 VAR_SET_STR(var, strptr); 11615184Sek110237 11626212Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 11636212Saw148015 "Var assign string $%s=%s", name, string); 11645184Sek110237 11655184Sek110237 return (0); 11665184Sek110237 } 11675184Sek110237 11685184Sek110237 /* 1169*6550Saw148015 * Allocates a local var. The then extracts the var_string from 1170*6550Saw148015 * the var named "string" and copies it into the var_string 1171*6550Saw148015 * of the var "name", after first allocating a piece of 1172*6550Saw148015 * interprocess shared string memory. Returns a pointer to the 1173*6550Saw148015 * newly allocated local var or NULL on error. 1174*6550Saw148015 */ 1175*6550Saw148015 var_t * 1176*6550Saw148015 var_lvar_assign_var(char *name, char *src_name) 1177*6550Saw148015 { 1178*6550Saw148015 var_t *dst_var, *src_var; 1179*6550Saw148015 1180*6550Saw148015 src_name += 1; 1181*6550Saw148015 1182*6550Saw148015 if ((src_var = var_find(src_name)) == NULL) { 1183*6550Saw148015 filebench_log(LOG_ERROR, 1184*6550Saw148015 "Cannot find source variable %s", src_name); 1185*6550Saw148015 return (NULL); 1186*6550Saw148015 } 1187*6550Saw148015 1188*6550Saw148015 dst_var = var_lvar_alloc_local(name); 1189*6550Saw148015 1190*6550Saw148015 if (dst_var == NULL) { 1191*6550Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1192*6550Saw148015 name); 1193*6550Saw148015 return (NULL); 1194*6550Saw148015 } 1195*6550Saw148015 1196*6550Saw148015 /* 1197*6550Saw148015 * if referencing another local var which is currently 1198*6550Saw148015 * empty, indirect to it 1199*6550Saw148015 */ 1200*6550Saw148015 if ((src_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_LOCAL) { 1201*6550Saw148015 VAR_SET_INDVAR(dst_var, src_var); 1202*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1203*6550Saw148015 "Assign local var %s to %s", name, src_name); 1204*6550Saw148015 return (dst_var); 1205*6550Saw148015 } 1206*6550Saw148015 1207*6550Saw148015 if (VAR_HAS_BOOLEAN(src_var)) { 1208*6550Saw148015 VAR_SET_BOOL(dst_var, src_var->var_val.boolean); 1209*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1210*6550Saw148015 "Assign var (%s, %p)=%s", name, 1211*6550Saw148015 dst_var, src_var->var_val.boolean?"true":"false"); 1212*6550Saw148015 } else if (VAR_HAS_INTEGER(src_var)) { 1213*6550Saw148015 VAR_SET_INT(dst_var, src_var->var_val.integer); 1214*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1215*6550Saw148015 "Assign var (%s, %p)=%llu", name, 1216*6550Saw148015 dst_var, (u_longlong_t)src_var->var_val.integer); 1217*6550Saw148015 } else if (VAR_HAS_STRING(src_var)) { 1218*6550Saw148015 char *strptr; 1219*6550Saw148015 1220*6550Saw148015 if ((strptr = ipc_stralloc(src_var->var_val.string)) == NULL) { 1221*6550Saw148015 filebench_log(LOG_ERROR, 1222*6550Saw148015 "Cannot assign variable %s", 1223*6550Saw148015 name); 1224*6550Saw148015 return (NULL); 1225*6550Saw148015 } 1226*6550Saw148015 VAR_SET_STR(dst_var, strptr); 1227*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1228*6550Saw148015 "Assign var (%s, %p)=%s", name, 1229*6550Saw148015 dst_var, src_var->var_val.string); 1230*6550Saw148015 } else if (VAR_HAS_DOUBLE(src_var)) { 1231*6550Saw148015 /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */ 1232*6550Saw148015 VAR_SET_INT(dst_var, src_var->var_val.dbl_flt); 1233*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1234*6550Saw148015 "Assign var (%s, %p)=%8.2f", name, 1235*6550Saw148015 dst_var, src_var->var_val.dbl_flt); 1236*6550Saw148015 } else if (VAR_HAS_RANDDIST(src_var)) { 1237*6550Saw148015 VAR_SET_RAND(dst_var, src_var->var_val.randptr); 1238*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1239*6550Saw148015 "Assign var (%s, %p)=%llu", name, 1240*6550Saw148015 dst_var, (u_longlong_t)src_var->var_val.integer); 1241*6550Saw148015 } 1242*6550Saw148015 1243*6550Saw148015 return (dst_var); 1244*6550Saw148015 } 1245*6550Saw148015 1246*6550Saw148015 /* 1247*6550Saw148015 * the routine allocates a new local var and sets 1248*6550Saw148015 * its var_boolean's value to that of the supplied 1249*6550Saw148015 * boolean. It returns a pointer to the new local var 1250*6550Saw148015 */ 1251*6550Saw148015 var_t * 1252*6550Saw148015 var_lvar_assign_boolean(char *name, boolean_t bool) 1253*6550Saw148015 { 1254*6550Saw148015 var_t *var; 1255*6550Saw148015 1256*6550Saw148015 var = var_lvar_alloc_local(name); 1257*6550Saw148015 1258*6550Saw148015 if (var == NULL) { 1259*6550Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1260*6550Saw148015 name); 1261*6550Saw148015 return (NULL); 1262*6550Saw148015 } 1263*6550Saw148015 1264*6550Saw148015 VAR_SET_BOOL(var, bool); 1265*6550Saw148015 1266*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%s", 1267*6550Saw148015 name, bool ? "true" : "false"); 1268*6550Saw148015 1269*6550Saw148015 return (var); 1270*6550Saw148015 } 1271*6550Saw148015 1272*6550Saw148015 /* 1273*6550Saw148015 * the routine allocates a new local var and sets 1274*6550Saw148015 * its var_integers's value to that of the supplied 1275*6550Saw148015 * integer. It returns a pointer to the new local var 1276*6550Saw148015 */ 1277*6550Saw148015 var_t * 1278*6550Saw148015 var_lvar_assign_integer(char *name, fbint_t integer) 1279*6550Saw148015 { 1280*6550Saw148015 var_t *var; 1281*6550Saw148015 1282*6550Saw148015 var = var_lvar_alloc_local(name); 1283*6550Saw148015 1284*6550Saw148015 if (var == NULL) { 1285*6550Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1286*6550Saw148015 name); 1287*6550Saw148015 return (NULL); 1288*6550Saw148015 } 1289*6550Saw148015 1290*6550Saw148015 VAR_SET_INT(var, integer); 1291*6550Saw148015 1292*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu", 1293*6550Saw148015 name, (u_longlong_t)integer); 1294*6550Saw148015 1295*6550Saw148015 return (var); 1296*6550Saw148015 } 1297*6550Saw148015 1298*6550Saw148015 /* 1299*6550Saw148015 * the routine allocates a new local var and sets 1300*6550Saw148015 * its var_dbl_flt value to that of the supplied 1301*6550Saw148015 * double precission floating point number. It returns 1302*6550Saw148015 * a pointer to the new local var 1303*6550Saw148015 */ 1304*6550Saw148015 var_t * 1305*6550Saw148015 var_lvar_assign_double(char *name, double dbl) 1306*6550Saw148015 { 1307*6550Saw148015 var_t *var; 1308*6550Saw148015 1309*6550Saw148015 var = var_lvar_alloc_local(name); 1310*6550Saw148015 1311*6550Saw148015 if (var == NULL) { 1312*6550Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1313*6550Saw148015 name); 1314*6550Saw148015 return (NULL); 1315*6550Saw148015 } 1316*6550Saw148015 1317*6550Saw148015 VAR_SET_DBL(var, dbl); 1318*6550Saw148015 1319*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%8.2f", name, dbl); 1320*6550Saw148015 1321*6550Saw148015 return (var); 1322*6550Saw148015 } 1323*6550Saw148015 1324*6550Saw148015 /* 1325*6550Saw148015 * Like var_lvar_assign_integer, only this routine copies the 1326*6550Saw148015 * supplied "string" into the var named "name". If the var 1327*6550Saw148015 * named "name" cannot be found then it is first allocated 1328*6550Saw148015 * before the copy. Space for the string in the var comes 1329*6550Saw148015 * from interprocess shared memory. The allocated local var 1330*6550Saw148015 * is returned at as a char *, or NULL on error. 1331*6550Saw148015 */ 1332*6550Saw148015 var_t * 1333*6550Saw148015 var_lvar_assign_string(char *name, char *string) 1334*6550Saw148015 { 1335*6550Saw148015 var_t *var; 1336*6550Saw148015 char *strptr; 1337*6550Saw148015 1338*6550Saw148015 var = var_lvar_alloc_local(name); 1339*6550Saw148015 1340*6550Saw148015 if (var == NULL) { 1341*6550Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1342*6550Saw148015 name); 1343*6550Saw148015 return (NULL); 1344*6550Saw148015 } 1345*6550Saw148015 1346*6550Saw148015 if ((strptr = ipc_stralloc(string)) == NULL) { 1347*6550Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 1348*6550Saw148015 name); 1349*6550Saw148015 return (NULL); 1350*6550Saw148015 } 1351*6550Saw148015 VAR_SET_STR(var, strptr); 1352*6550Saw148015 1353*6550Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 1354*6550Saw148015 "Lvar_assign_string (%s, %p)=%s", name, var, string); 1355*6550Saw148015 1356*6550Saw148015 return (var); 1357*6550Saw148015 } 1358*6550Saw148015 1359*6550Saw148015 /* 13606212Saw148015 * Tests to see if the supplied variable name without the portion after 13616212Saw148015 * the last period is that of a random variable. If it is, it returns 13626212Saw148015 * the number of characters to backspace to skip the period and field 13636212Saw148015 * name. Otherwise it returns 0. 13645184Sek110237 */ 13656212Saw148015 int 13666212Saw148015 var_is_set4_randvar(char *name) 13675184Sek110237 { 13685184Sek110237 var_t *var; 13696212Saw148015 char varname[128]; 13706212Saw148015 int namelength; 13716212Saw148015 char *sp; 13725184Sek110237 13736212Saw148015 (void) strncpy(varname, name, 128); 13746212Saw148015 namelength = strlen(varname); 13756212Saw148015 sp = varname + namelength; 13765184Sek110237 13776212Saw148015 while (sp != varname) { 13786212Saw148015 int c = *sp; 13795184Sek110237 13806212Saw148015 *sp = 0; 13816212Saw148015 if (c == '.') 13826212Saw148015 break; 13836212Saw148015 13846212Saw148015 sp--; 13855184Sek110237 } 13865184Sek110237 13876212Saw148015 /* not a variable name + field? */ 13886212Saw148015 if (sp == varname) 13896212Saw148015 return (0); 13906212Saw148015 13916212Saw148015 /* first part not a variable name? */ 13926212Saw148015 if ((var = var_find(varname+1)) == NULL) 13936212Saw148015 return (0); 13946212Saw148015 13956212Saw148015 /* Make sure it is a random variable */ 13966212Saw148015 if ((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) 13976212Saw148015 return (0); 13986212Saw148015 13996212Saw148015 /* calculate offset from end of random variable name */ 14006212Saw148015 return (namelength - (sp - varname)); 14015184Sek110237 } 14025184Sek110237 14035184Sek110237 /* 14045184Sek110237 * Implements a simple path name like scheme for finding values 14055184Sek110237 * to place in certain specially named vars. The first part of 14065184Sek110237 * the name is interpreted as a category of either: stats, 14075184Sek110237 * eventgen, date, script, or host var. If a match is found, 14085184Sek110237 * the appropriate routine is called to fill in the requested 14095184Sek110237 * value in the provided var_t, and a pointer to the supplied 14105184Sek110237 * var_t is returned. If the requested value is not found, NULL 14115184Sek110237 * is returned. 14125184Sek110237 */ 14135184Sek110237 static var_t * 14145184Sek110237 var_find_internal(var_t *var) 14155184Sek110237 { 14165184Sek110237 char *n = fb_stralloc(var->var_name); 14175184Sek110237 char *name = n; 14185184Sek110237 var_t *rtn = NULL; 14195184Sek110237 14205184Sek110237 name++; 14215184Sek110237 if (name[strlen(name) - 1] != '}') 14225184Sek110237 return (NULL); 14235184Sek110237 name[strlen(name) - 1] = 0; 14245184Sek110237 14255184Sek110237 if (strncmp(name, STATS_VAR, strlen(STATS_VAR)) == 0) 14265184Sek110237 rtn = stats_findvar(var, name + strlen(STATS_VAR)); 14275184Sek110237 14285184Sek110237 if (strcmp(name, EVENTGEN_VAR) == 0) 14295184Sek110237 rtn = eventgen_ratevar(var); 14305184Sek110237 14315184Sek110237 if (strcmp(name, DATE_VAR) == 0) 14325184Sek110237 rtn = date_var(var); 14335184Sek110237 14345184Sek110237 if (strcmp(name, SCRIPT_VAR) == 0) 14355184Sek110237 rtn = script_var(var); 14365184Sek110237 14375184Sek110237 if (strcmp(name, HOST_VAR) == 0) 14385184Sek110237 rtn = host_var(var); 14395184Sek110237 14405184Sek110237 free(n); 14415184Sek110237 14425184Sek110237 return (rtn); 14435184Sek110237 } 14445184Sek110237 14455184Sek110237 /* 14465184Sek110237 * Calls the C library routine getenv() to obtain the value 14475184Sek110237 * for the environment variable specified by var->var_name. 14486212Saw148015 * If found, the value string is returned in var->var_val.string. 14495184Sek110237 * If the requested value is not found, NULL is returned. 14505184Sek110237 */ 14515184Sek110237 static var_t * 14525184Sek110237 var_find_environment(var_t *var) 14535184Sek110237 { 14545184Sek110237 char *n = fb_stralloc(var->var_name); 14555184Sek110237 char *name = n; 14566212Saw148015 char *strptr; 14575184Sek110237 14585184Sek110237 name++; 14596212Saw148015 if (name[strlen(name) - 1] != ')') { 14606212Saw148015 free(n); 14615184Sek110237 return (NULL); 14626212Saw148015 } 14635184Sek110237 name[strlen(name) - 1] = 0; 14645184Sek110237 14656212Saw148015 if ((strptr = getenv(name)) != NULL) { 14665184Sek110237 free(n); 14676212Saw148015 VAR_SET_STR(var, strptr); 14685184Sek110237 return (var); 14695184Sek110237 } else { 14705184Sek110237 free(n); 14715184Sek110237 return (NULL); 14725184Sek110237 } 14735184Sek110237 } 14745184Sek110237 14755184Sek110237 /* 14765184Sek110237 * Look up special variables. The "name" argument is used to find 14775184Sek110237 * the desired special var and fill it with an appropriate string 14785184Sek110237 * value. Looks for an already allocated var of the same name on 1479*6550Saw148015 * the shm_var_dyn_list. If not found a new dynamic var is allocated. 14805184Sek110237 * if the name begins with '{', it is an internal variable, and 14815184Sek110237 * var_find_internal() is called. If the name begins with '(' it 14825184Sek110237 * is an environment varable, and var_find_environment() is 14835184Sek110237 * called. On success, a pointer to the var_t is returned, 14845184Sek110237 * otherwise, NULL is returned. 14855184Sek110237 */ 14865184Sek110237 static var_t * 14875184Sek110237 var_find_dynamic(char *name) 14885184Sek110237 { 14895184Sek110237 var_t *var = NULL; 14906391Saw148015 var_t *v = filebench_shm->shm_var_dyn_list; 14915184Sek110237 var_t *rtn; 14925184Sek110237 14935184Sek110237 /* 14945184Sek110237 * Lookup a reference to the var handle for this 14955184Sek110237 * special var 14965184Sek110237 */ 14976391Saw148015 for (v = filebench_shm->shm_var_dyn_list; v != NULL; v = v->var_next) { 14985184Sek110237 if (strcmp(v->var_name, name) == 0) { 14995184Sek110237 var = v; 15005184Sek110237 break; 15015184Sek110237 } 15025184Sek110237 } 15035184Sek110237 15045184Sek110237 if (var == NULL) 15055184Sek110237 var = var_alloc_dynamic(name); 15065184Sek110237 15075184Sek110237 /* Internal system control variable */ 15085184Sek110237 if (*name == '{') { 15095184Sek110237 rtn = var_find_internal(var); 15105184Sek110237 if (rtn == NULL) 15115184Sek110237 filebench_log(LOG_ERROR, 15125184Sek110237 "Cannot find internal variable %s", 15135184Sek110237 var->var_name); 15145184Sek110237 return (rtn); 15155184Sek110237 } 15165184Sek110237 15175184Sek110237 /* Lookup variable in environment */ 15185184Sek110237 if (*name == '(') { 15195184Sek110237 rtn = var_find_environment(var); 15205184Sek110237 if (rtn == NULL) 15215184Sek110237 filebench_log(LOG_ERROR, 15225184Sek110237 "Cannot find environment variable %s", 15235184Sek110237 var->var_name); 15245184Sek110237 return (rtn); 15255184Sek110237 } 15265184Sek110237 15275184Sek110237 return (NULL); 15285184Sek110237 } 1529*6550Saw148015 1530*6550Saw148015 /* 1531*6550Saw148015 * replace the avd_t attribute value descriptor in the new FLOW_MASTER flowop 1532*6550Saw148015 * that points to a local variable with a new avd_t containing 1533*6550Saw148015 * the actual value from the local variable. 1534*6550Saw148015 */ 1535*6550Saw148015 void 1536*6550Saw148015 avd_update(avd_t *avdp, var_t *lvar_list) 1537*6550Saw148015 { 1538*6550Saw148015 var_t *old_lvar, *new_lvar; 1539*6550Saw148015 1540*6550Saw148015 if ((*avdp)->avd_type == AVD_IND_VAR) { 1541*6550Saw148015 1542*6550Saw148015 /* Make sure there is a local var */ 1543*6550Saw148015 if ((old_lvar = (*avdp)->avd_val.varptr) == NULL) { 1544*6550Saw148015 filebench_log(LOG_ERROR, 1545*6550Saw148015 "avd_update: local var not found"); 1546*6550Saw148015 return; 1547*6550Saw148015 } 1548*6550Saw148015 } else { 1549*6550Saw148015 /* Empty or not indirect, so no update needed */ 1550*6550Saw148015 return; 1551*6550Saw148015 } 1552*6550Saw148015 1553*6550Saw148015 /* allocate a new avd using the new or old lvar contents */ 1554*6550Saw148015 if ((new_lvar = 1555*6550Saw148015 var_find_list(old_lvar->var_name, lvar_list)) != NULL) 1556*6550Saw148015 (*avdp) = avd_alloc_var_ptr(new_lvar); 1557*6550Saw148015 else 1558*6550Saw148015 (*avdp) = avd_alloc_var_ptr(old_lvar); 1559*6550Saw148015 } 1560*6550Saw148015 1561*6550Saw148015 void 1562*6550Saw148015 var_update_comp_lvars(var_t *newlvar, var_t *proto_comp_vars, 1563*6550Saw148015 var_t *mstr_lvars) 1564*6550Saw148015 { 1565*6550Saw148015 var_t *proto_lvar; 1566*6550Saw148015 1567*6550Saw148015 /* find the prototype lvar from the inherited list */ 1568*6550Saw148015 proto_lvar = var_find_list_only(newlvar->var_name, proto_comp_vars); 1569*6550Saw148015 1570*6550Saw148015 if (proto_lvar == NULL) 1571*6550Saw148015 return; 1572*6550Saw148015 1573*6550Saw148015 /* 1574*6550Saw148015 * if the new local variable has not already been assigned 1575*6550Saw148015 * a value, try to copy a value from the prototype local variable 1576*6550Saw148015 */ 1577*6550Saw148015 if ((newlvar->var_type & VAR_TYPE_SET_MASK) == 0) { 1578*6550Saw148015 1579*6550Saw148015 /* copy value from prototype lvar to new lvar */ 1580*6550Saw148015 (void) var_copy(newlvar, proto_lvar); 1581*6550Saw148015 } 1582*6550Saw148015 1583*6550Saw148015 /* If proto lvar is indirect, see if we can colapse indirection */ 1584*6550Saw148015 if (VAR_HAS_INDVAR(proto_lvar)) { 1585*6550Saw148015 var_t *uplvp; 1586*6550Saw148015 1587*6550Saw148015 uplvp = (var_t *)proto_lvar->var_val.varptr; 1588*6550Saw148015 1589*6550Saw148015 /* search for more current uplvar on comp master list */ 1590*6550Saw148015 if (mstr_lvars) { 1591*6550Saw148015 uplvp = var_find_list_only( 1592*6550Saw148015 uplvp->var_name, mstr_lvars); 1593*6550Saw148015 VAR_SET_INDVAR(newlvar, uplvp); 1594*6550Saw148015 } 1595*6550Saw148015 1596*6550Saw148015 if (VAR_HAS_INDVAR(uplvp)) 1597*6550Saw148015 VAR_SET_INDVAR(newlvar, uplvp->var_val.varptr); 1598*6550Saw148015 } 1599*6550Saw148015 } 1600