xref: /onnv-gate/usr/src/cmd/filebench/common/vars.c (revision 9801:4a9784073e11)
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 /*
22*9801SAndrew.W.Wilson@sun.com  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
235184Sek110237  * Use is subject to license terms.
246613Sek110237  *
256613Sek110237  * Portions Copyright 2008 Denis Cheng
265184Sek110237  */
275184Sek110237 
285184Sek110237 #include <stdlib.h>
295184Sek110237 #include <stdio.h>
305184Sek110237 #include <string.h>
315184Sek110237 #include <errno.h>
325184Sek110237 
336613Sek110237 #include "filebench.h"
345184Sek110237 #include "vars.h"
355184Sek110237 #include "misc.h"
365184Sek110237 #include "utils.h"
375184Sek110237 #include "stats.h"
385184Sek110237 #include "eventgen.h"
396212Saw148015 #include "fb_random.h"
405184Sek110237 
415184Sek110237 static var_t *var_find_dynamic(char *name);
42*9801SAndrew.W.Wilson@sun.com static boolean_t var_get_bool(var_t *var);
43*9801SAndrew.W.Wilson@sun.com static fbint_t var_get_int(var_t *var);
44*9801SAndrew.W.Wilson@sun.com static double var_get_dbl(var_t *var);
455184Sek110237 
465184Sek110237 /*
476212Saw148015  * The filebench variables system has attribute value descriptors (avd_t)
486212Saw148015  * where an avd contains a boolean, integer, double, string, random
496212Saw148015  * distribution object ptr, boolean ptr, integer ptr, double ptr,
506212Saw148015  * string ptr, or variable ptr. The system also has the variables
516212Saw148015  * themselves, (var_t), which are named, typed entities which can be
526212Saw148015  * allocated, selected and changed using the "set" command and used in
536212Saw148015  * attribute assignments. The variables contain either a boolean, an
546212Saw148015  * integer, a double, a string or pointer to an associated random
556212Saw148015  * distribution object. Both avd_t and var_t entities are allocated
565184Sek110237  * from interprocess shared memory space.
575184Sek110237  *
586212Saw148015  * The attribute descriptors implement delayed binding to variable values,
596212Saw148015  * which is necessary because the values of variables may be changed
606212Saw148015  * between the time the workload file is loaded and it is actually run,
616212Saw148015  * either by further "set" commands in the file or from the command line
626212Saw148015  * interface. For random variables, they actually point to the random
636212Saw148015  * distribution object, allowing FileBench to invoke the appropriate
646212Saw148015  * random distribution function on each access to the attribute. However,
656212Saw148015  * for static attributes, the value is just loaded in the descriptor
666212Saw148015  * directly, avoiding the need to allocate a variable to hold the static
676212Saw148015  * value.
686212Saw148015  *
695184Sek110237  * The routines in this module are used to allocate, locate, and
706212Saw148015  * manipulate the attribute descriptors, and vars. Routines are
716212Saw148015  * also included to convert between the component strings, doubles
726212Saw148015  * and integers of vars, and said components of avd_t.
735184Sek110237  */
745184Sek110237 
756550Saw148015 
765184Sek110237 /*
776212Saw148015  * returns a pointer to a string indicating the type of data contained
786212Saw148015  * in the supplied attribute variable descriptor.
795184Sek110237  */
806212Saw148015 static char *
avd_get_type_string(avd_t avd)816212Saw148015 avd_get_type_string(avd_t avd)
825184Sek110237 {
836212Saw148015 	switch (avd->avd_type) {
846212Saw148015 	case AVD_INVALID:
856212Saw148015 		return ("uninitialized");
866212Saw148015 
876212Saw148015 	case AVD_VAL_BOOL:
886212Saw148015 		return ("boolean value");
896212Saw148015 
906212Saw148015 	case AVD_VARVAL_BOOL:
916212Saw148015 		return ("points to boolean in var_t");
926212Saw148015 
936212Saw148015 	case AVD_VAL_INT:
946212Saw148015 		return ("integer value");
956212Saw148015 
966212Saw148015 	case AVD_VARVAL_INT:
976212Saw148015 		return ("points to integer in var_t");
986212Saw148015 
996212Saw148015 	case AVD_VAL_STR:
1006212Saw148015 		return ("string");
1016212Saw148015 
1026212Saw148015 	case AVD_VARVAL_STR:
1036212Saw148015 		return ("points to string in var_t");
1046212Saw148015 
1056212Saw148015 	case AVD_VAL_DBL:
1066212Saw148015 		return ("double float value");
1076212Saw148015 
1086212Saw148015 	case AVD_VARVAL_DBL:
1096212Saw148015 		return ("points to double float in var_t");
1106212Saw148015 
1116212Saw148015 	case AVD_IND_VAR:
1126212Saw148015 		return ("points to a var_t");
1136212Saw148015 
1146212Saw148015 	case AVD_IND_RANDVAR:
1156212Saw148015 		return ("points to var_t's random distribution object");
1166212Saw148015 
1176212Saw148015 	default:
1186212Saw148015 		return ("illegal avd type");
1196212Saw148015 	}
1206212Saw148015 }
1216212Saw148015 
1226212Saw148015 /*
1236212Saw148015  * returns a pointer to a string indicating the type of data contained
1246212Saw148015  * in the supplied variable.
1256212Saw148015  */
1266212Saw148015 static char *
var_get_type_string(var_t * ivp)1276212Saw148015 var_get_type_string(var_t *ivp)
1286212Saw148015 {
1296212Saw148015 	switch (ivp->var_type & VAR_TYPE_SET_MASK) {
1306212Saw148015 	case VAR_TYPE_BOOL_SET:
1316212Saw148015 		return ("boolean");
1326212Saw148015 
1336212Saw148015 	case VAR_TYPE_INT_SET:
1346212Saw148015 		return ("integer");
1356212Saw148015 
1366212Saw148015 	case VAR_TYPE_STR_SET:
1376212Saw148015 		return ("string");
1386212Saw148015 
1396212Saw148015 	case VAR_TYPE_DBL_SET:
1406212Saw148015 		return ("double float");
1416212Saw148015 
1426212Saw148015 	case VAR_TYPE_RAND_SET:
1436212Saw148015 		return ("random");
1446212Saw148015 
1456212Saw148015 	default:
1466212Saw148015 		return ("empty");
1476212Saw148015 	}
1486212Saw148015 }
1496212Saw148015 
1506212Saw148015 /*
1516212Saw148015  * Returns the fbint_t pointed to by the supplied avd_t "avd".
1526212Saw148015  */
1536212Saw148015 fbint_t
avd_get_int(avd_t avd)1546212Saw148015 avd_get_int(avd_t avd)
1556212Saw148015 {
1566212Saw148015 	randdist_t *rndp;
1576212Saw148015 
1586212Saw148015 	if (avd == NULL)
1595184Sek110237 		return (0);
1605184Sek110237 
1616212Saw148015 	switch (avd->avd_type) {
1626212Saw148015 	case AVD_VAL_INT:
1636212Saw148015 		return (avd->avd_val.intval);
1646212Saw148015 
1656212Saw148015 	case AVD_VARVAL_INT:
1666212Saw148015 		if (avd->avd_val.intptr)
1676212Saw148015 			return (*(avd->avd_val.intptr));
1686212Saw148015 		else
1696212Saw148015 			return (0);
1706212Saw148015 
1716212Saw148015 	case AVD_IND_VAR:
172*9801SAndrew.W.Wilson@sun.com 		return (var_get_int(avd->avd_val.varptr));
1736212Saw148015 
1746212Saw148015 	case AVD_IND_RANDVAR:
1756212Saw148015 		if ((rndp = avd->avd_val.randptr) == NULL)
1766212Saw148015 			return (0);
1776212Saw148015 		else
1786212Saw148015 			return ((fbint_t)rndp->rnd_get(rndp));
1796212Saw148015 
1806212Saw148015 	default:
1816212Saw148015 		filebench_log(LOG_ERROR,
1826212Saw148015 		    "Attempt to get integer from %s avd",
1836212Saw148015 		    avd_get_type_string(avd));
1846212Saw148015 		return (0);
1856212Saw148015 	}
1865184Sek110237 }
1875184Sek110237 
1885184Sek110237 /*
1896212Saw148015  * Returns the floating point value of a variable pointed to by the
1906212Saw148015  * supplied avd_t "avd". Intended to get the actual (double) value
1916212Saw148015  * supplied by the random variable.
1926212Saw148015  */
1936212Saw148015 double
avd_get_dbl(avd_t avd)1946212Saw148015 avd_get_dbl(avd_t avd)
1956212Saw148015 {
1966212Saw148015 	randdist_t *rndp;
1976212Saw148015 
1986212Saw148015 	if (avd == NULL)
1996212Saw148015 		return (0.0);
2006212Saw148015 
2016212Saw148015 	switch (avd->avd_type) {
2026212Saw148015 	case AVD_VAL_INT:
2036212Saw148015 		return ((double)avd->avd_val.intval);
2046212Saw148015 
2056212Saw148015 	case AVD_VAL_DBL:
2066212Saw148015 		return (avd->avd_val.dblval);
2076212Saw148015 
2086212Saw148015 	case AVD_VARVAL_INT:
2096212Saw148015 		if (avd->avd_val.intptr)
2106212Saw148015 			return ((double)(*(avd->avd_val.intptr)));
2116212Saw148015 		else
2126212Saw148015 			return (0.0);
2136212Saw148015 
2146212Saw148015 	case AVD_VARVAL_DBL:
2156212Saw148015 		if (avd->avd_val.dblptr)
2166212Saw148015 			return (*(avd->avd_val.dblptr));
2176212Saw148015 		else
2186212Saw148015 			return (0.0);
2196212Saw148015 
2206212Saw148015 	case AVD_IND_VAR:
221*9801SAndrew.W.Wilson@sun.com 		return (var_get_dbl(avd->avd_val.varptr));
2226212Saw148015 
2236212Saw148015 	case AVD_IND_RANDVAR:
2246212Saw148015 		if ((rndp = avd->avd_val.randptr) == NULL) {
2256212Saw148015 			return (0.0);
2266212Saw148015 		} else
2276212Saw148015 			return (rndp->rnd_get(rndp));
2286212Saw148015 
2296212Saw148015 	default:
2306212Saw148015 		filebench_log(LOG_ERROR,
2316212Saw148015 		    "Attempt to get floating point from %s avd",
2326212Saw148015 		    avd_get_type_string(avd));
2336212Saw148015 		return (0.0);
2346212Saw148015 	}
2356212Saw148015 }
2366212Saw148015 
2376212Saw148015 /*
2386212Saw148015  * Returns the boolean pointed to by the supplied avd_t "avd".
2395184Sek110237  */
2406212Saw148015 boolean_t
avd_get_bool(avd_t avd)2416212Saw148015 avd_get_bool(avd_t avd)
2425184Sek110237 {
2436212Saw148015 	if (avd == NULL)
2446212Saw148015 		return (0);
2456212Saw148015 
2466212Saw148015 	switch (avd->avd_type) {
2476212Saw148015 	case AVD_VAL_BOOL:
2486212Saw148015 		return (avd->avd_val.boolval);
2496212Saw148015 
2506212Saw148015 	case AVD_VARVAL_BOOL:
2516212Saw148015 		if (avd->avd_val.boolptr)
2526212Saw148015 			return (*(avd->avd_val.boolptr));
2536212Saw148015 		else
2546212Saw148015 			return (FALSE);
2556212Saw148015 
2566212Saw148015 	/* for backwards compatibility with old workloads */
2576212Saw148015 	case AVD_VAL_INT:
2586212Saw148015 		if (avd->avd_val.intval != 0)
2596212Saw148015 			return (TRUE);
2606212Saw148015 		else
2616212Saw148015 			return (FALSE);
2626212Saw148015 
2636212Saw148015 	case AVD_VARVAL_INT:
2646212Saw148015 		if (avd->avd_val.intptr)
2656212Saw148015 			if (*(avd->avd_val.intptr) != 0)
2666212Saw148015 				return (TRUE);
2676212Saw148015 
2686212Saw148015 		return (FALSE);
2696212Saw148015 
2706212Saw148015 	case AVD_IND_VAR:
271*9801SAndrew.W.Wilson@sun.com 		return (var_get_bool(avd->avd_val.varptr));
2726212Saw148015 
2736212Saw148015 	default:
2746212Saw148015 		filebench_log(LOG_ERROR,
2756212Saw148015 		    "Attempt to get boolean from %s avd",
2766212Saw148015 		    avd_get_type_string(avd));
2776212Saw148015 		return (FALSE);
2786212Saw148015 	}
2796212Saw148015 }
2806212Saw148015 
2816212Saw148015 /*
2826212Saw148015  * Returns the string pointed to by the supplied avd_t "avd".
2836212Saw148015  */
2846212Saw148015 char *
avd_get_str(avd_t avd)2856212Saw148015 avd_get_str(avd_t avd)
2866212Saw148015 {
2876212Saw148015 	var_t *ivp;
2886212Saw148015 
2896212Saw148015 	if (avd == NULL)
2906212Saw148015 		return (NULL);
2916212Saw148015 
2926212Saw148015 	switch (avd->avd_type) {
2936212Saw148015 	case AVD_VAL_STR:
2946212Saw148015 		return (avd->avd_val.strval);
2956212Saw148015 
2966212Saw148015 	case AVD_VARVAL_STR:
2976212Saw148015 		if (avd->avd_val.strptr)
2986212Saw148015 			return (*avd->avd_val.strptr);
2996212Saw148015 		else
3006212Saw148015 			return (NULL);
3016212Saw148015 
3026212Saw148015 	case AVD_IND_VAR:
3036212Saw148015 		ivp = avd->avd_val.varptr;
3046212Saw148015 
3056212Saw148015 		if (ivp && VAR_HAS_STRING(ivp))
3066212Saw148015 			return (ivp->var_val.string);
3076212Saw148015 
3086212Saw148015 		filebench_log(LOG_ERROR,
3096212Saw148015 		    "Attempt to get string from %s var $%s",
3106212Saw148015 		    var_get_type_string(ivp), ivp->var_name);
3116212Saw148015 		return (NULL);
3126212Saw148015 
3136212Saw148015 	default:
3146212Saw148015 		filebench_log(LOG_ERROR,
3156212Saw148015 		    "Attempt to get string from %s avd",
3166212Saw148015 		    avd_get_type_string(avd));
3175184Sek110237 		return (NULL);
3185184Sek110237 	}
3196212Saw148015 }
3205184Sek110237 
3216212Saw148015 /*
3226212Saw148015  * Allocates a avd_t from ipc memory space.
3236212Saw148015  * logs an error and returns NULL on failure.
3246212Saw148015  */
3256212Saw148015 static avd_t
avd_alloc_cmn(void)3266212Saw148015 avd_alloc_cmn(void)
3276212Saw148015 {
3286212Saw148015 	avd_t rtn;
3295184Sek110237 
3306212Saw148015 	if ((rtn = (avd_t)ipc_malloc(FILEBENCH_AVD)) == NULL)
3316212Saw148015 		filebench_log(LOG_ERROR, "Avd alloc failed");
3325184Sek110237 
3335184Sek110237 	return (rtn);
3345184Sek110237 }
3355184Sek110237 
3365184Sek110237 /*
3376212Saw148015  * pre-loads the allocated avd_t with the boolean_t "bool".
3386212Saw148015  * Returns the avd_t on success, NULL on failure.
3396212Saw148015  */
3406212Saw148015 avd_t
avd_bool_alloc(boolean_t bool)3416212Saw148015 avd_bool_alloc(boolean_t bool)
3426212Saw148015 {
3436212Saw148015 	avd_t avd;
3446212Saw148015 
3456212Saw148015 	if ((avd = avd_alloc_cmn()) == NULL)
3466212Saw148015 		return (NULL);
3476212Saw148015 
3486212Saw148015 	avd->avd_type = AVD_VAL_BOOL;
3496212Saw148015 	avd->avd_val.boolval = bool;
3506212Saw148015 
3516212Saw148015 	filebench_log(LOG_DEBUG_IMPL, "Alloc boolean %d", bool);
3526212Saw148015 
3536212Saw148015 	return (avd);
3546212Saw148015 }
3556212Saw148015 
3566212Saw148015 /*
3576212Saw148015  * pre-loads the allocated avd_t with the fbint_t "integer".
3586212Saw148015  * Returns the avd_t on success, NULL on failure.
3596212Saw148015  */
3606212Saw148015 avd_t
avd_int_alloc(fbint_t integer)3616212Saw148015 avd_int_alloc(fbint_t integer)
3626212Saw148015 {
3636212Saw148015 	avd_t avd;
3646212Saw148015 
3656212Saw148015 	if ((avd = avd_alloc_cmn()) == NULL)
3666212Saw148015 		return (NULL);
3676212Saw148015 
3686212Saw148015 	avd->avd_type = AVD_VAL_INT;
3696212Saw148015 	avd->avd_val.intval = integer;
3706212Saw148015 
3716286Saw148015 	filebench_log(LOG_DEBUG_IMPL, "Alloc integer %llu",
3726286Saw148015 	    (u_longlong_t)integer);
3736212Saw148015 
3746212Saw148015 	return (avd);
3756212Saw148015 }
3766212Saw148015 
3776212Saw148015 /*
3786212Saw148015  * Gets a avd_t and points it to the var that
3796212Saw148015  * it will eventually be filled from
3805184Sek110237  */
3816212Saw148015 static avd_t
avd_alloc_var_ptr(var_t * var)3826212Saw148015 avd_alloc_var_ptr(var_t *var)
3835184Sek110237 {
3846212Saw148015 	avd_t avd;
3856212Saw148015 
3866212Saw148015 	if (var == NULL)
3876212Saw148015 		return (NULL);
3886212Saw148015 
3896212Saw148015 	if ((avd = avd_alloc_cmn()) == NULL)
3906212Saw148015 		return (NULL);
3916212Saw148015 
3926212Saw148015 	switch (var->var_type & VAR_TYPE_SET_MASK) {
3936212Saw148015 	case VAR_TYPE_BOOL_SET:
3946212Saw148015 		avd->avd_type = AVD_VARVAL_BOOL;
3956212Saw148015 		avd->avd_val.boolptr = (&var->var_val.boolean);
3966212Saw148015 		break;
3976212Saw148015 
3986212Saw148015 	case VAR_TYPE_INT_SET:
3996212Saw148015 		avd->avd_type = AVD_VARVAL_INT;
4006212Saw148015 		avd->avd_val.intptr = (&var->var_val.integer);
4016212Saw148015 		break;
4026212Saw148015 
4036212Saw148015 	case VAR_TYPE_STR_SET:
4046212Saw148015 		avd->avd_type = AVD_VARVAL_STR;
4056212Saw148015 		avd->avd_val.strptr = &(var->var_val.string);
4066212Saw148015 		break;
4075184Sek110237 
4086212Saw148015 	case VAR_TYPE_DBL_SET:
4096212Saw148015 		avd->avd_type = AVD_VARVAL_DBL;
4106212Saw148015 		avd->avd_val.dblptr = &(var->var_val.dbl_flt);
4116212Saw148015 		break;
4126212Saw148015 
4136212Saw148015 	case VAR_TYPE_RAND_SET:
4146212Saw148015 		avd->avd_type = AVD_IND_RANDVAR;
4156212Saw148015 		avd->avd_val.randptr = var->var_val.randptr;
4166212Saw148015 		break;
4176212Saw148015 
4186550Saw148015 	case VAR_TYPE_INDVAR_SET:
4196550Saw148015 		avd->avd_type = AVD_IND_VAR;
420*9801SAndrew.W.Wilson@sun.com 		if ((var->var_type & VAR_INDVAR_MASK) == VAR_IND_ASSIGN)
421*9801SAndrew.W.Wilson@sun.com 			avd->avd_val.varptr = var->var_varptr1;
422*9801SAndrew.W.Wilson@sun.com 		else
423*9801SAndrew.W.Wilson@sun.com 			avd->avd_val.varptr = var;
424*9801SAndrew.W.Wilson@sun.com 
4256550Saw148015 		break;
4266550Saw148015 
4276212Saw148015 	default:
4286212Saw148015 		avd->avd_type = AVD_IND_VAR;
4296212Saw148015 		avd->avd_val.varptr = var;
4306212Saw148015 		break;
4316212Saw148015 	}
4326212Saw148015 	return (avd);
4336212Saw148015 }
4346212Saw148015 
4356212Saw148015 /*
4366212Saw148015  * Gets a avd_t, then allocates and initializes a piece of
4376212Saw148015  * shared string memory, putting the pointer to it into the just
4386212Saw148015  * allocated string pointer location. The routine returns a pointer
4396212Saw148015  * to the string pointer location or returns NULL on error.
4406212Saw148015  */
4416212Saw148015 avd_t
avd_str_alloc(char * string)4426212Saw148015 avd_str_alloc(char *string)
4436212Saw148015 {
4446212Saw148015 	avd_t avd;
4456212Saw148015 
4466212Saw148015 	if (string == NULL) {
4476212Saw148015 		filebench_log(LOG_ERROR, "No string supplied\n");
4485184Sek110237 		return (NULL);
4495184Sek110237 	}
4505184Sek110237 
4516212Saw148015 	if ((avd = avd_alloc_cmn()) == NULL)
4526212Saw148015 		return (NULL);
4536212Saw148015 
4546212Saw148015 	avd->avd_type = AVD_VAL_STR;
4556212Saw148015 	avd->avd_val.strval = ipc_stralloc(string);
4565184Sek110237 
4575184Sek110237 	filebench_log(LOG_DEBUG_IMPL,
4585184Sek110237 	    "Alloc string %s ptr %zx",
4596212Saw148015 	    string, avd);
4605184Sek110237 
4616212Saw148015 	return (avd);
4625184Sek110237 }
4635184Sek110237 
4645184Sek110237 /*
4655184Sek110237  * Allocates a var (var_t) from interprocess shared memory.
4665184Sek110237  * Places the allocated var on the end of the globally shared
4676550Saw148015  * shm_var_list. Finally, the routine allocates a string containing
4685184Sek110237  * a copy of the supplied "name" string. If any allocations
4695184Sek110237  * fails, returns NULL, otherwise it returns a pointer to the
4705184Sek110237  * newly allocated var.
4715184Sek110237  */
4725184Sek110237 static var_t *
var_alloc_cmn(char * name,int var_type)4736212Saw148015 var_alloc_cmn(char *name, int var_type)
4745184Sek110237 {
4756212Saw148015 	var_t **var_listp;
4765184Sek110237 	var_t *var = NULL;
4775184Sek110237 	var_t *prev = NULL;
4785184Sek110237 	var_t *newvar;
4795184Sek110237 
4805184Sek110237 	if ((newvar = (var_t *)ipc_malloc(FILEBENCH_VARIABLE)) == NULL) {
4815184Sek110237 		filebench_log(LOG_ERROR, "Out of memory for variables");
4825184Sek110237 		return (NULL);
4835184Sek110237 	}
4845184Sek110237 	(void) memset(newvar, 0, sizeof (newvar));
4856212Saw148015 	newvar->var_type = var_type;
4865184Sek110237 
4875184Sek110237 	if ((newvar->var_name = ipc_stralloc(name)) == NULL) {
4885184Sek110237 		filebench_log(LOG_ERROR, "Out of memory for variables");
4895184Sek110237 		return (NULL);
4905184Sek110237 	}
4915184Sek110237 
4926212Saw148015 	switch (var_type & VAR_TYPE_MASK) {
4936212Saw148015 	case VAR_TYPE_RANDOM:
4946212Saw148015 	case VAR_TYPE_GLOBAL:
4956391Saw148015 		var_listp = &filebench_shm->shm_var_list;
4966212Saw148015 		break;
4976212Saw148015 
4986212Saw148015 	case VAR_TYPE_DYNAMIC:
4996391Saw148015 		var_listp = &filebench_shm->shm_var_dyn_list;
5006212Saw148015 		break;
5016212Saw148015 
5026550Saw148015 	case VAR_TYPE_LOCAL:
5036550Saw148015 		/* place on head of shared local list */
5046550Saw148015 		newvar->var_next = filebench_shm->shm_var_loc_list;
5056550Saw148015 		filebench_shm->shm_var_loc_list = newvar;
5066550Saw148015 		return (newvar);
5076550Saw148015 
5086212Saw148015 	default:
5096391Saw148015 		var_listp = &filebench_shm->shm_var_list;
5106212Saw148015 		break;
5116212Saw148015 	}
5126212Saw148015 
5136212Saw148015 	/* add to the end of list */
5146212Saw148015 	for (var = *var_listp; var != NULL; var = var->var_next)
5156212Saw148015 		prev = var; /* Find end of list */
5166212Saw148015 	if (prev != NULL)
5176212Saw148015 		prev->var_next = newvar;
5186212Saw148015 	else
5196212Saw148015 		*var_listp = newvar;
5206212Saw148015 
5215184Sek110237 	return (newvar);
5225184Sek110237 }
5235184Sek110237 
5245184Sek110237 /*
5256550Saw148015  * Allocates a var (var_t) from interprocess shared memory after
5266550Saw148015  * first adjusting the name to elminate the leading $. Places the
5276550Saw148015  * allocated var temporarily on the end of the globally
5286550Saw148015  * shared var_loc_list. If the allocation fails, returns NULL,
5296550Saw148015  * otherwise it returns a pointer to the newly allocated var.
5306550Saw148015  */
5316550Saw148015 var_t *
var_lvar_alloc_local(char * name)5326550Saw148015 var_lvar_alloc_local(char *name)
5336550Saw148015 {
5346550Saw148015 	if (name[0] == '$')
5356550Saw148015 		name += 1;
5366550Saw148015 
5376550Saw148015 	return (var_alloc_cmn(name, VAR_TYPE_LOCAL));
5386550Saw148015 }
5396550Saw148015 
5406550Saw148015 /*
5416212Saw148015  * Allocates a var (var_t) from interprocess shared memory and
5426212Saw148015  * places the allocated var on the end of the globally shared
5436550Saw148015  * shm_var_list. If the allocation fails, returns NULL, otherwise
5446212Saw148015  * it returns a pointer to the newly allocated var.
5456212Saw148015  */
5466212Saw148015 static var_t *
var_alloc(char * name)5476212Saw148015 var_alloc(char *name)
5486212Saw148015 {
5496212Saw148015 	return (var_alloc_cmn(name, VAR_TYPE_GLOBAL));
5506212Saw148015 }
5516212Saw148015 
5526212Saw148015 /*
5535184Sek110237  * Allocates a var (var_t) from interprocess shared memory.
5545184Sek110237  * Places the allocated var on the end of the globally shared
5556550Saw148015  * shm_var_dyn_list. If the allocation fails, returns NULL, otherwise
5566212Saw148015  * it returns a pointer to the newly allocated var.
5575184Sek110237  */
5585184Sek110237 static var_t *
var_alloc_dynamic(char * name)5595184Sek110237 var_alloc_dynamic(char *name)
5605184Sek110237 {
5616212Saw148015 	return (var_alloc_cmn(name, VAR_TYPE_DYNAMIC));
5625184Sek110237 }
5635184Sek110237 
5645184Sek110237 /*
5656550Saw148015  * Searches for var_t with name "name" in the shm_var_loc_list,
5666550Saw148015  * then, if not found, in the global shm_var_list. If a matching
5676550Saw148015  * local or global var is found, returns a pointer to the var_t,
5686550Saw148015  * otherwise returns NULL.
5695184Sek110237  */
5705184Sek110237 static var_t *
var_find(char * name)5715184Sek110237 var_find(char *name)
5725184Sek110237 {
5735184Sek110237 	var_t *var;
5745184Sek110237 
5756550Saw148015 	for (var = filebench_shm->shm_var_loc_list; var != NULL;
5766550Saw148015 	    var = var->var_next) {
5776550Saw148015 		if (strcmp(var->var_name, name) == 0)
5786550Saw148015 			return (var);
5796550Saw148015 	}
5806550Saw148015 
5816391Saw148015 	for (var = filebench_shm->shm_var_list; var != NULL;
5826391Saw148015 	    var = var->var_next) {
5835184Sek110237 		if (strcmp(var->var_name, name) == 0)
5845184Sek110237 			return (var);
5855184Sek110237 	}
5865184Sek110237 
5875184Sek110237 	return (NULL);
5885184Sek110237 }
5895184Sek110237 
5905184Sek110237 /*
5916550Saw148015  * Searches for var_t with name "name" in the supplied shm_var_list.
5926550Saw148015  * If not found there, checks the global list. If still
5936550Saw148015  * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t.
5946550Saw148015  */
5956550Saw148015 static var_t *
var_find_list_only(char * name,var_t * var_list)5966550Saw148015 var_find_list_only(char *name, var_t *var_list)
5976550Saw148015 {
5986550Saw148015 	var_t *var;
5996550Saw148015 
6006550Saw148015 	for (var = var_list; var != NULL; var = var->var_next) {
6016550Saw148015 		if (strcmp(var->var_name, name) == 0)
6026550Saw148015 			return (var);
6036550Saw148015 	}
6046550Saw148015 
6056550Saw148015 	return (NULL);
6066550Saw148015 }
6076550Saw148015 
6086550Saw148015 /*
6096550Saw148015  * Searches for var_t with name "name" in the supplied shm_var_list.
6106550Saw148015  * If not found there, checks the global list. If still
6116550Saw148015  * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t.
6126550Saw148015  */
6136550Saw148015 static var_t *
var_find_list(char * name,var_t * var_list)6146550Saw148015 var_find_list(char *name, var_t *var_list)
6156550Saw148015 {
6166550Saw148015 	var_t *var;
6176550Saw148015 
6186550Saw148015 	if ((var = var_find_list_only(name, var_list)) != NULL)
6196550Saw148015 		return (var);
6206550Saw148015 	else
6216550Saw148015 		return (var_find(name));
6226550Saw148015 }
6236550Saw148015 
6246550Saw148015 /*
625*9801SAndrew.W.Wilson@sun.com  * Searches for the named var and returns it if found. If not
626*9801SAndrew.W.Wilson@sun.com  * found it allocates a new variable
627*9801SAndrew.W.Wilson@sun.com  */
628*9801SAndrew.W.Wilson@sun.com static var_t *
var_find_alloc(char * name)629*9801SAndrew.W.Wilson@sun.com var_find_alloc(char *name)
630*9801SAndrew.W.Wilson@sun.com {
631*9801SAndrew.W.Wilson@sun.com 	var_t *var;
632*9801SAndrew.W.Wilson@sun.com 
633*9801SAndrew.W.Wilson@sun.com 	if (name == NULL) {
634*9801SAndrew.W.Wilson@sun.com 		filebench_log(LOG_ERROR,
635*9801SAndrew.W.Wilson@sun.com 		    "var_find_alloc: Var name not supplied");
636*9801SAndrew.W.Wilson@sun.com 		return (NULL);
637*9801SAndrew.W.Wilson@sun.com 	}
638*9801SAndrew.W.Wilson@sun.com 
639*9801SAndrew.W.Wilson@sun.com 	name += 1;
640*9801SAndrew.W.Wilson@sun.com 
641*9801SAndrew.W.Wilson@sun.com 	if ((var = var_find(name)) == NULL) {
642*9801SAndrew.W.Wilson@sun.com 			var = var_alloc(name);
643*9801SAndrew.W.Wilson@sun.com 	}
644*9801SAndrew.W.Wilson@sun.com 	return (var);
645*9801SAndrew.W.Wilson@sun.com }
646*9801SAndrew.W.Wilson@sun.com 
647*9801SAndrew.W.Wilson@sun.com /*
6485184Sek110237  * Searches for the named var, and, if found, sets its
6496212Saw148015  * var_val.boolean's value to that of the supplied boolean.
6505184Sek110237  * If not found, the routine allocates a new var and sets
6516212Saw148015  * its var_val.boolean's value to that of the supplied
6526212Saw148015  * boolean. If the named var cannot be found or allocated
6536212Saw148015  * the routine returns -1, otherwise it returns 0.
6545184Sek110237  */
6555184Sek110237 int
var_assign_boolean(char * name,boolean_t bool)6566212Saw148015 var_assign_boolean(char *name, boolean_t bool)
6575184Sek110237 {
6585184Sek110237 	var_t *var;
6595184Sek110237 
660*9801SAndrew.W.Wilson@sun.com 	if ((var = var_find_alloc(name)) == NULL) {
6615184Sek110237 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
6625184Sek110237 		    name);
6635184Sek110237 		return (-1);
6645184Sek110237 	}
6655184Sek110237 
6666212Saw148015 	if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
6676212Saw148015 		filebench_log(LOG_ERROR,
6686212Saw148015 		    "Cannot assign integer to random variable %s", name);
6696212Saw148015 		return (-1);
6706212Saw148015 	}
6716212Saw148015 
6726212Saw148015 	VAR_SET_BOOL(var, bool);
6736212Saw148015 
6746212Saw148015 	filebench_log(LOG_DEBUG_SCRIPT, "Assign boolean %s=%d",
6756212Saw148015 	    name, bool);
6766212Saw148015 
6776212Saw148015 	return (0);
6786212Saw148015 }
6796212Saw148015 
6806212Saw148015 /*
6816212Saw148015  * Searches for the named var, and, if found, sets its
6826212Saw148015  * var_integer's value to that of the supplied integer.
6836212Saw148015  * If not found, the routine allocates a new var and sets
6846212Saw148015  * its var_integers's value to that of the supplied
6856212Saw148015  * integer. If the named var cannot be found or allocated
6866212Saw148015  * the routine returns -1, otherwise it returns 0.
6876212Saw148015  */
6886212Saw148015 int
var_assign_integer(char * name,fbint_t integer)6896212Saw148015 var_assign_integer(char *name, fbint_t integer)
6906212Saw148015 {
6916212Saw148015 	var_t *var;
6926212Saw148015 
693*9801SAndrew.W.Wilson@sun.com 	if ((var = var_find_alloc(name)) == NULL) {
6946212Saw148015 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
6956212Saw148015 		    name);
6966212Saw148015 		return (-1);
6976212Saw148015 	}
6986212Saw148015 
6996212Saw148015 	if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
7006212Saw148015 		filebench_log(LOG_ERROR,
7016212Saw148015 		    "Cannot assign integer to random variable %s", name);
7026212Saw148015 		return (-1);
7036212Saw148015 	}
7046212Saw148015 
7056212Saw148015 	VAR_SET_INT(var, integer);
7065184Sek110237 
7076286Saw148015 	filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu",
7086286Saw148015 	    name, (u_longlong_t)integer);
7095184Sek110237 
7105184Sek110237 	return (0);
7115184Sek110237 }
7125184Sek110237 
7135184Sek110237 /*
714*9801SAndrew.W.Wilson@sun.com  * Add, subtract, multiply or divide two integers based on optype
715*9801SAndrew.W.Wilson@sun.com  * passed from caller.
716*9801SAndrew.W.Wilson@sun.com  */
717*9801SAndrew.W.Wilson@sun.com static fbint_t
var_binary_integer_op(var_t * var)718*9801SAndrew.W.Wilson@sun.com var_binary_integer_op(var_t *var)
719*9801SAndrew.W.Wilson@sun.com {
720*9801SAndrew.W.Wilson@sun.com 	fbint_t result;
721*9801SAndrew.W.Wilson@sun.com 	fbint_t src1, src2;
722*9801SAndrew.W.Wilson@sun.com 
723*9801SAndrew.W.Wilson@sun.com 	if (var == NULL)
724*9801SAndrew.W.Wilson@sun.com 		return (0);
725*9801SAndrew.W.Wilson@sun.com 
726*9801SAndrew.W.Wilson@sun.com 	switch (var->var_type & VAR_INDBINOP_MASK) {
727*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_BINOP_INT:
728*9801SAndrew.W.Wilson@sun.com 		src2 = var->var_val.integer;
729*9801SAndrew.W.Wilson@sun.com 		break;
730*9801SAndrew.W.Wilson@sun.com 
731*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_BINOP_DBL:
732*9801SAndrew.W.Wilson@sun.com 		src2 = (fbint_t)var->var_val.dbl_flt;
733*9801SAndrew.W.Wilson@sun.com 		break;
734*9801SAndrew.W.Wilson@sun.com 
735*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_BINOP_VAR:
736*9801SAndrew.W.Wilson@sun.com 		if (var->var_val.varptr2 != NULL)
737*9801SAndrew.W.Wilson@sun.com 			src2 = var_get_int(var->var_val.varptr2);
738*9801SAndrew.W.Wilson@sun.com 		else
739*9801SAndrew.W.Wilson@sun.com 			src2 = 0;
740*9801SAndrew.W.Wilson@sun.com 		break;
741*9801SAndrew.W.Wilson@sun.com 	}
742*9801SAndrew.W.Wilson@sun.com 
743*9801SAndrew.W.Wilson@sun.com 	if (var->var_varptr1 != NULL)
744*9801SAndrew.W.Wilson@sun.com 		src1 = var_get_int(var->var_varptr1);
745*9801SAndrew.W.Wilson@sun.com 	else
746*9801SAndrew.W.Wilson@sun.com 		src1 = 0;
747*9801SAndrew.W.Wilson@sun.com 
748*9801SAndrew.W.Wilson@sun.com 	switch (var->var_type & VAR_INDVAR_MASK) {
749*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_SUM_VC:
750*9801SAndrew.W.Wilson@sun.com 		result = src1 + src2;
751*9801SAndrew.W.Wilson@sun.com 		break;
752*9801SAndrew.W.Wilson@sun.com 
753*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_DIF_VC:
754*9801SAndrew.W.Wilson@sun.com 		result = src1 - src2;
755*9801SAndrew.W.Wilson@sun.com 		break;
756*9801SAndrew.W.Wilson@sun.com 
757*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_C_DIF_VAR:
758*9801SAndrew.W.Wilson@sun.com 		result = src2 - src1;
759*9801SAndrew.W.Wilson@sun.com 		break;
760*9801SAndrew.W.Wilson@sun.com 
761*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_MUL_VC:
762*9801SAndrew.W.Wilson@sun.com 		result = src1 * src2;
763*9801SAndrew.W.Wilson@sun.com 		break;
764*9801SAndrew.W.Wilson@sun.com 
765*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_DIV_VC:
766*9801SAndrew.W.Wilson@sun.com 		result = src1 / src2;
767*9801SAndrew.W.Wilson@sun.com 		break;
768*9801SAndrew.W.Wilson@sun.com 
769*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_C_DIV_VAR:
770*9801SAndrew.W.Wilson@sun.com 		result = src2 / src1;
771*9801SAndrew.W.Wilson@sun.com 		break;
772*9801SAndrew.W.Wilson@sun.com 
773*9801SAndrew.W.Wilson@sun.com 	default:
774*9801SAndrew.W.Wilson@sun.com 		filebench_log(LOG_DEBUG_IMPL,
775*9801SAndrew.W.Wilson@sun.com 		    "var_binary_integer_op: Called with unknown IND_TYPE");
776*9801SAndrew.W.Wilson@sun.com 		result = 0;
777*9801SAndrew.W.Wilson@sun.com 		break;
778*9801SAndrew.W.Wilson@sun.com 	}
779*9801SAndrew.W.Wilson@sun.com 	return (result);
780*9801SAndrew.W.Wilson@sun.com }
781*9801SAndrew.W.Wilson@sun.com 
782*9801SAndrew.W.Wilson@sun.com /*
783*9801SAndrew.W.Wilson@sun.com  * Add, subtract, multiply or divide two double precision floating point
784*9801SAndrew.W.Wilson@sun.com  * numbers based on optype passed from caller.
785*9801SAndrew.W.Wilson@sun.com  */
786*9801SAndrew.W.Wilson@sun.com static double
var_binary_dbl_flt_op(var_t * var)787*9801SAndrew.W.Wilson@sun.com var_binary_dbl_flt_op(var_t *var)
788*9801SAndrew.W.Wilson@sun.com {
789*9801SAndrew.W.Wilson@sun.com 	double result;
790*9801SAndrew.W.Wilson@sun.com 	double src1, src2;
791*9801SAndrew.W.Wilson@sun.com 
792*9801SAndrew.W.Wilson@sun.com 	if (var == NULL)
793*9801SAndrew.W.Wilson@sun.com 		return (0.0);
794*9801SAndrew.W.Wilson@sun.com 
795*9801SAndrew.W.Wilson@sun.com 	switch (var->var_type & VAR_INDBINOP_MASK) {
796*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_BINOP_INT:
797*9801SAndrew.W.Wilson@sun.com 		src2 = (double)var->var_val.integer;
798*9801SAndrew.W.Wilson@sun.com 		break;
799*9801SAndrew.W.Wilson@sun.com 
800*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_BINOP_DBL:
801*9801SAndrew.W.Wilson@sun.com 		src2 = var->var_val.dbl_flt;
802*9801SAndrew.W.Wilson@sun.com 		break;
803*9801SAndrew.W.Wilson@sun.com 
804*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_BINOP_VAR:
805*9801SAndrew.W.Wilson@sun.com 		if (var->var_val.varptr2 != NULL)
806*9801SAndrew.W.Wilson@sun.com 			src2 = var_get_dbl(var->var_val.varptr2);
807*9801SAndrew.W.Wilson@sun.com 		else
808*9801SAndrew.W.Wilson@sun.com 			src2 = 0;
809*9801SAndrew.W.Wilson@sun.com 		break;
810*9801SAndrew.W.Wilson@sun.com 	}
811*9801SAndrew.W.Wilson@sun.com 
812*9801SAndrew.W.Wilson@sun.com 	if (var->var_varptr1 != NULL)
813*9801SAndrew.W.Wilson@sun.com 		src1 = var_get_dbl(var->var_varptr1);
814*9801SAndrew.W.Wilson@sun.com 	else
815*9801SAndrew.W.Wilson@sun.com 		src1 = 0;
816*9801SAndrew.W.Wilson@sun.com 
817*9801SAndrew.W.Wilson@sun.com 	switch (var->var_type & VAR_INDVAR_MASK) {
818*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_SUM_VC:
819*9801SAndrew.W.Wilson@sun.com 		result = src1 + src2;
820*9801SAndrew.W.Wilson@sun.com 		break;
821*9801SAndrew.W.Wilson@sun.com 
822*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_DIF_VC:
823*9801SAndrew.W.Wilson@sun.com 		result = src1 - src2;
824*9801SAndrew.W.Wilson@sun.com 		break;
825*9801SAndrew.W.Wilson@sun.com 
826*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_C_DIF_VAR:
827*9801SAndrew.W.Wilson@sun.com 		result = src2 - src1;
828*9801SAndrew.W.Wilson@sun.com 		break;
829*9801SAndrew.W.Wilson@sun.com 
830*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_MUL_VC:
831*9801SAndrew.W.Wilson@sun.com 		result = src1 * src2;
832*9801SAndrew.W.Wilson@sun.com 		break;
833*9801SAndrew.W.Wilson@sun.com 
834*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_C_DIV_VAR:
835*9801SAndrew.W.Wilson@sun.com 		result = src2 / src1;
836*9801SAndrew.W.Wilson@sun.com 		break;
837*9801SAndrew.W.Wilson@sun.com 
838*9801SAndrew.W.Wilson@sun.com 	case VAR_IND_VAR_DIV_VC:
839*9801SAndrew.W.Wilson@sun.com 		result = src1 / src2;
840*9801SAndrew.W.Wilson@sun.com 		break;
841*9801SAndrew.W.Wilson@sun.com 
842*9801SAndrew.W.Wilson@sun.com 	default:
843*9801SAndrew.W.Wilson@sun.com 		filebench_log(LOG_DEBUG_IMPL,
844*9801SAndrew.W.Wilson@sun.com 		    "var_binary_dbl_flt_op: Called with unknown IND_TYPE");
845*9801SAndrew.W.Wilson@sun.com 		result = 0;
846*9801SAndrew.W.Wilson@sun.com 		break;
847*9801SAndrew.W.Wilson@sun.com 	}
848*9801SAndrew.W.Wilson@sun.com 	return (result);
849*9801SAndrew.W.Wilson@sun.com }
850*9801SAndrew.W.Wilson@sun.com 
851*9801SAndrew.W.Wilson@sun.com /*
852*9801SAndrew.W.Wilson@sun.com  * Perform a binary operation on a variable and an integer
853*9801SAndrew.W.Wilson@sun.com  */
854*9801SAndrew.W.Wilson@sun.com int
var_assign_op_var_int(char * name,int optype,char * src1,fbint_t src2)855*9801SAndrew.W.Wilson@sun.com var_assign_op_var_int(char *name, int optype, char *src1, fbint_t src2)
856*9801SAndrew.W.Wilson@sun.com {
857*9801SAndrew.W.Wilson@sun.com 	var_t *var;
858*9801SAndrew.W.Wilson@sun.com 	var_t *var_src1;
859*9801SAndrew.W.Wilson@sun.com 
860*9801SAndrew.W.Wilson@sun.com 	if ((var_src1 = var_find(src1+1)) == NULL)
861*9801SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
862*9801SAndrew.W.Wilson@sun.com 
863*9801SAndrew.W.Wilson@sun.com 	if ((var = var_find_alloc(name)) == NULL)
864*9801SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
865*9801SAndrew.W.Wilson@sun.com 
866*9801SAndrew.W.Wilson@sun.com 	if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
867*9801SAndrew.W.Wilson@sun.com 		filebench_log(LOG_ERROR,
868*9801SAndrew.W.Wilson@sun.com 		    "Cannot assign integer to random variable %s", name);
869*9801SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
870*9801SAndrew.W.Wilson@sun.com 	}
871*9801SAndrew.W.Wilson@sun.com 
872*9801SAndrew.W.Wilson@sun.com 	VAR_SET_BINOP_INDVAR(var, var_src1, optype);
873*9801SAndrew.W.Wilson@sun.com 
874*9801SAndrew.W.Wilson@sun.com 	var->var_val.integer = src2;
875*9801SAndrew.W.Wilson@sun.com 
876*9801SAndrew.W.Wilson@sun.com 	return (FILEBENCH_OK);
877*9801SAndrew.W.Wilson@sun.com }
878*9801SAndrew.W.Wilson@sun.com 
879*9801SAndrew.W.Wilson@sun.com int
var_assign_op_var_var(char * name,int optype,char * src1,char * src2)880*9801SAndrew.W.Wilson@sun.com var_assign_op_var_var(char *name, int optype, char *src1, char *src2)
881*9801SAndrew.W.Wilson@sun.com {
882*9801SAndrew.W.Wilson@sun.com 	var_t *var;
883*9801SAndrew.W.Wilson@sun.com 	var_t *var_src1;
884*9801SAndrew.W.Wilson@sun.com 	var_t *var_src2;
885*9801SAndrew.W.Wilson@sun.com 
886*9801SAndrew.W.Wilson@sun.com 	if ((var_src1 = var_find(src1+1)) == NULL)
887*9801SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
888*9801SAndrew.W.Wilson@sun.com 
889*9801SAndrew.W.Wilson@sun.com 	if ((var_src2 = var_find(src2+1)) == NULL)
890*9801SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
891*9801SAndrew.W.Wilson@sun.com 
892*9801SAndrew.W.Wilson@sun.com 	if ((var = var_find_alloc(name)) == NULL)
893*9801SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
894*9801SAndrew.W.Wilson@sun.com 
895*9801SAndrew.W.Wilson@sun.com 	if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
896*9801SAndrew.W.Wilson@sun.com 		filebench_log(LOG_ERROR,
897*9801SAndrew.W.Wilson@sun.com 		    "Cannot assign integer to random variable %s", name);
898*9801SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
899*9801SAndrew.W.Wilson@sun.com 	}
900*9801SAndrew.W.Wilson@sun.com 
901*9801SAndrew.W.Wilson@sun.com 	VAR_SET_BINOP_INDVAR(var, var_src1, optype);
902*9801SAndrew.W.Wilson@sun.com 
903*9801SAndrew.W.Wilson@sun.com 	var->var_val.varptr2 = var_src2;
904*9801SAndrew.W.Wilson@sun.com 
905*9801SAndrew.W.Wilson@sun.com 	return (FILEBENCH_OK);
906*9801SAndrew.W.Wilson@sun.com }
907*9801SAndrew.W.Wilson@sun.com 
908*9801SAndrew.W.Wilson@sun.com /*
9096212Saw148015  * Find a variable, and set it to random type.
9106212Saw148015  * If it does not have a random extension, allocate one
9116212Saw148015  */
9126212Saw148015 var_t *
var_find_randvar(char * name)9136212Saw148015 var_find_randvar(char *name)
9146212Saw148015 {
9156212Saw148015 	var_t *newvar;
9166212Saw148015 
9176212Saw148015 	name += 1;
9186212Saw148015 
9196212Saw148015 	if ((newvar = var_find(name)) == NULL) {
9206212Saw148015 		filebench_log(LOG_ERROR,
9216212Saw148015 		    "failed to locate random variable $%s\n", name);
9226212Saw148015 		return (NULL);
9236212Saw148015 	}
9246212Saw148015 
9256212Saw148015 	/* set randdist pointer unless it is already set */
9266212Saw148015 	if (((newvar->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) ||
9276212Saw148015 	    !VAR_HAS_RANDDIST(newvar)) {
9286212Saw148015 		filebench_log(LOG_ERROR,
9296212Saw148015 		    "Found variable $%s not random\n", name);
9306212Saw148015 		return (NULL);
9316212Saw148015 	}
9326212Saw148015 
9336212Saw148015 	return (newvar);
9346212Saw148015 }
9356212Saw148015 
9366212Saw148015 /*
9376212Saw148015  * Allocate a variable, and set it to random type. Then
9386212Saw148015  * allocate a random extension.
9396212Saw148015  */
9406212Saw148015 var_t *
var_define_randvar(char * name)9416212Saw148015 var_define_randvar(char *name)
9426212Saw148015 {
9436212Saw148015 	var_t *newvar;
9446212Saw148015 	randdist_t *rndp = NULL;
9456212Saw148015 
9466212Saw148015 	name += 1;
9476212Saw148015 
9486212Saw148015 	/* make sure variable doesn't already exist */
9496212Saw148015 	if (var_find(name) != NULL) {
9506212Saw148015 		filebench_log(LOG_ERROR,
9516212Saw148015 		    "variable name already in use\n");
9526212Saw148015 		return (NULL);
9536212Saw148015 	}
9546212Saw148015 
9556212Saw148015 	/* allocate a random variable */
9566212Saw148015 	if ((newvar = var_alloc_cmn(name, VAR_TYPE_RANDOM)) == NULL) {
9576212Saw148015 		filebench_log(LOG_ERROR,
9586212Saw148015 		    "failed to alloc random variable\n");
9596212Saw148015 		return (NULL);
9606212Saw148015 	}
9616212Saw148015 
9626212Saw148015 	/* set randdist pointer */
9636212Saw148015 	if ((rndp = randdist_alloc()) == NULL) {
9646212Saw148015 		filebench_log(LOG_ERROR,
9656212Saw148015 		    "failed to alloc random distribution object\n");
9666212Saw148015 		return (NULL);
9676212Saw148015 	}
9686212Saw148015 
9696212Saw148015 	rndp->rnd_var = newvar;
9706212Saw148015 	VAR_SET_RAND(newvar, rndp);
9716212Saw148015 
9726212Saw148015 	return (newvar);
9736212Saw148015 }
9746212Saw148015 
9756212Saw148015 /*
9766212Saw148015  * Searches for the named var, and if found returns an avd_t
9776212Saw148015  * pointing to the var's var_integer, var_string or var_double
9786212Saw148015  * as appropriate. If not found, attempts to allocate
9796212Saw148015  * a var named "name" and returns an avd_t to it with
9806212Saw148015  * no value set. If the var cannot be found or allocated, an
9815184Sek110237  * error is logged and the run is terminated.
9825184Sek110237  */
9836212Saw148015 avd_t
var_ref_attr(char * name)9846212Saw148015 var_ref_attr(char *name)
9855184Sek110237 {
9865184Sek110237 	var_t *var;
9875184Sek110237 
9885184Sek110237 	name += 1;
9895184Sek110237 
9905184Sek110237 	if ((var = var_find(name)) == NULL)
9915184Sek110237 		var = var_find_dynamic(name);
9925184Sek110237 
9935184Sek110237 	if (var == NULL)
9945184Sek110237 		var = var_alloc(name);
9955184Sek110237 
9965184Sek110237 	if (var == NULL) {
9975184Sek110237 		filebench_log(LOG_ERROR, "Invalid variable $%s",
9985184Sek110237 		    name);
9995184Sek110237 		filebench_shutdown(1);
10005184Sek110237 	}
10015184Sek110237 
10026212Saw148015 	/* allocate pointer to var and return */
10036212Saw148015 	return (avd_alloc_var_ptr(var));
10045184Sek110237 }
10055184Sek110237 
10065184Sek110237 /*
1007*9801SAndrew.W.Wilson@sun.com  * Converts the contents of a var to a string
10085184Sek110237  */
1009*9801SAndrew.W.Wilson@sun.com static char *
var_get_string(var_t * var)1010*9801SAndrew.W.Wilson@sun.com var_get_string(var_t *var)
10115184Sek110237 {
10125184Sek110237 
10136212Saw148015 	if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
10146212Saw148015 		switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) {
10156212Saw148015 		case RAND_TYPE_UNIFORM:
10166212Saw148015 			return (fb_stralloc("uniform random var"));
10176212Saw148015 		case RAND_TYPE_GAMMA:
10186212Saw148015 			return (fb_stralloc("gamma random var"));
10196212Saw148015 		case RAND_TYPE_TABLE:
10206212Saw148015 			return (fb_stralloc("tabular random var"));
10216212Saw148015 		default:
10226212Saw148015 			return (fb_stralloc("unitialized random var"));
10236212Saw148015 		}
10246212Saw148015 	}
10255184Sek110237 
10266212Saw148015 	if (VAR_HAS_STRING(var) && var->var_val.string)
10276212Saw148015 		return (fb_stralloc(var->var_val.string));
10285184Sek110237 
10296212Saw148015 	if (VAR_HAS_BOOLEAN(var)) {
10306212Saw148015 		if (var->var_val.boolean)
10316212Saw148015 			return (fb_stralloc("true"));
10326212Saw148015 		else
10336212Saw148015 			return (fb_stralloc("false"));
10346212Saw148015 	}
10356212Saw148015 
10366212Saw148015 	if (VAR_HAS_INTEGER(var)) {
1037*9801SAndrew.W.Wilson@sun.com 		char tmp[128];
1038*9801SAndrew.W.Wilson@sun.com 
10396286Saw148015 		(void) snprintf(tmp, sizeof (tmp), "%llu",
10406286Saw148015 		    (u_longlong_t)var->var_val.integer);
10416212Saw148015 		return (fb_stralloc(tmp));
10426212Saw148015 	}
10436212Saw148015 
1044*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_INDVAR(var)) {
1045*9801SAndrew.W.Wilson@sun.com 		var_t *ivp;
1046*9801SAndrew.W.Wilson@sun.com 
1047*9801SAndrew.W.Wilson@sun.com 		if ((ivp = var->var_varptr1) != NULL) {
1048*9801SAndrew.W.Wilson@sun.com 			return (var_get_string(ivp));
1049*9801SAndrew.W.Wilson@sun.com 		}
1050*9801SAndrew.W.Wilson@sun.com 	}
1051*9801SAndrew.W.Wilson@sun.com 
1052*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_BINOP(var)) {
1053*9801SAndrew.W.Wilson@sun.com 		char tmp[128];
1054*9801SAndrew.W.Wilson@sun.com 
1055*9801SAndrew.W.Wilson@sun.com 		(void) snprintf(tmp, sizeof (tmp), "%llu",
1056*9801SAndrew.W.Wilson@sun.com 		    var_binary_integer_op(var));
1057*9801SAndrew.W.Wilson@sun.com 		return (fb_stralloc(tmp));
1058*9801SAndrew.W.Wilson@sun.com 	}
1059*9801SAndrew.W.Wilson@sun.com 
10606212Saw148015 	return (fb_stralloc("No default"));
10615184Sek110237 }
10625184Sek110237 
10635184Sek110237 /*
1064*9801SAndrew.W.Wilson@sun.com  * Searches for the named var, and if found copies the var_val.string,
1065*9801SAndrew.W.Wilson@sun.com  * if it exists, a decimal number string representation of
1066*9801SAndrew.W.Wilson@sun.com  * var_val.integer, the state of var_val.boolean, or the type of random
1067*9801SAndrew.W.Wilson@sun.com  * distribution employed, into a malloc'd bit of memory using fb_stralloc().
1068*9801SAndrew.W.Wilson@sun.com  * Returns a pointer to the created string, or NULL on failure.
1069*9801SAndrew.W.Wilson@sun.com  */
1070*9801SAndrew.W.Wilson@sun.com char *
var_to_string(char * name)1071*9801SAndrew.W.Wilson@sun.com var_to_string(char *name)
1072*9801SAndrew.W.Wilson@sun.com {
1073*9801SAndrew.W.Wilson@sun.com 	var_t *var;
1074*9801SAndrew.W.Wilson@sun.com 
1075*9801SAndrew.W.Wilson@sun.com 	name += 1;
1076*9801SAndrew.W.Wilson@sun.com 
1077*9801SAndrew.W.Wilson@sun.com 	if ((var = var_find(name)) == NULL)
1078*9801SAndrew.W.Wilson@sun.com 		var = var_find_dynamic(name);
1079*9801SAndrew.W.Wilson@sun.com 
1080*9801SAndrew.W.Wilson@sun.com 	if (var == NULL)
1081*9801SAndrew.W.Wilson@sun.com 		return (NULL);
1082*9801SAndrew.W.Wilson@sun.com 
1083*9801SAndrew.W.Wilson@sun.com 	return (var_get_string(var));
1084*9801SAndrew.W.Wilson@sun.com }
1085*9801SAndrew.W.Wilson@sun.com 
1086*9801SAndrew.W.Wilson@sun.com /*
1087*9801SAndrew.W.Wilson@sun.com  * Returns the boolean from the supplied var_t "var".
1088*9801SAndrew.W.Wilson@sun.com  */
1089*9801SAndrew.W.Wilson@sun.com static boolean_t
var_get_bool(var_t * var)1090*9801SAndrew.W.Wilson@sun.com var_get_bool(var_t *var)
1091*9801SAndrew.W.Wilson@sun.com {
1092*9801SAndrew.W.Wilson@sun.com 	if (var == NULL)
1093*9801SAndrew.W.Wilson@sun.com 		return (0);
1094*9801SAndrew.W.Wilson@sun.com 
1095*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_BOOLEAN(var))
1096*9801SAndrew.W.Wilson@sun.com 		return (var->var_val.boolean);
1097*9801SAndrew.W.Wilson@sun.com 
1098*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_INTEGER(var)) {
1099*9801SAndrew.W.Wilson@sun.com 		if (var->var_val.integer == 0)
1100*9801SAndrew.W.Wilson@sun.com 			return (FALSE);
1101*9801SAndrew.W.Wilson@sun.com 		else
1102*9801SAndrew.W.Wilson@sun.com 			return (TRUE);
1103*9801SAndrew.W.Wilson@sun.com 	}
1104*9801SAndrew.W.Wilson@sun.com 
1105*9801SAndrew.W.Wilson@sun.com 	filebench_log(LOG_ERROR,
1106*9801SAndrew.W.Wilson@sun.com 	    "Attempt to get boolean from %s var $%s",
1107*9801SAndrew.W.Wilson@sun.com 	    var_get_type_string(var), var->var_name);
1108*9801SAndrew.W.Wilson@sun.com 	return (FALSE);
1109*9801SAndrew.W.Wilson@sun.com }
1110*9801SAndrew.W.Wilson@sun.com 
1111*9801SAndrew.W.Wilson@sun.com /*
1112*9801SAndrew.W.Wilson@sun.com  * Returns the fbint_t from the supplied var_t "var".
1113*9801SAndrew.W.Wilson@sun.com  */
1114*9801SAndrew.W.Wilson@sun.com static fbint_t
var_get_int(var_t * var)1115*9801SAndrew.W.Wilson@sun.com var_get_int(var_t *var)
1116*9801SAndrew.W.Wilson@sun.com {
1117*9801SAndrew.W.Wilson@sun.com 	randdist_t *rndp;
1118*9801SAndrew.W.Wilson@sun.com 
1119*9801SAndrew.W.Wilson@sun.com 	if (var == NULL)
1120*9801SAndrew.W.Wilson@sun.com 		return (0);
1121*9801SAndrew.W.Wilson@sun.com 
1122*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_INTEGER(var))
1123*9801SAndrew.W.Wilson@sun.com 		return (var->var_val.integer);
1124*9801SAndrew.W.Wilson@sun.com 
1125*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_RANDDIST(var)) {
1126*9801SAndrew.W.Wilson@sun.com 		if ((rndp = var->var_val.randptr) != NULL)
1127*9801SAndrew.W.Wilson@sun.com 			return ((fbint_t)rndp->rnd_get(rndp));
1128*9801SAndrew.W.Wilson@sun.com 	}
1129*9801SAndrew.W.Wilson@sun.com 
1130*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_BINOP(var))
1131*9801SAndrew.W.Wilson@sun.com 		return (var_binary_integer_op(var));
1132*9801SAndrew.W.Wilson@sun.com 
1133*9801SAndrew.W.Wilson@sun.com 	filebench_log(LOG_ERROR,
1134*9801SAndrew.W.Wilson@sun.com 	    "Attempt to get integer from %s var $%s",
1135*9801SAndrew.W.Wilson@sun.com 	    var_get_type_string(var), var->var_name);
1136*9801SAndrew.W.Wilson@sun.com 	return (0);
1137*9801SAndrew.W.Wilson@sun.com }
1138*9801SAndrew.W.Wilson@sun.com 
1139*9801SAndrew.W.Wilson@sun.com /*
1140*9801SAndrew.W.Wilson@sun.com  * Returns the floating point value of a variable pointed to by the
1141*9801SAndrew.W.Wilson@sun.com  * supplied var_t "var". Intended to get the actual (double) value
1142*9801SAndrew.W.Wilson@sun.com  * supplied by the random variable.
1143*9801SAndrew.W.Wilson@sun.com  */
1144*9801SAndrew.W.Wilson@sun.com static double
var_get_dbl(var_t * var)1145*9801SAndrew.W.Wilson@sun.com var_get_dbl(var_t *var)
1146*9801SAndrew.W.Wilson@sun.com {
1147*9801SAndrew.W.Wilson@sun.com 	randdist_t *rndp;
1148*9801SAndrew.W.Wilson@sun.com 
1149*9801SAndrew.W.Wilson@sun.com 	if (var == NULL)
1150*9801SAndrew.W.Wilson@sun.com 		return (0.0);
1151*9801SAndrew.W.Wilson@sun.com 
1152*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_INTEGER(var))
1153*9801SAndrew.W.Wilson@sun.com 		return ((double)var->var_val.integer);
1154*9801SAndrew.W.Wilson@sun.com 
1155*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_DOUBLE(var))
1156*9801SAndrew.W.Wilson@sun.com 		return (var->var_val.dbl_flt);
1157*9801SAndrew.W.Wilson@sun.com 
1158*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_RANDDIST(var)) {
1159*9801SAndrew.W.Wilson@sun.com 		if ((rndp = var->var_val.randptr) != NULL)
1160*9801SAndrew.W.Wilson@sun.com 			return (rndp->rnd_get(rndp));
1161*9801SAndrew.W.Wilson@sun.com 	}
1162*9801SAndrew.W.Wilson@sun.com 
1163*9801SAndrew.W.Wilson@sun.com 	if (VAR_HAS_BINOP(var))
1164*9801SAndrew.W.Wilson@sun.com 		return (var_binary_dbl_flt_op(var));
1165*9801SAndrew.W.Wilson@sun.com 
1166*9801SAndrew.W.Wilson@sun.com 	filebench_log(LOG_ERROR,
1167*9801SAndrew.W.Wilson@sun.com 	    "Attempt to get double float from %s var $%s",
1168*9801SAndrew.W.Wilson@sun.com 	    var_get_type_string(var), var->var_name);
1169*9801SAndrew.W.Wilson@sun.com 	return (0.0);
1170*9801SAndrew.W.Wilson@sun.com }
1171*9801SAndrew.W.Wilson@sun.com 
1172*9801SAndrew.W.Wilson@sun.com /*
11735184Sek110237  * Searches for the named var, and if found returns the value,
11746212Saw148015  * of var_val.boolean. If the var is not found, or a boolean
11756212Saw148015  * value has not been set, logs an error and returns 0.
11765184Sek110237  */
11776212Saw148015 boolean_t
var_to_boolean(char * name)11786212Saw148015 var_to_boolean(char *name)
11796212Saw148015 {
11806212Saw148015 	var_t *var;
11816212Saw148015 
11826212Saw148015 	name += 1;
11836212Saw148015 
11846212Saw148015 	if ((var = var_find(name)) == NULL)
11856212Saw148015 		var = var_find_dynamic(name);
11866212Saw148015 
1187*9801SAndrew.W.Wilson@sun.com 	if (var != NULL)
1188*9801SAndrew.W.Wilson@sun.com 		return (var_get_bool(var));
11896212Saw148015 
11906212Saw148015 	filebench_log(LOG_ERROR,
11916212Saw148015 	    "Variable %s referenced before set", name);
11926212Saw148015 
1193*9801SAndrew.W.Wilson@sun.com 	return (FALSE);
11946212Saw148015 }
11956212Saw148015 
11966212Saw148015 /*
11976212Saw148015  * Searches for the named var, and if found returns the value,
11986212Saw148015  * of var_val.integer. If the var is not found, or the an
11996212Saw148015  * integer value has not been set, logs an error and returns 0.
12006212Saw148015  */
12016212Saw148015 fbint_t
var_to_integer(char * name)12025184Sek110237 var_to_integer(char *name)
12035184Sek110237 {
12045184Sek110237 	var_t *var;
12055184Sek110237 
12065184Sek110237 	name += 1;
12075184Sek110237 
12085184Sek110237 	if ((var = var_find(name)) == NULL)
12095184Sek110237 		var = var_find_dynamic(name);
12105184Sek110237 
1211*9801SAndrew.W.Wilson@sun.com 	if (var != NULL)
1212*9801SAndrew.W.Wilson@sun.com 		return (var_get_int(var));
12135184Sek110237 
12145184Sek110237 	filebench_log(LOG_ERROR,
12155184Sek110237 	    "Variable %s referenced before set", name);
12165184Sek110237 
12175184Sek110237 	return (0);
12185184Sek110237 }
12195184Sek110237 
12205184Sek110237 /*
1221*9801SAndrew.W.Wilson@sun.com  * Searches for the named var, and if found returns the value,
1222*9801SAndrew.W.Wilson@sun.com  * of var_val.dbl_flt. If the var is not found, or the
1223*9801SAndrew.W.Wilson@sun.com  * floating value has not been set, logs an error and returns 0.0.
1224*9801SAndrew.W.Wilson@sun.com  */
1225*9801SAndrew.W.Wilson@sun.com double
var_to_double(char * name)1226*9801SAndrew.W.Wilson@sun.com var_to_double(char *name)
1227*9801SAndrew.W.Wilson@sun.com {
1228*9801SAndrew.W.Wilson@sun.com 	var_t *var;
1229*9801SAndrew.W.Wilson@sun.com 
1230*9801SAndrew.W.Wilson@sun.com 	name += 1;
1231*9801SAndrew.W.Wilson@sun.com 
1232*9801SAndrew.W.Wilson@sun.com 	if ((var = var_find(name)) == NULL)
1233*9801SAndrew.W.Wilson@sun.com 		var = var_find_dynamic(name);
1234*9801SAndrew.W.Wilson@sun.com 
1235*9801SAndrew.W.Wilson@sun.com 	if (var != NULL)
1236*9801SAndrew.W.Wilson@sun.com 		return (var_get_dbl(var));
1237*9801SAndrew.W.Wilson@sun.com 
1238*9801SAndrew.W.Wilson@sun.com 	filebench_log(LOG_ERROR,
1239*9801SAndrew.W.Wilson@sun.com 	    "Variable %s referenced before set", name);
1240*9801SAndrew.W.Wilson@sun.com 
1241*9801SAndrew.W.Wilson@sun.com 	return (0.0);
1242*9801SAndrew.W.Wilson@sun.com }
1243*9801SAndrew.W.Wilson@sun.com 
1244*9801SAndrew.W.Wilson@sun.com /*
12456212Saw148015  * Searches for the named random var, and if found, converts the
12466212Saw148015  * requested parameter into a string or a decimal number string
12476212Saw148015  * representation, into a malloc'd bit of memory using fb_stralloc().
12486212Saw148015  * Returns a pointer to the created string, or calls var_to_string()
12496212Saw148015  * if a random variable isn't found.
12506212Saw148015  */
12516212Saw148015 char *
var_randvar_to_string(char * name,int param_name)12526212Saw148015 var_randvar_to_string(char *name, int param_name)
12536212Saw148015 {
12546212Saw148015 	var_t *var;
12556212Saw148015 	fbint_t value;
12566212Saw148015 
12576212Saw148015 	if ((var = var_find(name + 1)) == NULL)
12586212Saw148015 		return (var_to_string(name));
12596212Saw148015 
12606212Saw148015 	if (((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) ||
12616212Saw148015 	    !VAR_HAS_RANDDIST(var))
12626212Saw148015 		return (var_to_string(name));
12636212Saw148015 
12646212Saw148015 	switch (param_name) {
12656212Saw148015 	case RAND_PARAM_TYPE:
12666212Saw148015 		switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) {
12676212Saw148015 		case RAND_TYPE_UNIFORM:
12686212Saw148015 			return (fb_stralloc("uniform"));
12696212Saw148015 		case RAND_TYPE_GAMMA:
12706212Saw148015 			return (fb_stralloc("gamma"));
12716212Saw148015 		case RAND_TYPE_TABLE:
12726212Saw148015 			return (fb_stralloc("tabular"));
12736212Saw148015 		default:
12746212Saw148015 			return (fb_stralloc("uninitialized"));
12756212Saw148015 		}
12766212Saw148015 
12776212Saw148015 	case RAND_PARAM_SRC:
12786212Saw148015 		if (var->var_val.randptr->rnd_type & RAND_SRC_GENERATOR)
12796212Saw148015 			return (fb_stralloc("rand48"));
12806212Saw148015 		else
12816212Saw148015 			return (fb_stralloc("urandom"));
12826212Saw148015 
12836212Saw148015 	case RAND_PARAM_SEED:
12846212Saw148015 		value = avd_get_int(var->var_val.randptr->rnd_seed);
12856212Saw148015 		break;
12866212Saw148015 
12876212Saw148015 	case RAND_PARAM_MIN:
12886212Saw148015 		value = avd_get_int(var->var_val.randptr->rnd_min);
12896212Saw148015 		break;
12906212Saw148015 
12916212Saw148015 	case RAND_PARAM_MEAN:
12926212Saw148015 		value = avd_get_int(var->var_val.randptr->rnd_mean);
12936212Saw148015 		break;
12946212Saw148015 
12956212Saw148015 	case RAND_PARAM_GAMMA:
12966212Saw148015 		value = avd_get_int(var->var_val.randptr->rnd_gamma);
12976212Saw148015 		break;
12986212Saw148015 
12996212Saw148015 	case RAND_PARAM_ROUND:
13006212Saw148015 		value = avd_get_int(var->var_val.randptr->rnd_round);
13016212Saw148015 		break;
13026212Saw148015 
13036212Saw148015 	default:
13046212Saw148015 		return (NULL);
13056212Saw148015 
13066212Saw148015 	}
13076212Saw148015 
13086212Saw148015 	/* just an integer value if we got here */
13096212Saw148015 	{
13106212Saw148015 		char tmp[128];
13116212Saw148015 
13126286Saw148015 		(void) snprintf(tmp, sizeof (tmp), "%llu",
13136286Saw148015 		    (u_longlong_t)value);
13146212Saw148015 		return (fb_stralloc(tmp));
13156212Saw148015 	}
13166212Saw148015 }
13176212Saw148015 
13186212Saw148015 /*
13196550Saw148015  * Copies the value stored in the source string into the destination
13206550Saw148015  * string. Returns -1 if any problems encountered, 0 otherwise.
13216550Saw148015  */
13226550Saw148015 static int
var_copy(var_t * dst_var,var_t * src_var)13236550Saw148015 var_copy(var_t *dst_var, var_t *src_var) {
13246550Saw148015 
13256550Saw148015 	if (VAR_HAS_BOOLEAN(src_var)) {
13266550Saw148015 		VAR_SET_BOOL(dst_var, src_var->var_val.boolean);
13276550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
13286550Saw148015 		    "Assign var %s=%s", dst_var->var_name,
13296550Saw148015 		    dst_var->var_val.boolean?"true":"false");
13306550Saw148015 	}
13316550Saw148015 
13326550Saw148015 	if (VAR_HAS_INTEGER(src_var)) {
13336550Saw148015 		VAR_SET_INT(dst_var, src_var->var_val.integer);
13346550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
13356550Saw148015 		    "Assign var %s=%llu", dst_var->var_name,
13366550Saw148015 		    (u_longlong_t)dst_var->var_val.integer);
13376550Saw148015 	}
13386550Saw148015 
13396550Saw148015 	if (VAR_HAS_DOUBLE(src_var)) {
13406550Saw148015 		VAR_SET_DBL(dst_var, src_var->var_val.dbl_flt);
13416550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
13426550Saw148015 		    "Assign var %s=%lf", dst_var->var_name,
13436550Saw148015 		    dst_var->var_val.dbl_flt);
13446550Saw148015 	}
13456550Saw148015 
13466550Saw148015 	if (VAR_HAS_STRING(src_var)) {
13476550Saw148015 		char *strptr;
13486550Saw148015 
13496550Saw148015 		if ((strptr =
13506550Saw148015 		    ipc_stralloc(src_var->var_val.string)) == NULL) {
13516550Saw148015 			filebench_log(LOG_ERROR,
13526550Saw148015 			    "Cannot assign string for variable %s",
13536550Saw148015 			    dst_var->var_name);
13546550Saw148015 			return (-1);
13556550Saw148015 		}
13566550Saw148015 		VAR_SET_STR(dst_var, strptr);
13576550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
13586550Saw148015 		    "Assign var %s=%s", dst_var->var_name,
13596550Saw148015 		    dst_var->var_val.string);
13606550Saw148015 	}
13616550Saw148015 
13626550Saw148015 	if (VAR_HAS_INDVAR(src_var)) {
1363*9801SAndrew.W.Wilson@sun.com 		VAR_SET_INDVAR(dst_var, src_var->var_varptr1);
13646550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
13656550Saw148015 		    "Assign var %s to var %s", dst_var->var_name,
13666550Saw148015 		    src_var->var_name);
13676550Saw148015 	}
13686550Saw148015 	return (0);
13696550Saw148015 }
13706550Saw148015 
13716550Saw148015 /*
13725184Sek110237  * Searches for the var named "name", and if not found
13736550Saw148015  * allocates it. The then copies the value from
13746550Saw148015  * the src_var into the destination var "name"
13756550Saw148015  * If the var "name" cannot be found or allocated, or the var "src_name"
13766550Saw148015  * cannot be found, the routine returns -1, otherwise it returns 0.
13775184Sek110237  */
13785184Sek110237 int
var_assign_var(char * name,char * src_name)13796212Saw148015 var_assign_var(char *name, char *src_name)
13805184Sek110237 {
13816212Saw148015 	var_t *dst_var, *src_var;
13825184Sek110237 
13835184Sek110237 	name += 1;
13846212Saw148015 	src_name += 1;
13855184Sek110237 
13866212Saw148015 	if ((src_var = var_find(src_name)) == NULL) {
13876212Saw148015 		filebench_log(LOG_ERROR,
13886212Saw148015 		    "Cannot find source variable %s", src_name);
13896212Saw148015 		return (-1);
13906212Saw148015 	}
13915184Sek110237 
13926212Saw148015 	if ((dst_var = var_find(name)) == NULL)
13936212Saw148015 		dst_var = var_alloc(name);
13946212Saw148015 
13956212Saw148015 	if (dst_var == NULL) {
13965184Sek110237 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
13975184Sek110237 		    name);
13985184Sek110237 		return (-1);
13995184Sek110237 	}
14005184Sek110237 
14016212Saw148015 	if ((dst_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
14026212Saw148015 		filebench_log(LOG_ERROR,
14036212Saw148015 		    "Cannot assign var to Random variable %s", name);
14045184Sek110237 		return (-1);
14055184Sek110237 	}
14066212Saw148015 
14076550Saw148015 	return (var_copy(dst_var, src_var));
14085184Sek110237 }
14095184Sek110237 
14105184Sek110237 /*
14115184Sek110237  * Like var_assign_integer, only this routine copies the
14125184Sek110237  * supplied "string" into the var named "name". If the var
14135184Sek110237  * named "name" cannot be found then it is first allocated
14145184Sek110237  * before the copy. Space for the string in the var comes
14155184Sek110237  * from interprocess shared memory. If the var "name"
14165184Sek110237  * cannot be found or allocated, or the memory for the
14176550Saw148015  * var_val.string copy of "string" cannot be allocated, the
14185184Sek110237  * routine returns -1, otherwise it returns 0.
14195184Sek110237  */
14205184Sek110237 int
var_assign_string(char * name,char * string)14215184Sek110237 var_assign_string(char *name, char *string)
14225184Sek110237 {
14235184Sek110237 	var_t *var;
14246212Saw148015 	char *strptr;
14255184Sek110237 
14265184Sek110237 	name += 1;
14275184Sek110237 
14285184Sek110237 	if ((var = var_find(name)) == NULL)
14295184Sek110237 		var = var_alloc(name);
14305184Sek110237 
14315184Sek110237 	if (var == NULL) {
14325184Sek110237 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
14335184Sek110237 		    name);
14345184Sek110237 		return (-1);
14355184Sek110237 	}
14365184Sek110237 
14376212Saw148015 	if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
14386212Saw148015 		filebench_log(LOG_ERROR,
14396212Saw148015 		    "Cannot assign string to random variable %s", name);
14406212Saw148015 		return (-1);
14416212Saw148015 	}
14426212Saw148015 
14436212Saw148015 	if ((strptr = ipc_stralloc(string)) == NULL) {
14445184Sek110237 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
14455184Sek110237 		    name);
14465184Sek110237 		return (-1);
14475184Sek110237 	}
14486212Saw148015 	VAR_SET_STR(var, strptr);
14495184Sek110237 
14506212Saw148015 	filebench_log(LOG_DEBUG_SCRIPT,
14516212Saw148015 	    "Var assign string $%s=%s", name, string);
14525184Sek110237 
14535184Sek110237 	return (0);
14545184Sek110237 }
14555184Sek110237 
14565184Sek110237 /*
14576550Saw148015  * Allocates a local var. The then extracts the var_string from
14586550Saw148015  * the var named "string" and copies it into the var_string
14596550Saw148015  * of the var "name", after first allocating a piece of
14606550Saw148015  * interprocess shared string memory. Returns a pointer to the
14616550Saw148015  * newly allocated local var or NULL on error.
14626550Saw148015  */
14636550Saw148015 var_t *
var_lvar_assign_var(char * name,char * src_name)14646550Saw148015 var_lvar_assign_var(char *name, char *src_name)
14656550Saw148015 {
14666550Saw148015 	var_t *dst_var, *src_var;
14676550Saw148015 
14686550Saw148015 	src_name += 1;
14696550Saw148015 
14706550Saw148015 	if ((src_var = var_find(src_name)) == NULL) {
14716550Saw148015 		filebench_log(LOG_ERROR,
14726550Saw148015 		    "Cannot find source variable %s", src_name);
14736550Saw148015 		return (NULL);
14746550Saw148015 	}
14756550Saw148015 
14766550Saw148015 	dst_var = var_lvar_alloc_local(name);
14776550Saw148015 
14786550Saw148015 	if (dst_var == NULL) {
14796550Saw148015 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
14806550Saw148015 		    name);
14816550Saw148015 		return (NULL);
14826550Saw148015 	}
14836550Saw148015 
14846550Saw148015 	/*
14856550Saw148015 	 * if referencing another local var which is currently
14866550Saw148015 	 * empty, indirect to it
14876550Saw148015 	 */
14886550Saw148015 	if ((src_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_LOCAL) {
14896550Saw148015 		VAR_SET_INDVAR(dst_var, src_var);
14906550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
14916550Saw148015 		    "Assign local var %s to %s", name, src_name);
14926550Saw148015 		return (dst_var);
14936550Saw148015 	}
14946550Saw148015 
14956550Saw148015 	if (VAR_HAS_BOOLEAN(src_var)) {
14966550Saw148015 		VAR_SET_BOOL(dst_var, src_var->var_val.boolean);
14976550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
14986550Saw148015 		    "Assign var (%s, %p)=%s", name,
14996550Saw148015 		    dst_var, src_var->var_val.boolean?"true":"false");
15006550Saw148015 	} else if (VAR_HAS_INTEGER(src_var)) {
15016550Saw148015 		VAR_SET_INT(dst_var, src_var->var_val.integer);
15026550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
15036550Saw148015 		    "Assign var (%s, %p)=%llu", name,
15046550Saw148015 		    dst_var, (u_longlong_t)src_var->var_val.integer);
15056550Saw148015 	} else if (VAR_HAS_STRING(src_var)) {
15066550Saw148015 		char *strptr;
15076550Saw148015 
15086550Saw148015 		if ((strptr = ipc_stralloc(src_var->var_val.string)) == NULL) {
15096550Saw148015 			filebench_log(LOG_ERROR,
15106550Saw148015 			    "Cannot assign variable %s",
15116550Saw148015 			    name);
15126550Saw148015 			return (NULL);
15136550Saw148015 		}
15146550Saw148015 		VAR_SET_STR(dst_var, strptr);
15156550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
15166550Saw148015 		    "Assign var (%s, %p)=%s", name,
15176550Saw148015 		    dst_var, src_var->var_val.string);
15186550Saw148015 	} else if (VAR_HAS_DOUBLE(src_var)) {
15196550Saw148015 		/* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
15206550Saw148015 		VAR_SET_INT(dst_var, src_var->var_val.dbl_flt);
15216550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
15226550Saw148015 		    "Assign var (%s, %p)=%8.2f", name,
15236550Saw148015 		    dst_var, src_var->var_val.dbl_flt);
15246550Saw148015 	} else if (VAR_HAS_RANDDIST(src_var)) {
15256550Saw148015 		VAR_SET_RAND(dst_var, src_var->var_val.randptr);
15266550Saw148015 		filebench_log(LOG_DEBUG_SCRIPT,
15276550Saw148015 		    "Assign var (%s, %p)=%llu", name,
15286550Saw148015 		    dst_var, (u_longlong_t)src_var->var_val.integer);
15296550Saw148015 	}
15306550Saw148015 
15316550Saw148015 	return (dst_var);
15326550Saw148015 }
15336550Saw148015 
15346550Saw148015 /*
15356550Saw148015  * the routine allocates a new local var and sets
15366550Saw148015  * its var_boolean's value to that of the supplied
15376550Saw148015  * boolean. It returns a pointer to the new local var
15386550Saw148015  */
15396550Saw148015 var_t *
var_lvar_assign_boolean(char * name,boolean_t bool)15406550Saw148015 var_lvar_assign_boolean(char *name, boolean_t bool)
15416550Saw148015 {
15426550Saw148015 	var_t *var;
15436550Saw148015 
15446550Saw148015 	var = var_lvar_alloc_local(name);
15456550Saw148015 
15466550Saw148015 	if (var == NULL) {
15476550Saw148015 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
15486550Saw148015 		    name);
15496550Saw148015 		return (NULL);
15506550Saw148015 	}
15516550Saw148015 
15526550Saw148015 	VAR_SET_BOOL(var, bool);
15536550Saw148015 
15546550Saw148015 	filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%s",
15556550Saw148015 	    name, bool ? "true" : "false");
15566550Saw148015 
15576550Saw148015 	return (var);
15586550Saw148015 }
15596550Saw148015 
15606550Saw148015 /*
15616550Saw148015  * the routine allocates a new local var and sets
15626550Saw148015  * its var_integers's value to that of the supplied
15636550Saw148015  * integer. It returns a pointer to the new local var
15646550Saw148015  */
15656550Saw148015 var_t *
var_lvar_assign_integer(char * name,fbint_t integer)15666550Saw148015 var_lvar_assign_integer(char *name, fbint_t integer)
15676550Saw148015 {
15686550Saw148015 	var_t *var;
15696550Saw148015 
15706550Saw148015 	var = var_lvar_alloc_local(name);
15716550Saw148015 
15726550Saw148015 	if (var == NULL) {
15736550Saw148015 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
15746550Saw148015 		    name);
15756550Saw148015 		return (NULL);
15766550Saw148015 	}
15776550Saw148015 
15786550Saw148015 	VAR_SET_INT(var, integer);
15796550Saw148015 
15806550Saw148015 	filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu",
15816550Saw148015 	    name, (u_longlong_t)integer);
15826550Saw148015 
15836550Saw148015 	return (var);
15846550Saw148015 }
15856550Saw148015 
15866550Saw148015 /*
15876550Saw148015  * the routine allocates a new local var and sets
15886550Saw148015  * its var_dbl_flt value to that of the supplied
15896550Saw148015  * double precission floating point number. It returns
15906550Saw148015  * a pointer to the new local var
15916550Saw148015  */
15926550Saw148015 var_t *
var_lvar_assign_double(char * name,double dbl)15936550Saw148015 var_lvar_assign_double(char *name, double dbl)
15946550Saw148015 {
15956550Saw148015 	var_t *var;
15966550Saw148015 
15976550Saw148015 	var = var_lvar_alloc_local(name);
15986550Saw148015 
15996550Saw148015 	if (var == NULL) {
16006550Saw148015 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
16016550Saw148015 		    name);
16026550Saw148015 		return (NULL);
16036550Saw148015 	}
16046550Saw148015 
16056550Saw148015 	VAR_SET_DBL(var, dbl);
16066550Saw148015 
16076550Saw148015 	filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%8.2f", name, dbl);
16086550Saw148015 
16096550Saw148015 	return (var);
16106550Saw148015 }
16116550Saw148015 
16126550Saw148015 /*
16136550Saw148015  * Like var_lvar_assign_integer, only this routine copies the
16146550Saw148015  * supplied "string" into the var named "name". If the var
16156550Saw148015  * named "name" cannot be found then it is first allocated
16166550Saw148015  * before the copy. Space for the string in the var comes
16176550Saw148015  * from interprocess shared memory. The allocated local var
16186550Saw148015  * is returned at as a char *, or NULL on error.
16196550Saw148015  */
16206550Saw148015 var_t *
var_lvar_assign_string(char * name,char * string)16216550Saw148015 var_lvar_assign_string(char *name, char *string)
16226550Saw148015 {
16236550Saw148015 	var_t *var;
16246550Saw148015 	char *strptr;
16256550Saw148015 
16266550Saw148015 	var = var_lvar_alloc_local(name);
16276550Saw148015 
16286550Saw148015 	if (var == NULL) {
16296550Saw148015 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
16306550Saw148015 		    name);
16316550Saw148015 		return (NULL);
16326550Saw148015 	}
16336550Saw148015 
16346550Saw148015 	if ((strptr = ipc_stralloc(string)) == NULL) {
16356550Saw148015 		filebench_log(LOG_ERROR, "Cannot assign variable %s",
16366550Saw148015 		    name);
16376550Saw148015 		return (NULL);
16386550Saw148015 	}
16396550Saw148015 	VAR_SET_STR(var, strptr);
16406550Saw148015 
16416550Saw148015 	filebench_log(LOG_DEBUG_SCRIPT,
16426550Saw148015 	    "Lvar_assign_string (%s, %p)=%s", name, var, string);
16436550Saw148015 
16446550Saw148015 	return (var);
16456550Saw148015 }
16466550Saw148015 
16476550Saw148015 /*
16486212Saw148015  * Tests to see if the supplied variable name without the portion after
16496212Saw148015  * the last period is that of a random variable. If it is, it returns
16506212Saw148015  * the number of characters to backspace to skip the period and field
16516212Saw148015  * name. Otherwise it returns 0.
16525184Sek110237  */
16536212Saw148015 int
var_is_set4_randvar(char * name)16546212Saw148015 var_is_set4_randvar(char *name)
16555184Sek110237 {
16565184Sek110237 	var_t *var;
16576212Saw148015 	char varname[128];
16586212Saw148015 	int namelength;
16596212Saw148015 	char *sp;
16605184Sek110237 
16616212Saw148015 	(void) strncpy(varname, name, 128);
16626212Saw148015 	namelength = strlen(varname);
16636212Saw148015 	sp = varname + namelength;
16645184Sek110237 
16656212Saw148015 	while (sp != varname) {
16666212Saw148015 		int c = *sp;
16675184Sek110237 
16686212Saw148015 		*sp = 0;
16696212Saw148015 		if (c == '.')
16706212Saw148015 			break;
16716212Saw148015 
16726212Saw148015 		sp--;
16735184Sek110237 	}
16745184Sek110237 
16756212Saw148015 	/* not a variable name + field? */
16766212Saw148015 	if (sp == varname)
16776212Saw148015 		return (0);
16786212Saw148015 
16796212Saw148015 	/* first part not a variable name? */
16806212Saw148015 	if ((var = var_find(varname+1)) == NULL)
16816212Saw148015 		return (0);
16826212Saw148015 
16836212Saw148015 	/* Make sure it is a random variable */
16846212Saw148015 	if ((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM)
16856212Saw148015 		return (0);
16866212Saw148015 
16876212Saw148015 	/* calculate offset from end of random variable name */
16886212Saw148015 	return (namelength - (sp - varname));
16895184Sek110237 }
16905184Sek110237 
16915184Sek110237 /*
16925184Sek110237  * Implements a simple path name like scheme for finding values
16935184Sek110237  * to place in certain specially named vars. The first part of
16945184Sek110237  * the name is interpreted as a category of either: stats,
16955184Sek110237  * eventgen, date, script, or host var. If a match is found,
16965184Sek110237  * the appropriate routine is called to fill in the requested
16975184Sek110237  * value in the provided var_t, and a pointer to the supplied
16985184Sek110237  * var_t is returned. If the requested value is not found, NULL
16995184Sek110237  * is returned.
17005184Sek110237  */
17015184Sek110237 static var_t *
var_find_internal(var_t * var)17025184Sek110237 var_find_internal(var_t *var)
17035184Sek110237 {
17045184Sek110237 	char *n = fb_stralloc(var->var_name);
17055184Sek110237 	char *name = n;
17065184Sek110237 	var_t *rtn = NULL;
17075184Sek110237 
17085184Sek110237 	name++;
17095184Sek110237 	if (name[strlen(name) - 1] != '}')
17105184Sek110237 		return (NULL);
17115184Sek110237 	name[strlen(name) - 1] = 0;
17125184Sek110237 
17135184Sek110237 	if (strncmp(name, STATS_VAR, strlen(STATS_VAR)) == 0)
17145184Sek110237 		rtn = stats_findvar(var, name + strlen(STATS_VAR));
17155184Sek110237 
17165184Sek110237 	if (strcmp(name, EVENTGEN_VAR) == 0)
17175184Sek110237 		rtn = eventgen_ratevar(var);
17185184Sek110237 
17195184Sek110237 	if (strcmp(name, DATE_VAR) == 0)
17205184Sek110237 		rtn = date_var(var);
17215184Sek110237 
17225184Sek110237 	if (strcmp(name, SCRIPT_VAR) == 0)
17235184Sek110237 		rtn = script_var(var);
17245184Sek110237 
17255184Sek110237 	if (strcmp(name, HOST_VAR) == 0)
17265184Sek110237 		rtn = host_var(var);
17275184Sek110237 
17285184Sek110237 	free(n);
17295184Sek110237 
17305184Sek110237 	return (rtn);
17315184Sek110237 }
17325184Sek110237 
17335184Sek110237 /*
17345184Sek110237  * Calls the C library routine getenv() to obtain the value
17355184Sek110237  * for the environment variable specified by var->var_name.
17366212Saw148015  * If found, the value string is returned in var->var_val.string.
17375184Sek110237  * If the requested value is not found, NULL is returned.
17385184Sek110237  */
17395184Sek110237 static var_t *
var_find_environment(var_t * var)17405184Sek110237 var_find_environment(var_t *var)
17415184Sek110237 {
17425184Sek110237 	char *n = fb_stralloc(var->var_name);
17435184Sek110237 	char *name = n;
17446212Saw148015 	char *strptr;
17455184Sek110237 
17465184Sek110237 	name++;
17476212Saw148015 	if (name[strlen(name) - 1] != ')') {
17486212Saw148015 		free(n);
17495184Sek110237 		return (NULL);
17506212Saw148015 	}
17515184Sek110237 	name[strlen(name) - 1] = 0;
17525184Sek110237 
17536212Saw148015 	if ((strptr = getenv(name)) != NULL) {
17545184Sek110237 		free(n);
17556212Saw148015 		VAR_SET_STR(var, strptr);
17565184Sek110237 		return (var);
17575184Sek110237 	} else {
17585184Sek110237 		free(n);
17595184Sek110237 		return (NULL);
17605184Sek110237 	}
17615184Sek110237 }
17625184Sek110237 
17635184Sek110237 /*
17645184Sek110237  * Look up special variables. The "name" argument is used to find
17655184Sek110237  * the desired special var and fill it with an appropriate string
17665184Sek110237  * value. Looks for an already allocated var of the same name on
17676550Saw148015  * the shm_var_dyn_list. If not found a new dynamic var is allocated.
17685184Sek110237  * if the name begins with '{', it is an internal variable, and
17695184Sek110237  * var_find_internal() is called. If the name begins with '(' it
17705184Sek110237  * is an environment varable, and var_find_environment() is
17715184Sek110237  * called. On success, a pointer to the var_t is returned,
17725184Sek110237  * otherwise, NULL is returned.
17735184Sek110237  */
17745184Sek110237 static var_t *
var_find_dynamic(char * name)17755184Sek110237 var_find_dynamic(char *name)
17765184Sek110237 {
17775184Sek110237 	var_t *var = NULL;
17786391Saw148015 	var_t *v = filebench_shm->shm_var_dyn_list;
17795184Sek110237 	var_t *rtn;
17805184Sek110237 
17815184Sek110237 	/*
17825184Sek110237 	 * Lookup a reference to the var handle for this
17835184Sek110237 	 * special var
17845184Sek110237 	 */
17856391Saw148015 	for (v = filebench_shm->shm_var_dyn_list; v != NULL; v = v->var_next) {
17865184Sek110237 		if (strcmp(v->var_name, name) == 0) {
17875184Sek110237 			var = v;
17885184Sek110237 			break;
17895184Sek110237 		}
17905184Sek110237 	}
17915184Sek110237 
17925184Sek110237 	if (var == NULL)
17935184Sek110237 		var = var_alloc_dynamic(name);
17945184Sek110237 
17955184Sek110237 	/* Internal system control variable */
17965184Sek110237 	if (*name == '{') {
17975184Sek110237 		rtn = var_find_internal(var);
17985184Sek110237 		if (rtn == NULL)
17995184Sek110237 			filebench_log(LOG_ERROR,
18005184Sek110237 			    "Cannot find internal variable %s",
18015184Sek110237 			    var->var_name);
18025184Sek110237 		return (rtn);
18035184Sek110237 	}
18045184Sek110237 
18055184Sek110237 	/* Lookup variable in environment */
18065184Sek110237 	if (*name == '(') {
18075184Sek110237 		rtn = var_find_environment(var);
18085184Sek110237 		if (rtn == NULL)
18095184Sek110237 			filebench_log(LOG_ERROR,
18105184Sek110237 			    "Cannot find environment variable %s",
18115184Sek110237 			    var->var_name);
18125184Sek110237 		return (rtn);
18135184Sek110237 	}
18145184Sek110237 
18155184Sek110237 	return (NULL);
18165184Sek110237 }
18176550Saw148015 
18186550Saw148015 /*
18196550Saw148015  * replace the avd_t attribute value descriptor in the new FLOW_MASTER flowop
18206550Saw148015  * that points to a local variable with a new avd_t containing
18216550Saw148015  * the actual value from the local variable.
18226550Saw148015  */
18236550Saw148015 void
avd_update(avd_t * avdp,var_t * lvar_list)18246550Saw148015 avd_update(avd_t *avdp, var_t *lvar_list)
18256550Saw148015 {
18266550Saw148015 	var_t *old_lvar, *new_lvar;
18276550Saw148015 
18286550Saw148015 	if ((*avdp)->avd_type == AVD_IND_VAR) {
18296550Saw148015 
18306550Saw148015 		/* Make sure there is a local var */
18316550Saw148015 		if ((old_lvar = (*avdp)->avd_val.varptr) == NULL) {
18326550Saw148015 			filebench_log(LOG_ERROR,
18336550Saw148015 			    "avd_update: local var not found");
18346550Saw148015 			return;
18356550Saw148015 		}
18366550Saw148015 	} else {
18376550Saw148015 		/* Empty or not indirect, so no update needed */
18386550Saw148015 		return;
18396550Saw148015 	}
18406550Saw148015 
18416550Saw148015 	/*  allocate a new avd using the new or old lvar contents */
18426550Saw148015 	if ((new_lvar =
18436550Saw148015 	    var_find_list(old_lvar->var_name, lvar_list)) != NULL)
18446550Saw148015 		(*avdp) = avd_alloc_var_ptr(new_lvar);
18456550Saw148015 	else
18466550Saw148015 		(*avdp) = avd_alloc_var_ptr(old_lvar);
18476550Saw148015 }
18486550Saw148015 
18496550Saw148015 void
var_update_comp_lvars(var_t * newlvar,var_t * proto_comp_vars,var_t * mstr_lvars)18506550Saw148015 var_update_comp_lvars(var_t *newlvar, var_t *proto_comp_vars,
18516550Saw148015     var_t *mstr_lvars)
18526550Saw148015 {
18536550Saw148015 	var_t *proto_lvar;
18546550Saw148015 
18556550Saw148015 	/* find the prototype lvar from the inherited list */
18566550Saw148015 	proto_lvar = var_find_list_only(newlvar->var_name, proto_comp_vars);
18576550Saw148015 
18586550Saw148015 	if (proto_lvar == NULL)
18596550Saw148015 		return;
18606550Saw148015 
18616550Saw148015 	/*
18626550Saw148015 	 * if the new local variable has not already been assigned
18636550Saw148015 	 * a value, try to copy a value from the prototype local variable
18646550Saw148015 	 */
18656550Saw148015 	if ((newlvar->var_type & VAR_TYPE_SET_MASK) == 0) {
18666550Saw148015 
18676550Saw148015 		/* copy value from prototype lvar to new lvar */
18686550Saw148015 		(void) var_copy(newlvar, proto_lvar);
18696550Saw148015 	}
18706550Saw148015 
18716550Saw148015 	/* If proto lvar is indirect, see if we can colapse indirection */
18726550Saw148015 	if (VAR_HAS_INDVAR(proto_lvar)) {
18736550Saw148015 		var_t *uplvp;
18746550Saw148015 
1875*9801SAndrew.W.Wilson@sun.com 		uplvp = (var_t *)proto_lvar->var_varptr1;
18766550Saw148015 
18776550Saw148015 		/* search for more current uplvar on comp master list */
18786550Saw148015 		if (mstr_lvars) {
18796550Saw148015 			uplvp = var_find_list_only(
18806550Saw148015 			    uplvp->var_name, mstr_lvars);
18816550Saw148015 			VAR_SET_INDVAR(newlvar, uplvp);
18826550Saw148015 		}
18836550Saw148015 
18846550Saw148015 		if (VAR_HAS_INDVAR(uplvp))
1885*9801SAndrew.W.Wilson@sun.com 			VAR_SET_INDVAR(newlvar, uplvp->var_varptr1);
18866550Saw148015 	}
18876550Saw148015 }
1888