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 725184Sek110237 /* 736212Saw148015 * returns a pointer to a string indicating the type of data contained 746212Saw148015 * in the supplied attribute variable descriptor. 755184Sek110237 */ 766212Saw148015 static char * 776212Saw148015 avd_get_type_string(avd_t avd) 785184Sek110237 { 796212Saw148015 switch (avd->avd_type) { 806212Saw148015 case AVD_INVALID: 816212Saw148015 return ("uninitialized"); 826212Saw148015 836212Saw148015 case AVD_VAL_BOOL: 846212Saw148015 return ("boolean value"); 856212Saw148015 866212Saw148015 case AVD_VARVAL_BOOL: 876212Saw148015 return ("points to boolean in var_t"); 886212Saw148015 896212Saw148015 case AVD_VAL_INT: 906212Saw148015 return ("integer value"); 916212Saw148015 926212Saw148015 case AVD_VARVAL_INT: 936212Saw148015 return ("points to integer in var_t"); 946212Saw148015 956212Saw148015 case AVD_VAL_STR: 966212Saw148015 return ("string"); 976212Saw148015 986212Saw148015 case AVD_VARVAL_STR: 996212Saw148015 return ("points to string in var_t"); 1006212Saw148015 1016212Saw148015 case AVD_VAL_DBL: 1026212Saw148015 return ("double float value"); 1036212Saw148015 1046212Saw148015 case AVD_VARVAL_DBL: 1056212Saw148015 return ("points to double float in var_t"); 1066212Saw148015 1076212Saw148015 case AVD_IND_VAR: 1086212Saw148015 return ("points to a var_t"); 1096212Saw148015 1106212Saw148015 case AVD_IND_RANDVAR: 1116212Saw148015 return ("points to var_t's random distribution object"); 1126212Saw148015 1136212Saw148015 default: 1146212Saw148015 return ("illegal avd type"); 1156212Saw148015 } 1166212Saw148015 } 1176212Saw148015 1186212Saw148015 /* 1196212Saw148015 * returns a pointer to a string indicating the type of data contained 1206212Saw148015 * in the supplied variable. 1216212Saw148015 */ 1226212Saw148015 static char * 1236212Saw148015 var_get_type_string(var_t *ivp) 1246212Saw148015 { 1256212Saw148015 switch (ivp->var_type & VAR_TYPE_SET_MASK) { 1266212Saw148015 case VAR_TYPE_BOOL_SET: 1276212Saw148015 return ("boolean"); 1286212Saw148015 1296212Saw148015 case VAR_TYPE_INT_SET: 1306212Saw148015 return ("integer"); 1316212Saw148015 1326212Saw148015 case VAR_TYPE_STR_SET: 1336212Saw148015 return ("string"); 1346212Saw148015 1356212Saw148015 case VAR_TYPE_DBL_SET: 1366212Saw148015 return ("double float"); 1376212Saw148015 1386212Saw148015 case VAR_TYPE_RAND_SET: 1396212Saw148015 return ("random"); 1406212Saw148015 1416212Saw148015 default: 1426212Saw148015 return ("empty"); 1436212Saw148015 } 1446212Saw148015 } 1456212Saw148015 1466212Saw148015 /* 1476212Saw148015 * Returns the fbint_t pointed to by the supplied avd_t "avd". 1486212Saw148015 */ 1496212Saw148015 fbint_t 1506212Saw148015 avd_get_int(avd_t avd) 1516212Saw148015 { 1526212Saw148015 var_t *ivp; 1536212Saw148015 randdist_t *rndp; 1546212Saw148015 1556212Saw148015 if (avd == NULL) 1565184Sek110237 return (0); 1575184Sek110237 1586212Saw148015 switch (avd->avd_type) { 1596212Saw148015 case AVD_VAL_INT: 1606212Saw148015 return (avd->avd_val.intval); 1616212Saw148015 1626212Saw148015 case AVD_VARVAL_INT: 1636212Saw148015 if (avd->avd_val.intptr) 1646212Saw148015 return (*(avd->avd_val.intptr)); 1656212Saw148015 else 1666212Saw148015 return (0); 1676212Saw148015 1686212Saw148015 case AVD_IND_VAR: 1696212Saw148015 if ((ivp = avd->avd_val.varptr) == NULL) 1706212Saw148015 return (0); 1716212Saw148015 1726212Saw148015 if (VAR_HAS_INTEGER(ivp)) 1736212Saw148015 return (ivp->var_val.integer); 1746212Saw148015 1756212Saw148015 if (VAR_HAS_RANDDIST(ivp)) { 1766212Saw148015 if ((rndp = ivp->var_val.randptr) != NULL) 1776212Saw148015 return ((fbint_t)rndp->rnd_get(rndp)); 1786212Saw148015 } 1796212Saw148015 1806212Saw148015 filebench_log(LOG_ERROR, 1816212Saw148015 "Attempt to get integer from %s var $%s", 1826212Saw148015 var_get_type_string(ivp), ivp->var_name); 1836212Saw148015 return (0); 1846212Saw148015 1856212Saw148015 case AVD_IND_RANDVAR: 1866212Saw148015 if ((rndp = avd->avd_val.randptr) == NULL) 1876212Saw148015 return (0); 1886212Saw148015 else 1896212Saw148015 return ((fbint_t)rndp->rnd_get(rndp)); 1906212Saw148015 1916212Saw148015 default: 1926212Saw148015 filebench_log(LOG_ERROR, 1936212Saw148015 "Attempt to get integer from %s avd", 1946212Saw148015 avd_get_type_string(avd)); 1956212Saw148015 return (0); 1966212Saw148015 } 1975184Sek110237 } 1985184Sek110237 1995184Sek110237 /* 2006212Saw148015 * Returns the floating point value of a variable pointed to by the 2016212Saw148015 * supplied avd_t "avd". Intended to get the actual (double) value 2026212Saw148015 * supplied by the random variable. 2036212Saw148015 */ 2046212Saw148015 double 2056212Saw148015 avd_get_dbl(avd_t avd) 2066212Saw148015 { 2076212Saw148015 var_t *ivp; 2086212Saw148015 randdist_t *rndp; 2096212Saw148015 2106212Saw148015 if (avd == NULL) 2116212Saw148015 return (0.0); 2126212Saw148015 2136212Saw148015 switch (avd->avd_type) { 2146212Saw148015 case AVD_VAL_INT: 2156212Saw148015 return ((double)avd->avd_val.intval); 2166212Saw148015 2176212Saw148015 case AVD_VAL_DBL: 2186212Saw148015 return (avd->avd_val.dblval); 2196212Saw148015 2206212Saw148015 case AVD_VARVAL_INT: 2216212Saw148015 if (avd->avd_val.intptr) 2226212Saw148015 return ((double)(*(avd->avd_val.intptr))); 2236212Saw148015 else 2246212Saw148015 return (0.0); 2256212Saw148015 2266212Saw148015 case AVD_VARVAL_DBL: 2276212Saw148015 if (avd->avd_val.dblptr) 2286212Saw148015 return (*(avd->avd_val.dblptr)); 2296212Saw148015 else 2306212Saw148015 return (0.0); 2316212Saw148015 2326212Saw148015 case AVD_IND_VAR: 2336212Saw148015 ivp = avd->avd_val.varptr; 2346212Saw148015 2356212Saw148015 if (ivp && VAR_HAS_INTEGER(ivp)) 2366212Saw148015 return ((double)ivp->var_val.integer); 2376212Saw148015 2386212Saw148015 if (ivp && VAR_HAS_DOUBLE(ivp)) 2396212Saw148015 return (ivp->var_val.dbl_flt); 2406212Saw148015 2416212Saw148015 if (ivp && VAR_HAS_RANDDIST(ivp)) { 2426212Saw148015 if ((rndp = ivp->var_val.randptr) != NULL) 2436212Saw148015 return (rndp->rnd_get(rndp)); 2446212Saw148015 } 2456212Saw148015 filebench_log(LOG_ERROR, 2466212Saw148015 "Attempt to get double float from %s var $%s", 2476212Saw148015 var_get_type_string(ivp), ivp->var_name); 2486212Saw148015 return (0.0); 2496212Saw148015 2506212Saw148015 case AVD_IND_RANDVAR: 2516212Saw148015 if ((rndp = avd->avd_val.randptr) == NULL) { 2526212Saw148015 return (0.0); 2536212Saw148015 } else 2546212Saw148015 return (rndp->rnd_get(rndp)); 2556212Saw148015 2566212Saw148015 default: 2576212Saw148015 filebench_log(LOG_ERROR, 2586212Saw148015 "Attempt to get floating point from %s avd", 2596212Saw148015 avd_get_type_string(avd)); 2606212Saw148015 return (0.0); 2616212Saw148015 } 2626212Saw148015 } 2636212Saw148015 2646212Saw148015 /* 2656212Saw148015 * Returns the boolean pointed to by the supplied avd_t "avd". 2665184Sek110237 */ 2676212Saw148015 boolean_t 2686212Saw148015 avd_get_bool(avd_t avd) 2695184Sek110237 { 2706212Saw148015 var_t *ivp; 2716212Saw148015 2726212Saw148015 if (avd == NULL) 2736212Saw148015 return (0); 2746212Saw148015 2756212Saw148015 switch (avd->avd_type) { 2766212Saw148015 case AVD_VAL_BOOL: 2776212Saw148015 return (avd->avd_val.boolval); 2786212Saw148015 2796212Saw148015 case AVD_VARVAL_BOOL: 2806212Saw148015 if (avd->avd_val.boolptr) 2816212Saw148015 return (*(avd->avd_val.boolptr)); 2826212Saw148015 else 2836212Saw148015 return (FALSE); 2846212Saw148015 2856212Saw148015 /* for backwards compatibility with old workloads */ 2866212Saw148015 case AVD_VAL_INT: 2876212Saw148015 if (avd->avd_val.intval != 0) 2886212Saw148015 return (TRUE); 2896212Saw148015 else 2906212Saw148015 return (FALSE); 2916212Saw148015 2926212Saw148015 case AVD_VARVAL_INT: 2936212Saw148015 if (avd->avd_val.intptr) 2946212Saw148015 if (*(avd->avd_val.intptr) != 0) 2956212Saw148015 return (TRUE); 2966212Saw148015 2976212Saw148015 return (FALSE); 2986212Saw148015 2996212Saw148015 case AVD_IND_VAR: 3006212Saw148015 if ((ivp = avd->avd_val.varptr) == NULL) 3016212Saw148015 return (0); 3026212Saw148015 3036212Saw148015 if (VAR_HAS_BOOLEAN(ivp)) 3046212Saw148015 return (ivp->var_val.boolean); 3056212Saw148015 3066212Saw148015 if (VAR_HAS_INTEGER(ivp)) { 3076212Saw148015 if (ivp->var_val.boolean) 3086212Saw148015 return (TRUE); 3096212Saw148015 else 3106212Saw148015 return (FALSE); 3116212Saw148015 } 3125184Sek110237 3136212Saw148015 filebench_log(LOG_ERROR, 3146212Saw148015 "Attempt to get boolean from %s var $%s", 3156212Saw148015 var_get_type_string(ivp), ivp->var_name); 3166212Saw148015 return (FALSE); 3176212Saw148015 3186212Saw148015 default: 3196212Saw148015 filebench_log(LOG_ERROR, 3206212Saw148015 "Attempt to get boolean from %s avd", 3216212Saw148015 avd_get_type_string(avd)); 3226212Saw148015 return (FALSE); 3236212Saw148015 } 3246212Saw148015 } 3256212Saw148015 3266212Saw148015 /* 3276212Saw148015 * Returns the string pointed to by the supplied avd_t "avd". 3286212Saw148015 */ 3296212Saw148015 char * 3306212Saw148015 avd_get_str(avd_t avd) 3316212Saw148015 { 3326212Saw148015 var_t *ivp; 3336212Saw148015 3346212Saw148015 if (avd == NULL) 3356212Saw148015 return (NULL); 3366212Saw148015 3376212Saw148015 switch (avd->avd_type) { 3386212Saw148015 case AVD_VAL_STR: 3396212Saw148015 return (avd->avd_val.strval); 3406212Saw148015 3416212Saw148015 case AVD_VARVAL_STR: 3426212Saw148015 if (avd->avd_val.strptr) 3436212Saw148015 return (*avd->avd_val.strptr); 3446212Saw148015 else 3456212Saw148015 return (NULL); 3466212Saw148015 3476212Saw148015 case AVD_IND_VAR: 3486212Saw148015 ivp = avd->avd_val.varptr; 3496212Saw148015 3506212Saw148015 if (ivp && VAR_HAS_STRING(ivp)) 3516212Saw148015 return (ivp->var_val.string); 3526212Saw148015 3536212Saw148015 filebench_log(LOG_ERROR, 3546212Saw148015 "Attempt to get string from %s var $%s", 3556212Saw148015 var_get_type_string(ivp), ivp->var_name); 3566212Saw148015 return (NULL); 3576212Saw148015 3586212Saw148015 default: 3596212Saw148015 filebench_log(LOG_ERROR, 3606212Saw148015 "Attempt to get string from %s avd", 3616212Saw148015 avd_get_type_string(avd)); 3625184Sek110237 return (NULL); 3635184Sek110237 } 3646212Saw148015 } 3655184Sek110237 3666212Saw148015 /* 3676212Saw148015 * Allocates a avd_t from ipc memory space. 3686212Saw148015 * logs an error and returns NULL on failure. 3696212Saw148015 */ 3706212Saw148015 static avd_t 3716212Saw148015 avd_alloc_cmn(void) 3726212Saw148015 { 3736212Saw148015 avd_t rtn; 3745184Sek110237 3756212Saw148015 if ((rtn = (avd_t)ipc_malloc(FILEBENCH_AVD)) == NULL) 3766212Saw148015 filebench_log(LOG_ERROR, "Avd alloc failed"); 3775184Sek110237 3785184Sek110237 return (rtn); 3795184Sek110237 } 3805184Sek110237 3815184Sek110237 /* 3826212Saw148015 * pre-loads the allocated avd_t with the boolean_t "bool". 3836212Saw148015 * Returns the avd_t on success, NULL on failure. 3846212Saw148015 */ 3856212Saw148015 avd_t 3866212Saw148015 avd_bool_alloc(boolean_t bool) 3876212Saw148015 { 3886212Saw148015 avd_t avd; 3896212Saw148015 3906212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 3916212Saw148015 return (NULL); 3926212Saw148015 3936212Saw148015 avd->avd_type = AVD_VAL_BOOL; 3946212Saw148015 avd->avd_val.boolval = bool; 3956212Saw148015 3966212Saw148015 filebench_log(LOG_DEBUG_IMPL, "Alloc boolean %d", bool); 3976212Saw148015 3986212Saw148015 return (avd); 3996212Saw148015 } 4006212Saw148015 4016212Saw148015 /* 4026212Saw148015 * pre-loads the allocated avd_t with the fbint_t "integer". 4036212Saw148015 * Returns the avd_t on success, NULL on failure. 4046212Saw148015 */ 4056212Saw148015 avd_t 4066212Saw148015 avd_int_alloc(fbint_t integer) 4076212Saw148015 { 4086212Saw148015 avd_t avd; 4096212Saw148015 4106212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 4116212Saw148015 return (NULL); 4126212Saw148015 4136212Saw148015 avd->avd_type = AVD_VAL_INT; 4146212Saw148015 avd->avd_val.intval = integer; 4156212Saw148015 4166286Saw148015 filebench_log(LOG_DEBUG_IMPL, "Alloc integer %llu", 4176286Saw148015 (u_longlong_t)integer); 4186212Saw148015 4196212Saw148015 return (avd); 4206212Saw148015 } 4216212Saw148015 4226212Saw148015 /* 4236212Saw148015 * Gets a avd_t and points it to the var that 4246212Saw148015 * it will eventually be filled from 4255184Sek110237 */ 4266212Saw148015 static avd_t 4276212Saw148015 avd_alloc_var_ptr(var_t *var) 4285184Sek110237 { 4296212Saw148015 avd_t avd; 4306212Saw148015 4316212Saw148015 if (var == NULL) 4326212Saw148015 return (NULL); 4336212Saw148015 4346212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 4356212Saw148015 return (NULL); 4366212Saw148015 4376212Saw148015 switch (var->var_type & VAR_TYPE_SET_MASK) { 4386212Saw148015 case VAR_TYPE_BOOL_SET: 4396212Saw148015 avd->avd_type = AVD_VARVAL_BOOL; 4406212Saw148015 avd->avd_val.boolptr = (&var->var_val.boolean); 4416212Saw148015 break; 4426212Saw148015 4436212Saw148015 case VAR_TYPE_INT_SET: 4446212Saw148015 avd->avd_type = AVD_VARVAL_INT; 4456212Saw148015 avd->avd_val.intptr = (&var->var_val.integer); 4466212Saw148015 break; 4476212Saw148015 4486212Saw148015 case VAR_TYPE_STR_SET: 4496212Saw148015 avd->avd_type = AVD_VARVAL_STR; 4506212Saw148015 avd->avd_val.strptr = &(var->var_val.string); 4516212Saw148015 break; 4525184Sek110237 4536212Saw148015 case VAR_TYPE_DBL_SET: 4546212Saw148015 avd->avd_type = AVD_VARVAL_DBL; 4556212Saw148015 avd->avd_val.dblptr = &(var->var_val.dbl_flt); 4566212Saw148015 break; 4576212Saw148015 4586212Saw148015 case VAR_TYPE_RAND_SET: 4596212Saw148015 avd->avd_type = AVD_IND_RANDVAR; 4606212Saw148015 avd->avd_val.randptr = var->var_val.randptr; 4616212Saw148015 break; 4626212Saw148015 4636212Saw148015 default: 4646212Saw148015 avd->avd_type = AVD_IND_VAR; 4656212Saw148015 avd->avd_val.varptr = var; 4666212Saw148015 break; 4676212Saw148015 } 4686212Saw148015 return (avd); 4696212Saw148015 } 4706212Saw148015 4716212Saw148015 /* 4726212Saw148015 * Gets a avd_t, then allocates and initializes a piece of 4736212Saw148015 * shared string memory, putting the pointer to it into the just 4746212Saw148015 * allocated string pointer location. The routine returns a pointer 4756212Saw148015 * to the string pointer location or returns NULL on error. 4766212Saw148015 */ 4776212Saw148015 avd_t 4786212Saw148015 avd_str_alloc(char *string) 4796212Saw148015 { 4806212Saw148015 avd_t avd; 4816212Saw148015 4826212Saw148015 if (string == NULL) { 4836212Saw148015 filebench_log(LOG_ERROR, "No string supplied\n"); 4845184Sek110237 return (NULL); 4855184Sek110237 } 4865184Sek110237 4876212Saw148015 if ((avd = avd_alloc_cmn()) == NULL) 4886212Saw148015 return (NULL); 4896212Saw148015 4906212Saw148015 avd->avd_type = AVD_VAL_STR; 4916212Saw148015 avd->avd_val.strval = ipc_stralloc(string); 4925184Sek110237 4935184Sek110237 filebench_log(LOG_DEBUG_IMPL, 4945184Sek110237 "Alloc string %s ptr %zx", 4956212Saw148015 string, avd); 4965184Sek110237 4976212Saw148015 return (avd); 4985184Sek110237 } 4995184Sek110237 5005184Sek110237 /* 5015184Sek110237 * Allocates a var (var_t) from interprocess shared memory. 5025184Sek110237 * Places the allocated var on the end of the globally shared 5035184Sek110237 * var_list. Finally, the routine allocates a string containing 5045184Sek110237 * a copy of the supplied "name" string. If any allocations 5055184Sek110237 * fails, returns NULL, otherwise it returns a pointer to the 5065184Sek110237 * newly allocated var. 5075184Sek110237 */ 5085184Sek110237 static var_t * 5096212Saw148015 var_alloc_cmn(char *name, int var_type) 5105184Sek110237 { 5116212Saw148015 var_t **var_listp; 5125184Sek110237 var_t *var = NULL; 5135184Sek110237 var_t *prev = NULL; 5145184Sek110237 var_t *newvar; 5155184Sek110237 5165184Sek110237 if ((newvar = (var_t *)ipc_malloc(FILEBENCH_VARIABLE)) == NULL) { 5175184Sek110237 filebench_log(LOG_ERROR, "Out of memory for variables"); 5185184Sek110237 return (NULL); 5195184Sek110237 } 5205184Sek110237 (void) memset(newvar, 0, sizeof (newvar)); 5216212Saw148015 newvar->var_type = var_type; 5225184Sek110237 5235184Sek110237 if ((newvar->var_name = ipc_stralloc(name)) == NULL) { 5245184Sek110237 filebench_log(LOG_ERROR, "Out of memory for variables"); 5255184Sek110237 return (NULL); 5265184Sek110237 } 5275184Sek110237 5286212Saw148015 switch (var_type & VAR_TYPE_MASK) { 5296212Saw148015 case VAR_TYPE_RANDOM: 5306212Saw148015 case VAR_TYPE_GLOBAL: 531*6391Saw148015 var_listp = &filebench_shm->shm_var_list; 5326212Saw148015 break; 5336212Saw148015 5346212Saw148015 case VAR_TYPE_DYNAMIC: 535*6391Saw148015 var_listp = &filebench_shm->shm_var_dyn_list; 5366212Saw148015 break; 5376212Saw148015 5386212Saw148015 default: 539*6391Saw148015 var_listp = &filebench_shm->shm_var_list; 5406212Saw148015 break; 5416212Saw148015 } 5426212Saw148015 5436212Saw148015 /* add to the end of list */ 5446212Saw148015 for (var = *var_listp; var != NULL; var = var->var_next) 5456212Saw148015 prev = var; /* Find end of list */ 5466212Saw148015 if (prev != NULL) 5476212Saw148015 prev->var_next = newvar; 5486212Saw148015 else 5496212Saw148015 *var_listp = newvar; 5506212Saw148015 5515184Sek110237 return (newvar); 5525184Sek110237 } 5535184Sek110237 5545184Sek110237 /* 5556212Saw148015 * Allocates a var (var_t) from interprocess shared memory and 5566212Saw148015 * places the allocated var on the end of the globally shared 5576212Saw148015 * var_list. If the allocation fails, returns NULL, otherwise 5586212Saw148015 * it returns a pointer to the newly allocated var. 5596212Saw148015 */ 5606212Saw148015 static var_t * 5616212Saw148015 var_alloc(char *name) 5626212Saw148015 { 5636212Saw148015 return (var_alloc_cmn(name, VAR_TYPE_GLOBAL)); 5646212Saw148015 } 5656212Saw148015 5666212Saw148015 /* 5675184Sek110237 * Allocates a var (var_t) from interprocess shared memory. 5685184Sek110237 * Places the allocated var on the end of the globally shared 5696212Saw148015 * var_dyn_list. If the allocation fails, returns NULL, otherwise 5706212Saw148015 * it returns a pointer to the newly allocated var. 5715184Sek110237 */ 5725184Sek110237 static var_t * 5735184Sek110237 var_alloc_dynamic(char *name) 5745184Sek110237 { 5756212Saw148015 return (var_alloc_cmn(name, VAR_TYPE_DYNAMIC)); 5765184Sek110237 } 5775184Sek110237 5785184Sek110237 /* 5795184Sek110237 * Searches for var_t with name "name" in the master var_list. 5805184Sek110237 * If successful, returns a pointer to the var_t, otherwise 5815184Sek110237 * returns NULL. 5825184Sek110237 */ 5835184Sek110237 static var_t * 5845184Sek110237 var_find(char *name) 5855184Sek110237 { 5865184Sek110237 var_t *var; 5875184Sek110237 588*6391Saw148015 for (var = filebench_shm->shm_var_list; var != NULL; 589*6391Saw148015 var = var->var_next) { 5905184Sek110237 if (strcmp(var->var_name, name) == 0) 5915184Sek110237 return (var); 5925184Sek110237 } 5935184Sek110237 5945184Sek110237 return (NULL); 5955184Sek110237 } 5965184Sek110237 5975184Sek110237 /* 5985184Sek110237 * Searches for the named var, and, if found, sets its 5996212Saw148015 * var_val.boolean's value to that of the supplied boolean. 6005184Sek110237 * If not found, the routine allocates a new var and sets 6016212Saw148015 * its var_val.boolean's value to that of the supplied 6026212Saw148015 * boolean. If the named var cannot be found or allocated 6036212Saw148015 * the routine returns -1, otherwise it returns 0. 6045184Sek110237 */ 6055184Sek110237 int 6066212Saw148015 var_assign_boolean(char *name, boolean_t bool) 6075184Sek110237 { 6085184Sek110237 var_t *var; 6095184Sek110237 6106212Saw148015 if (name == NULL) { 6116212Saw148015 filebench_log(LOG_ERROR, 6126212Saw148015 "var_assign_boolean: Name not supplied"); 6136212Saw148015 return (0); 6146212Saw148015 } 6156212Saw148015 6165184Sek110237 name += 1; 6175184Sek110237 6186212Saw148015 if ((var = var_find(name)) == NULL) { 6196212Saw148015 var = var_alloc(name); 6206212Saw148015 } 6215184Sek110237 6225184Sek110237 if (var == NULL) { 6235184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 6245184Sek110237 name); 6255184Sek110237 return (-1); 6265184Sek110237 } 6275184Sek110237 6286212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 6296212Saw148015 filebench_log(LOG_ERROR, 6306212Saw148015 "Cannot assign integer to random variable %s", name); 6316212Saw148015 return (-1); 6326212Saw148015 } 6336212Saw148015 6346212Saw148015 VAR_SET_BOOL(var, bool); 6356212Saw148015 6366212Saw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign boolean %s=%d", 6376212Saw148015 name, bool); 6386212Saw148015 6396212Saw148015 return (0); 6406212Saw148015 } 6416212Saw148015 6426212Saw148015 /* 6436212Saw148015 * Searches for the named var, and, if found, sets its 6446212Saw148015 * var_integer's value to that of the supplied integer. 6456212Saw148015 * If not found, the routine allocates a new var and sets 6466212Saw148015 * its var_integers's value to that of the supplied 6476212Saw148015 * integer. If the named var cannot be found or allocated 6486212Saw148015 * the routine returns -1, otherwise it returns 0. 6496212Saw148015 */ 6506212Saw148015 int 6516212Saw148015 var_assign_integer(char *name, fbint_t integer) 6526212Saw148015 { 6536212Saw148015 var_t *var; 6546212Saw148015 6556212Saw148015 if (name == NULL) { 6566212Saw148015 filebench_log(LOG_ERROR, 6576212Saw148015 "var_assign_integer: Name not supplied"); 6586212Saw148015 return (0); 6596212Saw148015 } 6606212Saw148015 6616212Saw148015 name += 1; 6626212Saw148015 6636212Saw148015 if ((var = var_find(name)) == NULL) { 6646212Saw148015 var = var_alloc(name); 6656212Saw148015 } 6666212Saw148015 6676212Saw148015 if (var == NULL) { 6686212Saw148015 filebench_log(LOG_ERROR, "Cannot assign variable %s", 6696212Saw148015 name); 6706212Saw148015 return (-1); 6716212Saw148015 } 6726212Saw148015 6736212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 6746212Saw148015 filebench_log(LOG_ERROR, 6756212Saw148015 "Cannot assign integer to random variable %s", name); 6766212Saw148015 return (-1); 6776212Saw148015 } 6786212Saw148015 6796212Saw148015 VAR_SET_INT(var, integer); 6805184Sek110237 6816286Saw148015 filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu", 6826286Saw148015 name, (u_longlong_t)integer); 6835184Sek110237 6845184Sek110237 return (0); 6855184Sek110237 } 6865184Sek110237 6875184Sek110237 /* 6886212Saw148015 * Find a variable, and set it to random type. 6896212Saw148015 * If it does not have a random extension, allocate one 6906212Saw148015 */ 6916212Saw148015 var_t * 6926212Saw148015 var_find_randvar(char *name) 6936212Saw148015 { 6946212Saw148015 var_t *newvar; 6956212Saw148015 6966212Saw148015 name += 1; 6976212Saw148015 6986212Saw148015 if ((newvar = var_find(name)) == NULL) { 6996212Saw148015 filebench_log(LOG_ERROR, 7006212Saw148015 "failed to locate random variable $%s\n", name); 7016212Saw148015 return (NULL); 7026212Saw148015 } 7036212Saw148015 7046212Saw148015 /* set randdist pointer unless it is already set */ 7056212Saw148015 if (((newvar->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) || 7066212Saw148015 !VAR_HAS_RANDDIST(newvar)) { 7076212Saw148015 filebench_log(LOG_ERROR, 7086212Saw148015 "Found variable $%s not random\n", name); 7096212Saw148015 return (NULL); 7106212Saw148015 } 7116212Saw148015 7126212Saw148015 return (newvar); 7136212Saw148015 } 7146212Saw148015 7156212Saw148015 /* 7166212Saw148015 * Allocate a variable, and set it to random type. Then 7176212Saw148015 * allocate a random extension. 7186212Saw148015 */ 7196212Saw148015 var_t * 7206212Saw148015 var_define_randvar(char *name) 7216212Saw148015 { 7226212Saw148015 var_t *newvar; 7236212Saw148015 randdist_t *rndp = NULL; 7246212Saw148015 7256212Saw148015 name += 1; 7266212Saw148015 7276212Saw148015 /* make sure variable doesn't already exist */ 7286212Saw148015 if (var_find(name) != NULL) { 7296212Saw148015 filebench_log(LOG_ERROR, 7306212Saw148015 "variable name already in use\n"); 7316212Saw148015 return (NULL); 7326212Saw148015 } 7336212Saw148015 7346212Saw148015 /* allocate a random variable */ 7356212Saw148015 if ((newvar = var_alloc_cmn(name, VAR_TYPE_RANDOM)) == NULL) { 7366212Saw148015 filebench_log(LOG_ERROR, 7376212Saw148015 "failed to alloc random variable\n"); 7386212Saw148015 return (NULL); 7396212Saw148015 } 7406212Saw148015 7416212Saw148015 /* set randdist pointer */ 7426212Saw148015 if ((rndp = randdist_alloc()) == NULL) { 7436212Saw148015 filebench_log(LOG_ERROR, 7446212Saw148015 "failed to alloc random distribution object\n"); 7456212Saw148015 return (NULL); 7466212Saw148015 } 7476212Saw148015 7486212Saw148015 rndp->rnd_var = newvar; 7496212Saw148015 VAR_SET_RAND(newvar, rndp); 7506212Saw148015 7516212Saw148015 return (newvar); 7526212Saw148015 } 7536212Saw148015 7546212Saw148015 /* 7556212Saw148015 * Searches for the named var, and if found returns an avd_t 7566212Saw148015 * pointing to the var's var_integer, var_string or var_double 7576212Saw148015 * as appropriate. If not found, attempts to allocate 7586212Saw148015 * a var named "name" and returns an avd_t to it with 7596212Saw148015 * no value set. If the var cannot be found or allocated, an 7605184Sek110237 * error is logged and the run is terminated. 7615184Sek110237 */ 7626212Saw148015 avd_t 7636212Saw148015 var_ref_attr(char *name) 7645184Sek110237 { 7655184Sek110237 var_t *var; 7665184Sek110237 7675184Sek110237 name += 1; 7685184Sek110237 7695184Sek110237 if ((var = var_find(name)) == NULL) 7705184Sek110237 var = var_find_dynamic(name); 7715184Sek110237 7725184Sek110237 if (var == NULL) 7735184Sek110237 var = var_alloc(name); 7745184Sek110237 7755184Sek110237 if (var == NULL) { 7765184Sek110237 filebench_log(LOG_ERROR, "Invalid variable $%s", 7775184Sek110237 name); 7785184Sek110237 filebench_shutdown(1); 7795184Sek110237 } 7805184Sek110237 7816212Saw148015 /* allocate pointer to var and return */ 7826212Saw148015 return (avd_alloc_var_ptr(var)); 7835184Sek110237 } 7845184Sek110237 7856212Saw148015 7865184Sek110237 /* 7876212Saw148015 * Searches for the named var, and if found copies the var_val.string, 7886212Saw148015 * if it exists, a decimal number string representation of 7896212Saw148015 * var_val.integer, the state of var_val.boolean, or the type of random 7906212Saw148015 * distribution employed, into a malloc'd bit of memory using fb_stralloc(). 7915184Sek110237 * Returns a pointer to the created string, or NULL on failure. 7925184Sek110237 */ 7935184Sek110237 char * 7945184Sek110237 var_to_string(char *name) 7955184Sek110237 { 7965184Sek110237 var_t *var; 7975184Sek110237 char tmp[128]; 7985184Sek110237 7995184Sek110237 name += 1; 8005184Sek110237 8015184Sek110237 if ((var = var_find(name)) == NULL) 8025184Sek110237 var = var_find_dynamic(name); 8035184Sek110237 8045184Sek110237 if (var == NULL) 8055184Sek110237 return (NULL); 8065184Sek110237 8076212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 8086212Saw148015 switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) { 8096212Saw148015 case RAND_TYPE_UNIFORM: 8106212Saw148015 return (fb_stralloc("uniform random var")); 8116212Saw148015 case RAND_TYPE_GAMMA: 8126212Saw148015 return (fb_stralloc("gamma random var")); 8136212Saw148015 case RAND_TYPE_TABLE: 8146212Saw148015 return (fb_stralloc("tabular random var")); 8156212Saw148015 default: 8166212Saw148015 return (fb_stralloc("unitialized random var")); 8176212Saw148015 } 8186212Saw148015 } 8195184Sek110237 8206212Saw148015 if (VAR_HAS_STRING(var) && var->var_val.string) 8216212Saw148015 return (fb_stralloc(var->var_val.string)); 8225184Sek110237 8236212Saw148015 if (VAR_HAS_BOOLEAN(var)) { 8246212Saw148015 if (var->var_val.boolean) 8256212Saw148015 return (fb_stralloc("true")); 8266212Saw148015 else 8276212Saw148015 return (fb_stralloc("false")); 8286212Saw148015 } 8296212Saw148015 8306212Saw148015 if (VAR_HAS_INTEGER(var)) { 8316286Saw148015 (void) snprintf(tmp, sizeof (tmp), "%llu", 8326286Saw148015 (u_longlong_t)var->var_val.integer); 8336212Saw148015 return (fb_stralloc(tmp)); 8346212Saw148015 } 8356212Saw148015 8366212Saw148015 return (fb_stralloc("No default")); 8375184Sek110237 } 8385184Sek110237 8395184Sek110237 /* 8405184Sek110237 * Searches for the named var, and if found returns the value, 8416212Saw148015 * of var_val.boolean. If the var is not found, or a boolean 8426212Saw148015 * value has not been set, logs an error and returns 0. 8435184Sek110237 */ 8446212Saw148015 boolean_t 8456212Saw148015 var_to_boolean(char *name) 8466212Saw148015 { 8476212Saw148015 var_t *var; 8486212Saw148015 8496212Saw148015 name += 1; 8506212Saw148015 8516212Saw148015 if ((var = var_find(name)) == NULL) 8526212Saw148015 var = var_find_dynamic(name); 8536212Saw148015 8546212Saw148015 if ((var != NULL) && VAR_HAS_BOOLEAN(var)) 8556212Saw148015 return (var->var_val.boolean); 8566212Saw148015 8576212Saw148015 filebench_log(LOG_ERROR, 8586212Saw148015 "Variable %s referenced before set", name); 8596212Saw148015 8606212Saw148015 return (0); 8616212Saw148015 } 8626212Saw148015 8636212Saw148015 /* 8646212Saw148015 * Searches for the named var, and if found returns the value, 8656212Saw148015 * of var_val.integer. If the var is not found, or the an 8666212Saw148015 * integer value has not been set, logs an error and returns 0. 8676212Saw148015 */ 8686212Saw148015 fbint_t 8695184Sek110237 var_to_integer(char *name) 8705184Sek110237 { 8715184Sek110237 var_t *var; 8725184Sek110237 8735184Sek110237 name += 1; 8745184Sek110237 8755184Sek110237 if ((var = var_find(name)) == NULL) 8765184Sek110237 var = var_find_dynamic(name); 8775184Sek110237 8786212Saw148015 if ((var != NULL) && VAR_HAS_INTEGER(var)) 8796212Saw148015 return (var->var_val.integer); 8805184Sek110237 8815184Sek110237 filebench_log(LOG_ERROR, 8825184Sek110237 "Variable %s referenced before set", name); 8835184Sek110237 8845184Sek110237 return (0); 8855184Sek110237 } 8865184Sek110237 8875184Sek110237 /* 8886212Saw148015 * Searches for the named random var, and if found, converts the 8896212Saw148015 * requested parameter into a string or a decimal number string 8906212Saw148015 * representation, into a malloc'd bit of memory using fb_stralloc(). 8916212Saw148015 * Returns a pointer to the created string, or calls var_to_string() 8926212Saw148015 * if a random variable isn't found. 8936212Saw148015 */ 8946212Saw148015 char * 8956212Saw148015 var_randvar_to_string(char *name, int param_name) 8966212Saw148015 { 8976212Saw148015 var_t *var; 8986212Saw148015 fbint_t value; 8996212Saw148015 9006212Saw148015 if ((var = var_find(name + 1)) == NULL) 9016212Saw148015 return (var_to_string(name)); 9026212Saw148015 9036212Saw148015 if (((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) || 9046212Saw148015 !VAR_HAS_RANDDIST(var)) 9056212Saw148015 return (var_to_string(name)); 9066212Saw148015 9076212Saw148015 switch (param_name) { 9086212Saw148015 case RAND_PARAM_TYPE: 9096212Saw148015 switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) { 9106212Saw148015 case RAND_TYPE_UNIFORM: 9116212Saw148015 return (fb_stralloc("uniform")); 9126212Saw148015 case RAND_TYPE_GAMMA: 9136212Saw148015 return (fb_stralloc("gamma")); 9146212Saw148015 case RAND_TYPE_TABLE: 9156212Saw148015 return (fb_stralloc("tabular")); 9166212Saw148015 default: 9176212Saw148015 return (fb_stralloc("uninitialized")); 9186212Saw148015 } 9196212Saw148015 9206212Saw148015 case RAND_PARAM_SRC: 9216212Saw148015 if (var->var_val.randptr->rnd_type & RAND_SRC_GENERATOR) 9226212Saw148015 return (fb_stralloc("rand48")); 9236212Saw148015 else 9246212Saw148015 return (fb_stralloc("urandom")); 9256212Saw148015 9266212Saw148015 case RAND_PARAM_SEED: 9276212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_seed); 9286212Saw148015 break; 9296212Saw148015 9306212Saw148015 case RAND_PARAM_MIN: 9316212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_min); 9326212Saw148015 break; 9336212Saw148015 9346212Saw148015 case RAND_PARAM_MEAN: 9356212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_mean); 9366212Saw148015 break; 9376212Saw148015 9386212Saw148015 case RAND_PARAM_GAMMA: 9396212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_gamma); 9406212Saw148015 break; 9416212Saw148015 9426212Saw148015 case RAND_PARAM_ROUND: 9436212Saw148015 value = avd_get_int(var->var_val.randptr->rnd_round); 9446212Saw148015 break; 9456212Saw148015 9466212Saw148015 default: 9476212Saw148015 return (NULL); 9486212Saw148015 9496212Saw148015 } 9506212Saw148015 9516212Saw148015 /* just an integer value if we got here */ 9526212Saw148015 { 9536212Saw148015 char tmp[128]; 9546212Saw148015 9556286Saw148015 (void) snprintf(tmp, sizeof (tmp), "%llu", 9566286Saw148015 (u_longlong_t)value); 9576212Saw148015 return (fb_stralloc(tmp)); 9586212Saw148015 } 9596212Saw148015 } 9606212Saw148015 9616212Saw148015 /* 9625184Sek110237 * Searches for the var named "name", and if not found 9635184Sek110237 * allocates it. The then extracts the var_string from 9645184Sek110237 * the var named "string" and copies it into the var_string 9655184Sek110237 * of the var "name", after first allocating a piece of 9665184Sek110237 * interprocess shared string memory. If the var "name" 9675184Sek110237 * cannot be found or allocated, or the var "string" cannot 9685184Sek110237 * be found, the routine returns -1, otherwise it returns 0. 9695184Sek110237 */ 9705184Sek110237 int 9716212Saw148015 var_assign_var(char *name, char *src_name) 9725184Sek110237 { 9736212Saw148015 var_t *dst_var, *src_var; 9745184Sek110237 9755184Sek110237 name += 1; 9766212Saw148015 src_name += 1; 9775184Sek110237 9786212Saw148015 if ((src_var = var_find(src_name)) == NULL) { 9796212Saw148015 filebench_log(LOG_ERROR, 9806212Saw148015 "Cannot find source variable %s", src_name); 9816212Saw148015 return (-1); 9826212Saw148015 } 9835184Sek110237 9846212Saw148015 if ((dst_var = var_find(name)) == NULL) 9856212Saw148015 dst_var = var_alloc(name); 9866212Saw148015 9876212Saw148015 if (dst_var == NULL) { 9885184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 9895184Sek110237 name); 9905184Sek110237 return (-1); 9915184Sek110237 } 9925184Sek110237 9936212Saw148015 if ((dst_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 9946212Saw148015 filebench_log(LOG_ERROR, 9956212Saw148015 "Cannot assign var to Random variable %s", name); 9965184Sek110237 return (-1); 9975184Sek110237 } 9986212Saw148015 9996212Saw148015 if (VAR_HAS_BOOLEAN(src_var)) { 10006212Saw148015 VAR_SET_BOOL(dst_var, src_var->var_val.boolean); 10016212Saw148015 filebench_log(LOG_VERBOSE, 10026212Saw148015 "Assign var %s=%d", name, src_var->var_val.boolean); 10036212Saw148015 } 10046212Saw148015 10056212Saw148015 if (VAR_HAS_INTEGER(src_var)) { 10066212Saw148015 VAR_SET_INT(dst_var, src_var->var_val.integer); 10076212Saw148015 filebench_log(LOG_VERBOSE, 10086286Saw148015 "Assign var %s=%llu", 10096286Saw148015 name, (u_longlong_t)src_var->var_val.integer); 10106212Saw148015 } 10116212Saw148015 10126212Saw148015 if (VAR_HAS_DOUBLE(src_var)) { 10136212Saw148015 VAR_SET_DBL(dst_var, src_var->var_val.dbl_flt); 10146212Saw148015 filebench_log(LOG_VERBOSE, 10156212Saw148015 "Assign var %s=%lf", name, src_var->var_val.dbl_flt); 10166212Saw148015 } 10176212Saw148015 10186212Saw148015 if (VAR_HAS_STRING(src_var)) { 10196212Saw148015 char *strptr; 10206212Saw148015 10216212Saw148015 if ((strptr = 10226212Saw148015 ipc_stralloc(src_var->var_val.string)) == NULL) { 10236212Saw148015 filebench_log(LOG_ERROR, 10246212Saw148015 "Cannot assign variable %s", 10256212Saw148015 name); 10266212Saw148015 return (-1); 10276212Saw148015 } 10286212Saw148015 VAR_SET_STR(dst_var, strptr); 10296212Saw148015 filebench_log(LOG_VERBOSE, 10306212Saw148015 "Assign var %s=%s", name, src_var->var_val.string); 10316212Saw148015 } 10325184Sek110237 return (0); 10335184Sek110237 } 10345184Sek110237 10355184Sek110237 /* 10365184Sek110237 * Like var_assign_integer, only this routine copies the 10375184Sek110237 * supplied "string" into the var named "name". If the var 10385184Sek110237 * named "name" cannot be found then it is first allocated 10395184Sek110237 * before the copy. Space for the string in the var comes 10405184Sek110237 * from interprocess shared memory. If the var "name" 10415184Sek110237 * cannot be found or allocated, or the memory for the 10425184Sek110237 * var_string copy of "string" cannot be allocated, the 10435184Sek110237 * routine returns -1, otherwise it returns 0. 10445184Sek110237 */ 10455184Sek110237 int 10465184Sek110237 var_assign_string(char *name, char *string) 10475184Sek110237 { 10485184Sek110237 var_t *var; 10496212Saw148015 char *strptr; 10505184Sek110237 10515184Sek110237 name += 1; 10525184Sek110237 10535184Sek110237 if ((var = var_find(name)) == NULL) 10545184Sek110237 var = var_alloc(name); 10555184Sek110237 10565184Sek110237 if (var == NULL) { 10575184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 10585184Sek110237 name); 10595184Sek110237 return (-1); 10605184Sek110237 } 10615184Sek110237 10626212Saw148015 if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) { 10636212Saw148015 filebench_log(LOG_ERROR, 10646212Saw148015 "Cannot assign string to random variable %s", name); 10656212Saw148015 return (-1); 10666212Saw148015 } 10676212Saw148015 10686212Saw148015 if ((strptr = ipc_stralloc(string)) == NULL) { 10695184Sek110237 filebench_log(LOG_ERROR, "Cannot assign variable %s", 10705184Sek110237 name); 10715184Sek110237 return (-1); 10725184Sek110237 } 10736212Saw148015 VAR_SET_STR(var, strptr); 10745184Sek110237 10756212Saw148015 filebench_log(LOG_DEBUG_SCRIPT, 10766212Saw148015 "Var assign string $%s=%s", name, string); 10775184Sek110237 10785184Sek110237 return (0); 10795184Sek110237 } 10805184Sek110237 10815184Sek110237 /* 10826212Saw148015 * Tests to see if the supplied variable name without the portion after 10836212Saw148015 * the last period is that of a random variable. If it is, it returns 10846212Saw148015 * the number of characters to backspace to skip the period and field 10856212Saw148015 * name. Otherwise it returns 0. 10865184Sek110237 */ 10876212Saw148015 int 10886212Saw148015 var_is_set4_randvar(char *name) 10895184Sek110237 { 10905184Sek110237 var_t *var; 10916212Saw148015 char varname[128]; 10926212Saw148015 int namelength; 10936212Saw148015 char *sp; 10945184Sek110237 10956212Saw148015 (void) strncpy(varname, name, 128); 10966212Saw148015 namelength = strlen(varname); 10976212Saw148015 sp = varname + namelength; 10985184Sek110237 10996212Saw148015 while (sp != varname) { 11006212Saw148015 int c = *sp; 11015184Sek110237 11026212Saw148015 *sp = 0; 11036212Saw148015 if (c == '.') 11046212Saw148015 break; 11056212Saw148015 11066212Saw148015 sp--; 11075184Sek110237 } 11085184Sek110237 11096212Saw148015 /* not a variable name + field? */ 11106212Saw148015 if (sp == varname) 11116212Saw148015 return (0); 11126212Saw148015 11136212Saw148015 /* first part not a variable name? */ 11146212Saw148015 if ((var = var_find(varname+1)) == NULL) 11156212Saw148015 return (0); 11166212Saw148015 11176212Saw148015 /* Make sure it is a random variable */ 11186212Saw148015 if ((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) 11196212Saw148015 return (0); 11206212Saw148015 11216212Saw148015 /* calculate offset from end of random variable name */ 11226212Saw148015 return (namelength - (sp - varname)); 11235184Sek110237 } 11245184Sek110237 11255184Sek110237 /* 11265184Sek110237 * Implements a simple path name like scheme for finding values 11275184Sek110237 * to place in certain specially named vars. The first part of 11285184Sek110237 * the name is interpreted as a category of either: stats, 11295184Sek110237 * eventgen, date, script, or host var. If a match is found, 11305184Sek110237 * the appropriate routine is called to fill in the requested 11315184Sek110237 * value in the provided var_t, and a pointer to the supplied 11325184Sek110237 * var_t is returned. If the requested value is not found, NULL 11335184Sek110237 * is returned. 11345184Sek110237 */ 11355184Sek110237 static var_t * 11365184Sek110237 var_find_internal(var_t *var) 11375184Sek110237 { 11385184Sek110237 char *n = fb_stralloc(var->var_name); 11395184Sek110237 char *name = n; 11405184Sek110237 var_t *rtn = NULL; 11415184Sek110237 11425184Sek110237 name++; 11435184Sek110237 if (name[strlen(name) - 1] != '}') 11445184Sek110237 return (NULL); 11455184Sek110237 name[strlen(name) - 1] = 0; 11465184Sek110237 11475184Sek110237 if (strncmp(name, STATS_VAR, strlen(STATS_VAR)) == 0) 11485184Sek110237 rtn = stats_findvar(var, name + strlen(STATS_VAR)); 11495184Sek110237 11505184Sek110237 if (strcmp(name, EVENTGEN_VAR) == 0) 11515184Sek110237 rtn = eventgen_ratevar(var); 11525184Sek110237 11535184Sek110237 if (strcmp(name, DATE_VAR) == 0) 11545184Sek110237 rtn = date_var(var); 11555184Sek110237 11565184Sek110237 if (strcmp(name, SCRIPT_VAR) == 0) 11575184Sek110237 rtn = script_var(var); 11585184Sek110237 11595184Sek110237 if (strcmp(name, HOST_VAR) == 0) 11605184Sek110237 rtn = host_var(var); 11615184Sek110237 11625184Sek110237 free(n); 11635184Sek110237 11645184Sek110237 return (rtn); 11655184Sek110237 } 11665184Sek110237 11675184Sek110237 /* 11685184Sek110237 * Calls the C library routine getenv() to obtain the value 11695184Sek110237 * for the environment variable specified by var->var_name. 11706212Saw148015 * If found, the value string is returned in var->var_val.string. 11715184Sek110237 * If the requested value is not found, NULL is returned. 11725184Sek110237 */ 11735184Sek110237 static var_t * 11745184Sek110237 var_find_environment(var_t *var) 11755184Sek110237 { 11765184Sek110237 char *n = fb_stralloc(var->var_name); 11775184Sek110237 char *name = n; 11786212Saw148015 char *strptr; 11795184Sek110237 11805184Sek110237 name++; 11816212Saw148015 if (name[strlen(name) - 1] != ')') { 11826212Saw148015 free(n); 11835184Sek110237 return (NULL); 11846212Saw148015 } 11855184Sek110237 name[strlen(name) - 1] = 0; 11865184Sek110237 11876212Saw148015 if ((strptr = getenv(name)) != NULL) { 11885184Sek110237 free(n); 11896212Saw148015 VAR_SET_STR(var, strptr); 11905184Sek110237 return (var); 11915184Sek110237 } else { 11925184Sek110237 free(n); 11935184Sek110237 return (NULL); 11945184Sek110237 } 11955184Sek110237 } 11965184Sek110237 11975184Sek110237 /* 11985184Sek110237 * Look up special variables. The "name" argument is used to find 11995184Sek110237 * the desired special var and fill it with an appropriate string 12005184Sek110237 * value. Looks for an already allocated var of the same name on 12015184Sek110237 * the var_dyn_list. If not found a new dynamic var is allocated. 12025184Sek110237 * if the name begins with '{', it is an internal variable, and 12035184Sek110237 * var_find_internal() is called. If the name begins with '(' it 12045184Sek110237 * is an environment varable, and var_find_environment() is 12055184Sek110237 * called. On success, a pointer to the var_t is returned, 12065184Sek110237 * otherwise, NULL is returned. 12075184Sek110237 */ 12085184Sek110237 static var_t * 12095184Sek110237 var_find_dynamic(char *name) 12105184Sek110237 { 12115184Sek110237 var_t *var = NULL; 1212*6391Saw148015 var_t *v = filebench_shm->shm_var_dyn_list; 12135184Sek110237 var_t *rtn; 12145184Sek110237 12155184Sek110237 /* 12165184Sek110237 * Lookup a reference to the var handle for this 12175184Sek110237 * special var 12185184Sek110237 */ 1219*6391Saw148015 for (v = filebench_shm->shm_var_dyn_list; v != NULL; v = v->var_next) { 12205184Sek110237 if (strcmp(v->var_name, name) == 0) { 12215184Sek110237 var = v; 12225184Sek110237 break; 12235184Sek110237 } 12245184Sek110237 } 12255184Sek110237 12265184Sek110237 if (var == NULL) 12275184Sek110237 var = var_alloc_dynamic(name); 12285184Sek110237 12295184Sek110237 /* Internal system control variable */ 12305184Sek110237 if (*name == '{') { 12315184Sek110237 rtn = var_find_internal(var); 12325184Sek110237 if (rtn == NULL) 12335184Sek110237 filebench_log(LOG_ERROR, 12345184Sek110237 "Cannot find internal variable %s", 12355184Sek110237 var->var_name); 12365184Sek110237 return (rtn); 12375184Sek110237 } 12385184Sek110237 12395184Sek110237 /* Lookup variable in environment */ 12405184Sek110237 if (*name == '(') { 12415184Sek110237 rtn = var_find_environment(var); 12425184Sek110237 if (rtn == NULL) 12435184Sek110237 filebench_log(LOG_ERROR, 12445184Sek110237 "Cannot find environment variable %s", 12455184Sek110237 var->var_name); 12465184Sek110237 return (rtn); 12475184Sek110237 } 12485184Sek110237 12495184Sek110237 return (NULL); 12505184Sek110237 } 1251