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 /* 226084Saw148015 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235184Sek110237 * Use is subject to license terms. 246613Sek110237 * 256613Sek110237 * Portions Copyright 2008 Denis Cheng 265184Sek110237 */ 275184Sek110237 285184Sek110237 %{ 295184Sek110237 #pragma ident "%Z%%M% %I% %E% SMI" 305184Sek110237 %} 315184Sek110237 325184Sek110237 %{ 335184Sek110237 345184Sek110237 #include <stdlib.h> 355184Sek110237 #include <stdio.h> 365184Sek110237 #include <string.h> 375184Sek110237 #include <signal.h> 385184Sek110237 #include <errno.h> 395184Sek110237 #include <sys/types.h> 405184Sek110237 #include <locale.h> 415184Sek110237 #include <sys/utsname.h> 425184Sek110237 #ifdef HAVE_STDINT_H 435184Sek110237 #include <stdint.h> 445184Sek110237 #endif 455184Sek110237 #include <fcntl.h> 465184Sek110237 #include <sys/mman.h> 475184Sek110237 #include <sys/wait.h> 485184Sek110237 #ifdef HAVE_LIBTECLA 495184Sek110237 #include <libtecla.h> 505184Sek110237 #endif 515184Sek110237 #include "parsertypes.h" 525184Sek110237 #include "filebench.h" 535184Sek110237 #include "utils.h" 545184Sek110237 #include "stats.h" 555184Sek110237 #include "vars.h" 565184Sek110237 #include "eventgen.h" 575184Sek110237 #ifdef HAVE_LIBTECLA 585184Sek110237 #include "auto_comp.h" 595184Sek110237 #endif 605184Sek110237 615184Sek110237 int dofile = FS_FALSE; 625184Sek110237 static const char cmdname[] = "filebench"; 635184Sek110237 static const char cmd_options[] = "pa:f:hi:s:m:"; 645184Sek110237 static void usage(int); 655184Sek110237 665184Sek110237 static cmd_t *cmd = NULL; /* Command being processed */ 675184Sek110237 #ifdef HAVE_LIBTECLA 685184Sek110237 static GetLine *gl; /* GetLine resource object */ 695184Sek110237 #endif 705184Sek110237 715184Sek110237 char *execname; 725184Sek110237 char *fscriptname; 735184Sek110237 int noproc = 0; 745184Sek110237 var_t *var_list = NULL; 755184Sek110237 pidlist_t *pidlist = NULL; 765184Sek110237 char *cwd = NULL; 775184Sek110237 FILE *parentscript = NULL; 785673Saw148015 795673Saw148015 static int filecreate_done = 0; 805673Saw148015 815184Sek110237 /* yacc externals */ 825184Sek110237 extern FILE *yyin; 835184Sek110237 extern int yydebug; 845184Sek110237 extern void yyerror(char *s); 855184Sek110237 865184Sek110237 /* utilities */ 875184Sek110237 static void terminate(void); 885184Sek110237 static cmd_t *alloc_cmd(void); 895184Sek110237 static attr_t *alloc_attr(void); 906550Saw148015 static attr_t *alloc_lvar_attr(var_t *var); 915184Sek110237 static attr_t *get_attr(cmd_t *cmd, int64_t name); 925184Sek110237 static attr_t *get_attr_integer(cmd_t *cmd, int64_t name); 935184Sek110237 static attr_t *get_attr_bool(cmd_t *cmd, int64_t name); 946550Saw148015 static void get_attr_lvars(cmd_t *cmd, flowop_t *flowop); 955184Sek110237 static var_t *alloc_var(void); 965184Sek110237 static var_t *get_var(cmd_t *cmd, int64_t name); 975184Sek110237 static list_t *alloc_list(); 986212Saw148015 static probtabent_t *alloc_probtabent(void); 996550Saw148015 static void add_lvar_to_list(var_t *newlvar, var_t **lvar_list); 1005184Sek110237 1015184Sek110237 /* Info Commands */ 1025184Sek110237 static void parser_list(cmd_t *); 1036212Saw148015 static void parser_flowop_list(cmd_t *); 1045184Sek110237 1055184Sek110237 /* Define Commands */ 1065184Sek110237 static void parser_proc_define(cmd_t *); 1075184Sek110237 static void parser_thread_define(cmd_t *, procflow_t *, int instances); 1086212Saw148015 static void parser_flowop_define(cmd_t *, threadflow_t *, flowop_t **, int); 1095184Sek110237 static void parser_file_define(cmd_t *); 1105184Sek110237 static void parser_fileset_define(cmd_t *); 1116212Saw148015 static void parser_randvar_define(cmd_t *); 1126212Saw148015 static void parser_randvar_set(cmd_t *); 1136550Saw148015 static void parser_composite_flowop_define(cmd_t *); 1145184Sek110237 1155184Sek110237 /* Create Commands */ 1165184Sek110237 static void parser_proc_create(cmd_t *); 1175184Sek110237 static void parser_thread_create(cmd_t *); 1185184Sek110237 static void parser_flowop_create(cmd_t *); 1195184Sek110237 static void parser_fileset_create(cmd_t *); 1205184Sek110237 1216212Saw148015 /* set commands */ 1226212Saw148015 static void parser_set_integer(char *, fbint_t); 1236212Saw148015 static void parser_set_var(char *, char *); 1246212Saw148015 1255184Sek110237 /* Shutdown Commands */ 1265184Sek110237 static void parser_proc_shutdown(cmd_t *); 1275184Sek110237 static void parser_filebench_shutdown(cmd_t *cmd); 1285184Sek110237 1295184Sek110237 /* Other Commands */ 1305184Sek110237 static void parser_foreach_integer(cmd_t *cmd); 1315184Sek110237 static void parser_foreach_string(cmd_t *cmd); 1325184Sek110237 static void parser_sleep(cmd_t *cmd); 1335184Sek110237 static void parser_sleep_variable(cmd_t *cmd); 1345184Sek110237 static void parser_log(cmd_t *cmd); 1355184Sek110237 static void parser_statscmd(cmd_t *cmd); 1365184Sek110237 static void parser_statsdump(cmd_t *cmd); 1375184Sek110237 static void parser_statsxmldump(cmd_t *cmd); 1385184Sek110237 static void parser_echo(cmd_t *cmd); 1395184Sek110237 static void parser_usage(cmd_t *cmd); 1405184Sek110237 static void parser_vars(cmd_t *cmd); 1415184Sek110237 static void parser_printvars(cmd_t *cmd); 1425184Sek110237 static void parser_system(cmd_t *cmd); 1435184Sek110237 static void parser_statssnap(cmd_t *cmd); 1445184Sek110237 static void parser_directory(cmd_t *cmd); 1455184Sek110237 static void parser_eventgen(cmd_t *cmd); 1465184Sek110237 static void parser_run(cmd_t *cmd); 1475184Sek110237 static void parser_run_variable(cmd_t *cmd); 1485184Sek110237 static void parser_help(cmd_t *cmd); 1495184Sek110237 static void arg_parse(const char *command); 1505184Sek110237 static void parser_abort(int arg); 151*6750Sek110237 static void parser_version(cmd_t *cmd); 1525184Sek110237 1535184Sek110237 %} 1545184Sek110237 1555184Sek110237 %union { 1566212Saw148015 int64_t ival; 1576212Saw148015 uchar_t bval; 1586212Saw148015 char * sval; 1596212Saw148015 fs_u val; 1606212Saw148015 avd_t avd; 1616212Saw148015 cmd_t *cmd; 1626212Saw148015 attr_t *attr; 1636212Saw148015 list_t *list; 1646212Saw148015 probtabent_t *rndtb; 1655184Sek110237 } 1665184Sek110237 1675184Sek110237 %start commands 1685184Sek110237 1695184Sek110237 %token FSC_LIST FSC_DEFINE FSC_EXEC FSC_QUIT FSC_DEBUG FSC_CREATE 1705184Sek110237 %token FSC_SLEEP FSC_STATS FSC_FOREACH FSC_SET FSC_SHUTDOWN FSC_LOG 1715184Sek110237 %token FSC_SYSTEM FSC_FLOWOP FSC_EVENTGEN FSC_ECHO FSC_LOAD FSC_RUN 172*6750Sek110237 %token FSC_USAGE FSC_HELP FSC_VARS FSC_VERSION 1735184Sek110237 %token FSV_STRING FSV_VAL_INT FSV_VAL_BOOLEAN FSV_VARIABLE FSV_WHITESTRING 1746212Saw148015 %token FSV_RANDUNI FSV_RANDTAB FSV_RANDVAR FSV_URAND FSV_RAND48 1755184Sek110237 %token FST_INT FST_BOOLEAN 1765184Sek110237 %token FSE_FILE FSE_PROC FSE_THREAD FSE_CLEAR FSE_ALL FSE_SNAP FSE_DUMP 1776212Saw148015 %token FSE_DIRECTORY FSE_COMMAND FSE_FILESET FSE_XMLDUMP FSE_RAND FSE_MODE 1785184Sek110237 %token FSK_SEPLST FSK_OPENLST FSK_CLOSELST FSK_ASSIGN FSK_IN FSK_QUOTE 1795184Sek110237 %token FSK_DIRSEPLST 1805184Sek110237 %token FSA_SIZE FSA_PREALLOC FSA_PARALLOC FSA_PATH FSA_REUSE 1815184Sek110237 %token FSA_PROCESS FSA_MEMSIZE FSA_RATE FSA_CACHED 1825184Sek110237 %token FSA_IOSIZE FSA_FILE FSA_WSS FSA_NAME FSA_RANDOM FSA_INSTANCES 1835184Sek110237 %token FSA_DSYNC FSA_TARGET FSA_ITERS FSA_NICE FSA_VALUE FSA_BLOCKING 1845184Sek110237 %token FSA_HIGHWATER FSA_DIRECTIO FSA_DIRWIDTH FSA_FD FSA_SRCFD FSA_ROTATEFD 1856212Saw148015 %token FSA_NAMELENGTH FSA_FILESIZE FSA_ENTRIES FSA_FILESIZEGAMMA FSA_DIRDEPTHRV 1866212Saw148015 %token FSA_DIRGAMMA FSA_USEISM FSA_TYPE FSA_RANDTABLE FSA_RANDSRC FSA_RANDROUND 1876212Saw148015 %token FSA_RANDSEED FSA_RANDGAMMA FSA_RANDMEAN FSA_RANDMIN 1886212Saw148015 %token FSS_TYPE FSS_SEED FSS_GAMMA FSS_MEAN FSS_MIN FSS_SRC FSS_ROUND 1896550Saw148015 %token FSV_SET_LOCAL_VAR FSA_LVAR_ASSIGN 1906212Saw148015 %token FSA_ALLDONE FSA_FIRSTDONE FSA_TIMEOUT 1915184Sek110237 1925184Sek110237 %type <ival> FSV_VAL_INT 1935184Sek110237 %type <bval> FSV_VAL_BOOLEAN 1945184Sek110237 %type <sval> FSV_STRING 1955184Sek110237 %type <sval> FSV_WHITESTRING 1965184Sek110237 %type <sval> FSV_VARIABLE 1976212Saw148015 %type <sval> FSV_RANDVAR 1985184Sek110237 %type <sval> FSK_ASSIGN 1996550Saw148015 %type <sval> FSV_SET_LOCAL_VAR 2005184Sek110237 2015184Sek110237 %type <ival> FSC_LIST FSC_DEFINE FSC_SET FSC_LOAD FSC_RUN 202*6750Sek110237 %type <ival> FSE_FILE FSE_PROC FSE_THREAD FSE_CLEAR FSC_HELP FSC_VERSION 2035184Sek110237 2045184Sek110237 %type <sval> name 2055184Sek110237 %type <ival> entity 2065184Sek110237 %type <val> value 2075184Sek110237 2086212Saw148015 %type <cmd> command inner_commands load_command run_command list_command 2096212Saw148015 %type <cmd> proc_define_command files_define_command randvar_define_command 2106550Saw148015 %type <cmd> fo_define_command debug_command create_command 2115184Sek110237 %type <cmd> sleep_command stats_command set_command shutdown_command 2125184Sek110237 %type <cmd> foreach_command log_command system_command flowop_command 2135184Sek110237 %type <cmd> eventgen_command quit_command flowop_list thread_list 2145184Sek110237 %type <cmd> thread echo_command usage_command help_command vars_command 215*6750Sek110237 %type <cmd> version_command 2165184Sek110237 2176212Saw148015 %type <attr> files_attr_op files_attr_ops pt_attr_op pt_attr_ops 2186212Saw148015 %type <attr> fo_attr_op fo_attr_ops ev_attr_op ev_attr_ops 2196212Saw148015 %type <attr> randvar_attr_op randvar_attr_ops randvar_attr_typop 2206212Saw148015 %type <attr> randvar_attr_srcop attr_value attr_list_value 2216550Saw148015 %type <attr> comp_lvar_def comp_attr_op comp_attr_ops 2226212Saw148015 %type <list> integer_seplist string_seplist string_list var_string_list 2236212Saw148015 %type <list> var_string whitevar_string whitevar_string_list 2246212Saw148015 %type <ival> attrs_define_file attrs_define_thread attrs_flowop 2256550Saw148015 %type <ival> attrs_define_fileset attrs_define_proc attrs_eventgen attrs_define_comp 2266212Saw148015 %type <ival> files_attr_name pt_attr_name fo_attr_name ev_attr_name 2276212Saw148015 %type <ival> randvar_attr_name FSA_TYPE randtype_name randvar_attr_param 2286212Saw148015 %type <ival> randsrc_name FSA_RANDSRC randvar_attr_tsp 2296212Saw148015 %type <ival> FSS_TYPE FSS_SEED FSS_GAMMA FSS_MEAN FSS_MIN FSS_SRC 2306212Saw148015 2316212Saw148015 %type <rndtb> probtabentry_list probtabentry 2326212Saw148015 %type <avd> var_int_val 2335184Sek110237 %% 2345184Sek110237 2355184Sek110237 commands: commands command 2365184Sek110237 { 2375184Sek110237 list_t *list = NULL; 2385184Sek110237 list_t *list_end = NULL; 2395184Sek110237 2405184Sek110237 if ($2->cmd != NULL) 2415184Sek110237 $2->cmd($2); 2425184Sek110237 2435184Sek110237 free($2); 2445184Sek110237 } 2455184Sek110237 | commands error 2465184Sek110237 { 2475184Sek110237 if (dofile) 2485184Sek110237 YYABORT; 2495184Sek110237 } 2505184Sek110237 |; 2515184Sek110237 2525184Sek110237 inner_commands: command 2535184Sek110237 { 2545184Sek110237 filebench_log(LOG_DEBUG_IMPL, "inner_command %zx", $1); 2555184Sek110237 $$ = $1; 2565184Sek110237 } 2575184Sek110237 | inner_commands command 2585184Sek110237 { 2595184Sek110237 cmd_t *list = NULL; 2605184Sek110237 cmd_t *list_end = NULL; 2615184Sek110237 2625184Sek110237 /* Find end of list */ 2635184Sek110237 for (list = $1; list != NULL; 2645184Sek110237 list = list->cmd_next) 2655184Sek110237 list_end = list; 2665184Sek110237 2675184Sek110237 list_end->cmd_next = $2; 2685184Sek110237 2695184Sek110237 filebench_log(LOG_DEBUG_IMPL, 2705184Sek110237 "inner_commands adding cmd %zx to list %zx", $2, $1); 2715184Sek110237 2725184Sek110237 $$ = $1; 2735184Sek110237 }; 2745184Sek110237 2755184Sek110237 command: 2766212Saw148015 proc_define_command 2776212Saw148015 | files_define_command 2786212Saw148015 | randvar_define_command 2796550Saw148015 | fo_define_command 2805184Sek110237 | debug_command 2815184Sek110237 | eventgen_command 2825184Sek110237 | create_command 2835184Sek110237 | echo_command 2845184Sek110237 | usage_command 2855184Sek110237 | vars_command 2865184Sek110237 | foreach_command 2875184Sek110237 | help_command 2885184Sek110237 | list_command 2895184Sek110237 | load_command 2905184Sek110237 | log_command 2915184Sek110237 | run_command 2925184Sek110237 | set_command 2935184Sek110237 | shutdown_command 2945184Sek110237 | sleep_command 2955184Sek110237 | stats_command 2965184Sek110237 | system_command 297*6750Sek110237 | version_command 2985184Sek110237 | quit_command; 2995184Sek110237 3005184Sek110237 foreach_command: FSC_FOREACH 3015184Sek110237 { 3025184Sek110237 if (($$ = alloc_cmd()) == NULL) 3035184Sek110237 YYERROR; 3045184Sek110237 filebench_log(LOG_DEBUG_IMPL, "foreach_command %zx", $$); 3055184Sek110237 } 3065184Sek110237 | foreach_command FSV_VARIABLE FSK_IN integer_seplist FSK_OPENLST inner_commands FSK_CLOSELST 3075184Sek110237 { 3085184Sek110237 cmd_t *cmd, *inner_cmd; 3095184Sek110237 list_t *list; 3105184Sek110237 3115184Sek110237 $$ = $1; 3125184Sek110237 $$->cmd_list = $6; 3135184Sek110237 $$->cmd_tgt1 = $2; 3145184Sek110237 $$->cmd_param_list = $4; 3155184Sek110237 $$->cmd = parser_foreach_integer; 3165184Sek110237 3175184Sek110237 for (list = $$->cmd_param_list; list != NULL; 3185184Sek110237 list = list->list_next) { 3195184Sek110237 for (inner_cmd = $$->cmd_list; 3205184Sek110237 inner_cmd != NULL; 3215184Sek110237 inner_cmd = inner_cmd->cmd_next) { 3225184Sek110237 filebench_log(LOG_DEBUG_IMPL, 3236286Saw148015 "packing foreach: %zx %s=%llu, cmd %zx", 3246212Saw148015 $$, $$->cmd_tgt1, 3256286Saw148015 (u_longlong_t)avd_get_int(list->list_integer), 3266286Saw148015 inner_cmd); 3275184Sek110237 } 3285184Sek110237 } 3295184Sek110237 }| foreach_command FSV_VARIABLE FSK_IN string_seplist FSK_OPENLST inner_commands FSK_CLOSELST 3305184Sek110237 { 3315184Sek110237 cmd_t *cmd, *inner_cmd; 3325184Sek110237 list_t *list; 3335184Sek110237 3345184Sek110237 $$ = $1; 3355184Sek110237 $$->cmd_list = $6; 3365184Sek110237 $$->cmd_tgt1 = $2; 3375184Sek110237 $$->cmd_param_list = $4; 3385184Sek110237 $$->cmd = parser_foreach_string; 3395184Sek110237 3405184Sek110237 for (list = $$->cmd_param_list; list != NULL; 3415184Sek110237 list = list->list_next) { 3425184Sek110237 for (inner_cmd = $$->cmd_list; 3435184Sek110237 inner_cmd != NULL; 3445184Sek110237 inner_cmd = inner_cmd->cmd_next) { 3455184Sek110237 filebench_log(LOG_DEBUG_IMPL, 3465184Sek110237 "packing foreach: %zx %s=%s, cmd %zx", 3475184Sek110237 $$, 3485184Sek110237 $$->cmd_tgt1, 3495184Sek110237 *list->list_string, inner_cmd); 3505184Sek110237 } 3515184Sek110237 } 3525184Sek110237 }; 3535184Sek110237 3545184Sek110237 integer_seplist: FSV_VAL_INT 3555184Sek110237 { 3565184Sek110237 if (($$ = alloc_list()) == NULL) 3575184Sek110237 YYERROR; 3585184Sek110237 3596212Saw148015 $$->list_integer = avd_int_alloc($1); 3605184Sek110237 } 3615184Sek110237 | integer_seplist FSK_SEPLST FSV_VAL_INT 3625184Sek110237 { 3635184Sek110237 list_t *list = NULL; 3645184Sek110237 list_t *list_end = NULL; 3655184Sek110237 3665184Sek110237 if (($$ = alloc_list()) == NULL) 3675184Sek110237 YYERROR; 3685184Sek110237 3696212Saw148015 $$->list_integer = avd_int_alloc($3); 3705184Sek110237 3715184Sek110237 /* Find end of list */ 3725184Sek110237 for (list = $1; list != NULL; 3735184Sek110237 list = list->list_next) 3745184Sek110237 list_end = list; 3755184Sek110237 list_end->list_next = $$; 3765184Sek110237 $$ = $1; 3775184Sek110237 }; 3785184Sek110237 3795184Sek110237 string_seplist: FSK_QUOTE FSV_WHITESTRING FSK_QUOTE 3805184Sek110237 { 3815184Sek110237 if (($$ = alloc_list()) == NULL) 3825184Sek110237 YYERROR; 3835184Sek110237 3846212Saw148015 $$->list_string = avd_str_alloc($2); 3855184Sek110237 } 3865184Sek110237 | string_seplist FSK_SEPLST FSK_QUOTE FSV_WHITESTRING FSK_QUOTE 3875184Sek110237 { 3885184Sek110237 list_t *list = NULL; 3895184Sek110237 list_t *list_end = NULL; 3905184Sek110237 3915184Sek110237 if (($$ = alloc_list()) == NULL) 3925184Sek110237 YYERROR; 3935184Sek110237 3946212Saw148015 $$->list_string = avd_str_alloc($4); 3955184Sek110237 3965184Sek110237 /* Find end of list */ 3975184Sek110237 for (list = $1; list != NULL; 3985184Sek110237 list = list->list_next) 3995184Sek110237 list_end = list; 4005184Sek110237 list_end->list_next = $$; 4015184Sek110237 $$ = $1; 4025184Sek110237 }; 4035184Sek110237 4045184Sek110237 eventgen_command: FSC_EVENTGEN 4055184Sek110237 { 4065184Sek110237 if (($$ = alloc_cmd()) == NULL) 4075184Sek110237 YYERROR; 4085184Sek110237 $$->cmd = &parser_eventgen; 4095184Sek110237 } 4106212Saw148015 | eventgen_command ev_attr_ops 4115184Sek110237 { 4125184Sek110237 $1->cmd_attr_list = $2; 4135184Sek110237 }; 4145184Sek110237 4155184Sek110237 system_command: FSC_SYSTEM whitevar_string_list 4165184Sek110237 { 4175184Sek110237 if (($$ = alloc_cmd()) == NULL) 4185184Sek110237 YYERROR; 4195184Sek110237 4205184Sek110237 $$->cmd_param_list = $2; 4215184Sek110237 $$->cmd = parser_system; 4225184Sek110237 }; 4235184Sek110237 4245184Sek110237 echo_command: FSC_ECHO whitevar_string_list 4255184Sek110237 { 4265184Sek110237 if (($$ = alloc_cmd()) == NULL) 4275184Sek110237 YYERROR; 4285184Sek110237 4295184Sek110237 $$->cmd_param_list = $2; 4305184Sek110237 $$->cmd = parser_echo; 4315184Sek110237 }; 4325184Sek110237 433*6750Sek110237 version_command: FSC_VERSION 434*6750Sek110237 { 435*6750Sek110237 if (($$ = alloc_cmd()) == NULL) 436*6750Sek110237 YYERROR; 437*6750Sek110237 $$->cmd = parser_version; 438*6750Sek110237 }; 439*6750Sek110237 4405184Sek110237 usage_command: FSC_USAGE whitevar_string_list 4415184Sek110237 { 4425184Sek110237 if (($$ = alloc_cmd()) == NULL) 4435184Sek110237 YYERROR; 4445184Sek110237 4455184Sek110237 $$->cmd_param_list = $2; 4465184Sek110237 $$->cmd = parser_usage; 4475184Sek110237 }; 4485184Sek110237 4495184Sek110237 vars_command: FSC_VARS 4505184Sek110237 { 4515184Sek110237 if (($$ = alloc_cmd()) == NULL) 4525184Sek110237 YYERROR; 4535184Sek110237 4545184Sek110237 $$->cmd = parser_printvars; 4555184Sek110237 }; 4565184Sek110237 4575184Sek110237 string_list: FSV_VARIABLE 4585184Sek110237 { 4595184Sek110237 if (($$ = alloc_list()) == NULL) 4605184Sek110237 YYERROR; 4616212Saw148015 $$->list_string = avd_str_alloc($1); 4625184Sek110237 } 4635184Sek110237 | string_list FSK_SEPLST FSV_VARIABLE 4645184Sek110237 { 4655184Sek110237 list_t *list = NULL; 4665184Sek110237 list_t *list_end = NULL; 4675184Sek110237 4685184Sek110237 if (($$ = alloc_list()) == NULL) 4695184Sek110237 YYERROR; 4705184Sek110237 4716212Saw148015 $$->list_string = avd_str_alloc($3); 4725184Sek110237 4735184Sek110237 /* Find end of list */ 4745184Sek110237 for (list = $1; list != NULL; 4755184Sek110237 list = list->list_next) 4765184Sek110237 list_end = list; 4775184Sek110237 list_end->list_next = $$; 4785184Sek110237 $$ = $1; 4795184Sek110237 }; 4805184Sek110237 4815184Sek110237 var_string: FSV_VARIABLE 4825184Sek110237 { 4835184Sek110237 if (($$ = alloc_list()) == NULL) 4845184Sek110237 YYERROR; 4855184Sek110237 4866212Saw148015 $$->list_string = avd_str_alloc($1); 4875184Sek110237 } 4885184Sek110237 | FSV_STRING 4895184Sek110237 { 4905184Sek110237 if (($$ = alloc_list()) == NULL) 4915184Sek110237 YYERROR; 4925184Sek110237 4936212Saw148015 $$->list_string = avd_str_alloc($1); 4945184Sek110237 }; 4955184Sek110237 4965184Sek110237 var_string_list: var_string 4975184Sek110237 { 4985184Sek110237 $$ = $1; 4995184Sek110237 }| var_string FSV_STRING 5005184Sek110237 { 5015184Sek110237 list_t *list = NULL; 5025184Sek110237 list_t *list_end = NULL; 5035184Sek110237 5045184Sek110237 /* Add string */ 5055184Sek110237 if (($$ = alloc_list()) == NULL) 5065184Sek110237 YYERROR; 5075184Sek110237 5086212Saw148015 $$->list_string = avd_str_alloc($2); 5095184Sek110237 5105184Sek110237 /* Find end of list */ 5115184Sek110237 for (list = $1; list != NULL; 5125184Sek110237 list = list->list_next) 5135184Sek110237 list_end = list; 5145184Sek110237 list_end->list_next = $$; 5155184Sek110237 $$ = $1; 5165184Sek110237 5175184Sek110237 }| var_string FSV_VARIABLE 5185184Sek110237 { 5195184Sek110237 list_t *list = NULL; 5205184Sek110237 list_t *list_end = NULL; 5215184Sek110237 5225184Sek110237 /* Add variable */ 5235184Sek110237 if (($$ = alloc_list()) == NULL) 5245184Sek110237 YYERROR; 5255184Sek110237 5266212Saw148015 $$->list_string = avd_str_alloc($2); 5275184Sek110237 5285184Sek110237 /* Find end of list */ 5295184Sek110237 for (list = $1; list != NULL; 5305184Sek110237 list = list->list_next) 5315184Sek110237 list_end = list; 5325184Sek110237 list_end->list_next = $$; 5335184Sek110237 $$ = $1; 5345184Sek110237 } |var_string_list FSV_STRING 5355184Sek110237 { 5365184Sek110237 list_t *list = NULL; 5375184Sek110237 list_t *list_end = NULL; 5385184Sek110237 5395184Sek110237 /* Add string */ 5405184Sek110237 if (($$ = alloc_list()) == NULL) 5415184Sek110237 YYERROR; 5425184Sek110237 5436212Saw148015 $$->list_string = avd_str_alloc($2); 5445184Sek110237 5455184Sek110237 /* Find end of list */ 5465184Sek110237 for (list = $1; list != NULL; 5475184Sek110237 list = list->list_next) 5485184Sek110237 list_end = list; 5495184Sek110237 list_end->list_next = $$; 5505184Sek110237 $$ = $1; 5515184Sek110237 5525184Sek110237 }| var_string_list FSV_VARIABLE 5535184Sek110237 { 5545184Sek110237 list_t *list = NULL; 5555184Sek110237 list_t *list_end = NULL; 5565184Sek110237 5575184Sek110237 /* Add variable */ 5585184Sek110237 if (($$ = alloc_list()) == NULL) 5595184Sek110237 YYERROR; 5605184Sek110237 5616212Saw148015 $$->list_string = avd_str_alloc($2); 5625184Sek110237 5635184Sek110237 /* Find end of list */ 5645184Sek110237 for (list = $1; list != NULL; 5655184Sek110237 list = list->list_next) 5665184Sek110237 list_end = list; 5675184Sek110237 list_end->list_next = $$; 5685184Sek110237 $$ = $1; 5695184Sek110237 }; 5705184Sek110237 5715184Sek110237 whitevar_string: FSK_QUOTE FSV_VARIABLE 5725184Sek110237 { 5735184Sek110237 if (($$ = alloc_list()) == NULL) 5745184Sek110237 YYERROR; 5755184Sek110237 5766212Saw148015 $$->list_string = avd_str_alloc($2); 5775184Sek110237 } 5785184Sek110237 | FSK_QUOTE FSV_WHITESTRING 5795184Sek110237 { 5805184Sek110237 if (($$ = alloc_list()) == NULL) 5815184Sek110237 YYERROR; 5825184Sek110237 5836212Saw148015 $$->list_string = avd_str_alloc($2); 5845184Sek110237 }; 5855184Sek110237 5865184Sek110237 whitevar_string_list: whitevar_string FSV_WHITESTRING 5875184Sek110237 { 5885184Sek110237 list_t *list = NULL; 5895184Sek110237 list_t *list_end = NULL; 5905184Sek110237 5915184Sek110237 /* Add string */ 5925184Sek110237 if (($$ = alloc_list()) == NULL) 5935184Sek110237 YYERROR; 5945184Sek110237 5956212Saw148015 $$->list_string = avd_str_alloc($2); 5965184Sek110237 5975184Sek110237 /* Find end of list */ 5985184Sek110237 for (list = $1; list != NULL; 5995184Sek110237 list = list->list_next) 6005184Sek110237 list_end = list; 6015184Sek110237 list_end->list_next = $$; 6025184Sek110237 $$ = $1; 6035184Sek110237 6045184Sek110237 }| whitevar_string FSV_VARIABLE 6055184Sek110237 { 6065184Sek110237 list_t *list = NULL; 6075184Sek110237 list_t *list_end = NULL; 6085184Sek110237 6095184Sek110237 /* Add variable */ 6105184Sek110237 if (($$ = alloc_list()) == NULL) 6115184Sek110237 YYERROR; 6125184Sek110237 6136212Saw148015 $$->list_string = avd_str_alloc($2); 6145184Sek110237 6155184Sek110237 /* Find end of list */ 6165184Sek110237 for (list = $1; list != NULL; 6175184Sek110237 list = list->list_next) 6185184Sek110237 list_end = list; 6195184Sek110237 list_end->list_next = $$; 6205184Sek110237 $$ = $1; 6216212Saw148015 }| whitevar_string FSV_RANDVAR randvar_attr_tsp 6226212Saw148015 { 6236212Saw148015 list_t *list = NULL; 6246212Saw148015 list_t *list_end = NULL; 6256212Saw148015 6266212Saw148015 /* Add variable */ 6276212Saw148015 if (($$ = alloc_list()) == NULL) 6286212Saw148015 YYERROR; 6296212Saw148015 6306212Saw148015 $$->list_string = avd_str_alloc($2); 6316212Saw148015 $$->list_integer = avd_int_alloc($3); 6326212Saw148015 6336212Saw148015 /* Find end of list */ 6346212Saw148015 for (list = $1; list != NULL; 6356212Saw148015 list = list->list_next) 6366212Saw148015 list_end = list; 6376212Saw148015 list_end->list_next = $$; 6386212Saw148015 $$ = $1; 6396212Saw148015 }| whitevar_string_list FSV_WHITESTRING 6405184Sek110237 { 6415184Sek110237 list_t *list = NULL; 6425184Sek110237 list_t *list_end = NULL; 6435184Sek110237 6445184Sek110237 /* Add string */ 6455184Sek110237 if (($$ = alloc_list()) == NULL) 6465184Sek110237 YYERROR; 6475184Sek110237 6486212Saw148015 $$->list_string = avd_str_alloc($2); 6495184Sek110237 6505184Sek110237 /* Find end of list */ 6515184Sek110237 for (list = $1; list != NULL; 6525184Sek110237 list = list->list_next) 6535184Sek110237 list_end = list; 6545184Sek110237 list_end->list_next = $$; 6555184Sek110237 $$ = $1; 6565184Sek110237 6575184Sek110237 }| whitevar_string_list FSV_VARIABLE 6585184Sek110237 { 6595184Sek110237 list_t *list = NULL; 6605184Sek110237 list_t *list_end = NULL; 6615184Sek110237 6625184Sek110237 /* Add variable */ 6635184Sek110237 if (($$ = alloc_list()) == NULL) 6645184Sek110237 YYERROR; 6655184Sek110237 6666212Saw148015 $$->list_string = avd_str_alloc($2); 6676212Saw148015 6686212Saw148015 /* Find end of list */ 6696212Saw148015 for (list = $1; list != NULL; 6706212Saw148015 list = list->list_next) 6716212Saw148015 list_end = list; 6726212Saw148015 list_end->list_next = $$; 6736212Saw148015 $$ = $1; 6746212Saw148015 }| whitevar_string_list FSV_RANDVAR randvar_attr_tsp 6756212Saw148015 { 6766212Saw148015 list_t *list = NULL; 6776212Saw148015 list_t *list_end = NULL; 6786212Saw148015 6796212Saw148015 /* Add variable */ 6806212Saw148015 if (($$ = alloc_list()) == NULL) 6816212Saw148015 YYERROR; 6826212Saw148015 6836212Saw148015 $$->list_string = avd_str_alloc($2); 6846212Saw148015 $$->list_integer = avd_int_alloc($3); 6855184Sek110237 6865184Sek110237 /* Find end of list */ 6875184Sek110237 for (list = $1; list != NULL; 6885184Sek110237 list = list->list_next) 6895184Sek110237 list_end = list; 6905184Sek110237 list_end->list_next = $$; 6915184Sek110237 $$ = $1; 6925184Sek110237 }| whitevar_string_list FSK_QUOTE 6935184Sek110237 { 6945184Sek110237 $$ = $1; 6955184Sek110237 }| whitevar_string FSK_QUOTE 6965184Sek110237 { 6975184Sek110237 $$ = $1; 6985184Sek110237 }; 6995184Sek110237 7005184Sek110237 list_command: FSC_LIST 7015184Sek110237 { 7025184Sek110237 if (($$ = alloc_cmd()) == NULL) 7035184Sek110237 YYERROR; 7045184Sek110237 $$->cmd = &parser_list; 7056212Saw148015 } 7066212Saw148015 | list_command FSC_FLOWOP 7076212Saw148015 { 7086212Saw148015 $1->cmd = &parser_flowop_list; 7095184Sek110237 }; 7105184Sek110237 7115184Sek110237 log_command: FSC_LOG whitevar_string_list 7125184Sek110237 { 7135184Sek110237 if (($$ = alloc_cmd()) == NULL) 7145184Sek110237 YYERROR; 7155184Sek110237 $$->cmd = &parser_log; 7165184Sek110237 $$->cmd_param_list = $2; 7175184Sek110237 }; 7185184Sek110237 7195184Sek110237 debug_command: FSC_DEBUG FSV_VAL_INT 7205184Sek110237 { 7215184Sek110237 if (($$ = alloc_cmd()) == NULL) 7225184Sek110237 YYERROR; 7235184Sek110237 $$->cmd = NULL; 7246391Saw148015 filebench_shm->shm_debug_level = $2; 7256391Saw148015 if (filebench_shm->shm_debug_level > 9) 7265184Sek110237 yydebug = 1; 7275184Sek110237 }; 7285184Sek110237 7295184Sek110237 set_command: FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_VAL_INT 7305184Sek110237 { 7315184Sek110237 if (($$ = alloc_cmd()) == NULL) 7325184Sek110237 YYERROR; 7335184Sek110237 var_assign_integer($2, $4); 7345184Sek110237 if (parentscript) { 7355184Sek110237 $$->cmd_tgt1 = $2; 7365184Sek110237 parser_vars($$); 7375184Sek110237 } 7385184Sek110237 $$->cmd = NULL; 7395184Sek110237 } 7406212Saw148015 | FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_VAL_BOOLEAN 7416212Saw148015 { 7426212Saw148015 if (($$ = alloc_cmd()) == NULL) 7436212Saw148015 YYERROR; 7446212Saw148015 var_assign_boolean($2, $4); 7456212Saw148015 if (parentscript) { 7466212Saw148015 $$->cmd_tgt1 = $2; 7476212Saw148015 parser_vars($$); 7486212Saw148015 } 7496212Saw148015 $$->cmd = NULL; 7506212Saw148015 } 7515184Sek110237 | FSC_SET FSV_VARIABLE FSK_ASSIGN FSK_QUOTE FSV_WHITESTRING FSK_QUOTE 7525184Sek110237 { 7535184Sek110237 if (($$ = alloc_cmd()) == NULL) 7545184Sek110237 YYERROR; 7555184Sek110237 var_assign_string($2, $5); 7565184Sek110237 if (parentscript) { 7575184Sek110237 $$->cmd_tgt1 = $2; 7585184Sek110237 parser_vars($$); 7595184Sek110237 } 7605184Sek110237 $$->cmd = NULL; 7615184Sek110237 }| FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_STRING 7625184Sek110237 { 7635184Sek110237 if (($$ = alloc_cmd()) == NULL) 7645184Sek110237 YYERROR; 7655184Sek110237 var_assign_string($2, $4); 7665184Sek110237 if (parentscript) { 7675184Sek110237 $$->cmd_tgt1 = $2; 7685184Sek110237 parser_vars($$); 7695184Sek110237 } 7705184Sek110237 $$->cmd = NULL; 7715184Sek110237 }| FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_VARIABLE 7725184Sek110237 { 7735184Sek110237 if (($$ = alloc_cmd()) == NULL) 7745184Sek110237 YYERROR; 7755184Sek110237 var_assign_var($2, $4); 7765184Sek110237 if (parentscript) { 7775184Sek110237 $$->cmd_tgt1 = $2; 7785184Sek110237 parser_vars($$); 7795184Sek110237 } 7805184Sek110237 $$->cmd = NULL; 7816084Saw148015 } | FSC_SET FSE_MODE FSC_QUIT FSA_TIMEOUT 7826084Saw148015 { 7836084Saw148015 filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT; 7846084Saw148015 if (($$ = alloc_cmd()) == NULL) 7856084Saw148015 YYERROR; 7866084Saw148015 $$->cmd = NULL; 7876084Saw148015 } | FSC_SET FSE_MODE FSC_QUIT FSA_ALLDONE 7886084Saw148015 { 7896084Saw148015 filebench_shm->shm_rmode = FILEBENCH_MODE_QALLDONE; 7906084Saw148015 if (($$ = alloc_cmd()) == NULL) 7916084Saw148015 YYERROR; 7926084Saw148015 $$->cmd = NULL; 7936084Saw148015 } | FSC_SET FSE_MODE FSC_QUIT FSA_FIRSTDONE 7946084Saw148015 { 7956084Saw148015 filebench_shm->shm_rmode = FILEBENCH_MODE_Q1STDONE; 7966084Saw148015 if (($$ = alloc_cmd()) == NULL) 7976084Saw148015 YYERROR; 7986084Saw148015 $$->cmd = NULL; 7996212Saw148015 }| FSC_SET FSV_RANDVAR FSS_TYPE FSK_ASSIGN randvar_attr_typop 8006212Saw148015 { 8016212Saw148015 if (($$ = alloc_cmd()) == NULL) 8026212Saw148015 YYERROR; 8036212Saw148015 $$->cmd = &parser_randvar_set; 8046212Saw148015 $$->cmd_tgt1 = $2; 8056212Saw148015 $$->cmd_qty = FSS_TYPE; 8066212Saw148015 $$->cmd_attr_list = $5; 8076212Saw148015 8086212Saw148015 }| FSC_SET FSV_RANDVAR FSS_SRC FSK_ASSIGN randvar_attr_srcop 8096212Saw148015 { 8106212Saw148015 if (($$ = alloc_cmd()) == NULL) 8116212Saw148015 YYERROR; 8126212Saw148015 $$->cmd = &parser_randvar_set; 8136212Saw148015 $$->cmd_tgt1 = $2; 8146212Saw148015 $$->cmd_qty = FSS_SRC; 8156212Saw148015 $$->cmd_attr_list = $5; 8166212Saw148015 8176212Saw148015 }| FSC_SET FSV_RANDVAR randvar_attr_param FSK_ASSIGN attr_value 8186212Saw148015 { 8196212Saw148015 if (($$ = alloc_cmd()) == NULL) 8206212Saw148015 YYERROR; 8216212Saw148015 $$->cmd = &parser_randvar_set; 8226212Saw148015 $$->cmd_tgt1 = $2; 8236212Saw148015 $$->cmd_qty = $3; 8246212Saw148015 $$->cmd_attr_list = $5; 8256212Saw148015 8265184Sek110237 }; 8275184Sek110237 8285184Sek110237 stats_command: FSC_STATS FSE_SNAP 8295184Sek110237 { 8305184Sek110237 if (($$ = alloc_cmd()) == NULL) 8315184Sek110237 YYERROR; 8325184Sek110237 $$->cmd = (void (*)(struct cmd *))&parser_statssnap; 8335184Sek110237 break; 8345184Sek110237 8355184Sek110237 } 8365184Sek110237 | FSC_STATS FSE_CLEAR 8375184Sek110237 { 8385184Sek110237 if (($$ = alloc_cmd()) == NULL) 8395184Sek110237 YYERROR; 8405184Sek110237 $$->cmd = (void (*)(struct cmd *))&stats_clear; 8415184Sek110237 8425184Sek110237 } 8435184Sek110237 | FSC_STATS FSE_DIRECTORY var_string_list 8445184Sek110237 { 8455184Sek110237 if (($$ = alloc_cmd()) == NULL) 8465184Sek110237 YYERROR; 8475184Sek110237 $$->cmd_param_list = $3; 8485184Sek110237 $$->cmd = (void (*)(struct cmd *))&parser_directory; 8495184Sek110237 8505184Sek110237 } 8515184Sek110237 | FSC_STATS FSE_COMMAND whitevar_string_list 8525184Sek110237 { 8535184Sek110237 if (($$ = alloc_cmd()) == NULL) 8545184Sek110237 YYERROR; 8555184Sek110237 8565184Sek110237 $$->cmd_param_list = $3; 8575184Sek110237 $$->cmd = parser_statscmd; 8585184Sek110237 8595184Sek110237 }| FSC_STATS FSE_DUMP whitevar_string_list 8605184Sek110237 { 8615184Sek110237 if (($$ = alloc_cmd()) == NULL) 8625184Sek110237 YYERROR; 8635184Sek110237 8645184Sek110237 $$->cmd_param_list = $3; 8655184Sek110237 $$->cmd = parser_statsdump; 8665184Sek110237 }| FSC_STATS FSE_XMLDUMP whitevar_string_list 8675184Sek110237 { 8685184Sek110237 if (($$ = alloc_cmd()) == NULL) 8695184Sek110237 YYERROR; 8705184Sek110237 8715184Sek110237 $$->cmd_param_list = $3; 8725184Sek110237 $$->cmd = parser_statsxmldump; 8735184Sek110237 }; 8745184Sek110237 8755184Sek110237 quit_command: FSC_QUIT 8765184Sek110237 { 8775184Sek110237 if (($$ = alloc_cmd()) == NULL) 8785184Sek110237 YYERROR; 8795184Sek110237 $$->cmd = parser_filebench_shutdown; 8805184Sek110237 }; 8815184Sek110237 8825184Sek110237 flowop_list: flowop_command 8835184Sek110237 { 8845184Sek110237 $$ = $1; 8855184Sek110237 }| flowop_list flowop_command 8865184Sek110237 { 8875184Sek110237 cmd_t *list = NULL; 8885184Sek110237 cmd_t *list_end = NULL; 8895184Sek110237 8905184Sek110237 /* Find end of list */ 8915184Sek110237 for (list = $1; list != NULL; 8925184Sek110237 list = list->cmd_next) 8935184Sek110237 list_end = list; 8945184Sek110237 8955184Sek110237 list_end->cmd_next = $2; 8965184Sek110237 8975184Sek110237 filebench_log(LOG_DEBUG_IMPL, 8985184Sek110237 "flowop_list adding cmd %zx to list %zx", $2, $1); 8995184Sek110237 9005184Sek110237 $$ = $1; 9015184Sek110237 }; 9025184Sek110237 9036212Saw148015 thread: FSE_THREAD pt_attr_ops FSK_OPENLST flowop_list FSK_CLOSELST 9045184Sek110237 { 9055184Sek110237 /* 9065184Sek110237 * Allocate a cmd node per thread, with a 9075184Sek110237 * list of flowops attached to the cmd_list 9085184Sek110237 */ 9095184Sek110237 if (($$ = alloc_cmd()) == NULL) 9105184Sek110237 YYERROR; 9115184Sek110237 $$->cmd_list = $4; 9125184Sek110237 $$->cmd_attr_list = $2; 9135184Sek110237 }; 9145184Sek110237 9155184Sek110237 thread_list: thread 9165184Sek110237 { 9175184Sek110237 $$ = $1; 9185184Sek110237 }| thread_list thread 9195184Sek110237 { 9205184Sek110237 cmd_t *list = NULL; 9215184Sek110237 cmd_t *list_end = NULL; 9225184Sek110237 9235184Sek110237 /* Find end of list */ 9245184Sek110237 for (list = $1; list != NULL; 9255184Sek110237 list = list->cmd_next) 9265184Sek110237 list_end = list; 9275184Sek110237 9285184Sek110237 list_end->cmd_next = $2; 9295184Sek110237 9305184Sek110237 filebench_log(LOG_DEBUG_IMPL, 9315184Sek110237 "thread_list adding cmd %zx to list %zx", $2, $1); 9325184Sek110237 9335184Sek110237 $$ = $1; 9345184Sek110237 }; 9355184Sek110237 9366212Saw148015 proc_define_command: FSC_DEFINE FSE_PROC pt_attr_ops FSK_OPENLST thread_list FSK_CLOSELST 9375184Sek110237 { 9385184Sek110237 if (($$ = alloc_cmd()) == NULL) 9395184Sek110237 YYERROR; 9405184Sek110237 $$->cmd = &parser_proc_define; 9415184Sek110237 $$->cmd_list = $5; 9425184Sek110237 $$->cmd_attr_list = $3; 9435184Sek110237 9446212Saw148015 } 9456212Saw148015 | proc_define_command pt_attr_ops 9466212Saw148015 { 9476212Saw148015 $1->cmd_attr_list = $2; 9486212Saw148015 }; 9496212Saw148015 9506212Saw148015 files_define_command: FSC_DEFINE FSE_FILE 9515184Sek110237 { 9525184Sek110237 if (($$ = alloc_cmd()) == NULL) 9535184Sek110237 YYERROR; 9545184Sek110237 $$->cmd = &parser_file_define; 9555184Sek110237 }| FSC_DEFINE FSE_FILESET 9565184Sek110237 { 9575184Sek110237 if (($$ = alloc_cmd()) == NULL) 9585184Sek110237 YYERROR; 9595184Sek110237 $$->cmd = &parser_fileset_define; 9605184Sek110237 } 9616212Saw148015 | files_define_command files_attr_ops 9625184Sek110237 { 9635184Sek110237 $1->cmd_attr_list = $2; 9645184Sek110237 }; 9655184Sek110237 9666212Saw148015 randvar_define_command: FSC_DEFINE FSE_RAND randvar_attr_ops 9676212Saw148015 { 9686212Saw148015 if (($$ = alloc_cmd()) == NULL) 9696212Saw148015 YYERROR; 9706212Saw148015 $$->cmd = &parser_randvar_define; 9716212Saw148015 $$->cmd_attr_list = $3; 9726212Saw148015 }; 9736212Saw148015 9746550Saw148015 fo_define_command: FSC_DEFINE FSC_FLOWOP comp_attr_ops FSK_OPENLST flowop_list FSK_CLOSELST 9756550Saw148015 { 9766550Saw148015 if (($$ = alloc_cmd()) == NULL) 9776550Saw148015 YYERROR; 9786550Saw148015 $$->cmd = &parser_composite_flowop_define; 9796550Saw148015 $$->cmd_list = $5; 9806550Saw148015 $$->cmd_attr_list = $3; 9816550Saw148015 } 9826550Saw148015 | fo_define_command comp_attr_ops 9836550Saw148015 { 9846550Saw148015 $1->cmd_attr_list = $2; 9856550Saw148015 }; 9866550Saw148015 9875184Sek110237 create_command: FSC_CREATE entity 9885184Sek110237 { 9895184Sek110237 if (($$ = alloc_cmd()) == NULL) 9905184Sek110237 YYERROR; 9915184Sek110237 switch ($2) { 9925184Sek110237 case FSE_PROC: 9935184Sek110237 $$->cmd = &parser_proc_create; 9945184Sek110237 break; 9955673Saw148015 case FSE_FILESET: 9965184Sek110237 case FSE_FILE: 9975184Sek110237 $$->cmd = &parser_fileset_create; 9985184Sek110237 break; 9995184Sek110237 default: 10005184Sek110237 filebench_log(LOG_ERROR, "unknown entity", $2); 10015184Sek110237 YYERROR; 10025184Sek110237 } 10035184Sek110237 10045184Sek110237 }; 10055184Sek110237 10065184Sek110237 shutdown_command: FSC_SHUTDOWN entity 10075184Sek110237 { 10085184Sek110237 if (($$ = alloc_cmd()) == NULL) 10095184Sek110237 YYERROR; 10105184Sek110237 switch ($2) { 10115184Sek110237 case FSE_PROC: 10125184Sek110237 $$->cmd = &parser_proc_shutdown; 10135184Sek110237 break; 10145184Sek110237 default: 10155184Sek110237 filebench_log(LOG_ERROR, "unknown entity", $2); 10165184Sek110237 YYERROR; 10175184Sek110237 } 10185184Sek110237 10195184Sek110237 }; 10205184Sek110237 10215184Sek110237 sleep_command: FSC_SLEEP FSV_VAL_INT 10225184Sek110237 { 10235184Sek110237 if (($$ = alloc_cmd()) == NULL) 10245184Sek110237 YYERROR; 10255184Sek110237 $$->cmd = parser_sleep; 10265184Sek110237 $$->cmd_qty = $2; 10275184Sek110237 } 10285184Sek110237 | FSC_SLEEP FSV_VARIABLE 10295184Sek110237 { 10306212Saw148015 fbint_t *integer; 10315184Sek110237 10325184Sek110237 if (($$ = alloc_cmd()) == NULL) 10335184Sek110237 YYERROR; 10345184Sek110237 $$->cmd = parser_sleep_variable; 10355184Sek110237 $$->cmd_tgt1 = fb_stralloc($2); 10365184Sek110237 }; 10375184Sek110237 10385184Sek110237 run_command: FSC_RUN FSV_VAL_INT 10395184Sek110237 { 10405184Sek110237 if (($$ = alloc_cmd()) == NULL) 10415184Sek110237 YYERROR; 10425184Sek110237 $$->cmd = parser_run; 10435184Sek110237 $$->cmd_qty = $2; 10445184Sek110237 } 10455184Sek110237 | FSC_RUN FSV_VARIABLE 10465184Sek110237 { 10476212Saw148015 fbint_t *integer; 10485184Sek110237 10495184Sek110237 if (($$ = alloc_cmd()) == NULL) 10505184Sek110237 YYERROR; 10515184Sek110237 $$->cmd = parser_run_variable; 10525184Sek110237 $$->cmd_tgt1 = fb_stralloc($2); 10535184Sek110237 } 10545184Sek110237 | FSC_RUN 10555184Sek110237 { 10566212Saw148015 fbint_t *integer; 10575184Sek110237 10585184Sek110237 if (($$ = alloc_cmd()) == NULL) 10595184Sek110237 YYERROR; 10605184Sek110237 $$->cmd = parser_run; 10615184Sek110237 $$->cmd_qty = 60UL; 10625184Sek110237 }; 10635184Sek110237 10645184Sek110237 help_command: FSC_HELP 10655184Sek110237 { 10665184Sek110237 if (($$ = alloc_cmd()) == NULL) 10675184Sek110237 YYERROR; 10685184Sek110237 $$->cmd = parser_help; 10695184Sek110237 }; 10705184Sek110237 10715184Sek110237 flowop_command: FSC_FLOWOP name 10725184Sek110237 { 10735184Sek110237 if (($$ = alloc_cmd()) == NULL) 10745184Sek110237 YYERROR; 10755184Sek110237 $$->cmd_name = fb_stralloc($2); 10765184Sek110237 } 10776212Saw148015 | flowop_command fo_attr_ops 10785184Sek110237 { 10795184Sek110237 $1->cmd_attr_list = $2; 10805184Sek110237 }; 10815184Sek110237 10825184Sek110237 load_command: FSC_LOAD FSV_STRING 10835184Sek110237 { 10845184Sek110237 FILE *newfile; 10855184Sek110237 char loadfile[128]; 10865184Sek110237 10875184Sek110237 if (($$ = alloc_cmd()) == NULL) 10885184Sek110237 YYERROR; 10895184Sek110237 10905184Sek110237 (void) strcpy(loadfile, $2); 10915184Sek110237 (void) strcat(loadfile, ".f"); 10925184Sek110237 10935184Sek110237 if ((newfile = fopen(loadfile, "r")) == NULL) { 10945184Sek110237 (void) strcpy(loadfile, FILEBENCHDIR); 10955184Sek110237 (void) strcat(loadfile, "/workloads/"); 10965184Sek110237 (void) strcat(loadfile, $2); 10975184Sek110237 (void) strcat(loadfile, ".f"); 10985184Sek110237 if ((newfile = fopen(loadfile, "r")) == NULL) { 10995184Sek110237 filebench_log(LOG_ERROR, "Cannot open %s", loadfile); 11005184Sek110237 YYERROR; 11015184Sek110237 } 11025184Sek110237 } 11035184Sek110237 11045184Sek110237 parentscript = yyin; 11055184Sek110237 yyin = newfile; 11065184Sek110237 yy_switchfileparent(yyin); 11075184Sek110237 }; 11085184Sek110237 11096212Saw148015 11105184Sek110237 entity: FSE_PROC {$$ = FSE_PROC;} 11115184Sek110237 | FSE_THREAD {$$ = FSE_THREAD;} 11125184Sek110237 | FSE_FILESET {$$ = FSE_FILESET;} 11135184Sek110237 | FSE_FILE {$$ = FSE_FILE;}; 11145184Sek110237 11155184Sek110237 value: FSV_VAL_INT { $$.i = $1;} 11165184Sek110237 | FSV_STRING { $$.s = $1;} 11175184Sek110237 | FSV_VAL_BOOLEAN { $$.b = $1;}; 11185184Sek110237 11195184Sek110237 name: FSV_STRING; 11205184Sek110237 11216212Saw148015 /* attribute parsing for define file and define fileset */ 11226212Saw148015 files_attr_ops: files_attr_op 11236212Saw148015 { 11246212Saw148015 $$ = $1; 11256212Saw148015 } 11266212Saw148015 | files_attr_ops FSK_SEPLST files_attr_op 11276212Saw148015 { 11286212Saw148015 attr_t *attr = NULL; 11296212Saw148015 attr_t *list_end = NULL; 11306212Saw148015 11316212Saw148015 for (attr = $1; attr != NULL; 11326212Saw148015 attr = attr->attr_next) 11336212Saw148015 list_end = attr; /* Find end of list */ 11346212Saw148015 11356212Saw148015 list_end->attr_next = $3; 11366212Saw148015 11376212Saw148015 $$ = $1; 11386212Saw148015 }; 11396212Saw148015 11406212Saw148015 files_attr_op: files_attr_name FSK_ASSIGN attr_list_value 11416212Saw148015 { 11426212Saw148015 $$ = $3; 11436212Saw148015 $$->attr_name = $1; 11446212Saw148015 } 11456212Saw148015 | files_attr_name 11466212Saw148015 { 11476212Saw148015 if (($$ = alloc_attr()) == NULL) 11486212Saw148015 YYERROR; 11496212Saw148015 $$->attr_name = $1; 11506212Saw148015 }; 11516212Saw148015 11526212Saw148015 /* attribute parsing for random variables */ 11536212Saw148015 randvar_attr_ops: randvar_attr_op 11545184Sek110237 { 11555184Sek110237 $$ = $1; 11565184Sek110237 } 11576212Saw148015 | randvar_attr_ops FSK_SEPLST randvar_attr_op 11586212Saw148015 { 11596212Saw148015 attr_t *attr = NULL; 11606212Saw148015 attr_t *list_end = NULL; 11616212Saw148015 11626212Saw148015 for (attr = $1; attr != NULL; 11636212Saw148015 attr = attr->attr_next) 11646212Saw148015 list_end = attr; /* Find end of list */ 11656212Saw148015 11666212Saw148015 list_end->attr_next = $3; 11676212Saw148015 11686212Saw148015 $$ = $1; 11696212Saw148015 } 11706212Saw148015 | randvar_attr_ops FSK_SEPLST FSA_RANDTABLE FSK_ASSIGN FSK_OPENLST probtabentry_list FSK_CLOSELST 11716212Saw148015 { 11726212Saw148015 attr_t *attr = NULL; 11736212Saw148015 attr_t *list_end = NULL; 11746212Saw148015 11756212Saw148015 for (attr = $1; attr != NULL; 11766212Saw148015 attr = attr->attr_next) 11776212Saw148015 list_end = attr; /* Find end of list */ 11786212Saw148015 11796212Saw148015 11806212Saw148015 if ((attr = alloc_attr()) == NULL) 11816212Saw148015 YYERROR; 11826212Saw148015 11836212Saw148015 attr->attr_name = FSA_RANDTABLE; 11846212Saw148015 attr->attr_obj = (void *)$6; 11856212Saw148015 list_end->attr_next = attr; 11866212Saw148015 $$ = $1; 11876212Saw148015 }; 11886212Saw148015 11896212Saw148015 randvar_attr_op: randvar_attr_name FSK_ASSIGN attr_list_value 11906212Saw148015 { 11916212Saw148015 $$ = $3; 11926212Saw148015 $$->attr_name = $1; 11936212Saw148015 } 11946212Saw148015 | randvar_attr_name 11956212Saw148015 { 11966212Saw148015 if (($$ = alloc_attr()) == NULL) 11976212Saw148015 YYERROR; 11986212Saw148015 $$->attr_name = $1; 11996212Saw148015 } 12006212Saw148015 | FSA_TYPE FSK_ASSIGN randvar_attr_typop 12016212Saw148015 { 12026212Saw148015 $$ = $3; 12036212Saw148015 $$->attr_name = FSA_TYPE; 12046212Saw148015 } 12056212Saw148015 | FSA_RANDSRC FSK_ASSIGN randvar_attr_srcop 12066212Saw148015 { 12076212Saw148015 $$ = $3; 12086212Saw148015 $$->attr_name = FSA_RANDSRC; 12096212Saw148015 }; 12106212Saw148015 12116212Saw148015 probtabentry: FSK_OPENLST var_int_val FSK_SEPLST var_int_val FSK_SEPLST var_int_val FSK_CLOSELST 12126212Saw148015 { 12136212Saw148015 if (($$ = alloc_probtabent()) == NULL) 12146212Saw148015 YYERROR; 12156212Saw148015 $$->pte_percent = $2; 12166212Saw148015 $$->pte_segmin = $4; 12176212Saw148015 $$->pte_segmax = $6; 12186212Saw148015 }; 12196212Saw148015 12206212Saw148015 /* attribute parsing for prob density function table */ 12216212Saw148015 probtabentry_list: probtabentry 12226212Saw148015 { 12236212Saw148015 $$ = $1; 12246212Saw148015 } 12256212Saw148015 | probtabentry_list FSK_SEPLST probtabentry 12266212Saw148015 { 12276212Saw148015 probtabent_t *pte = NULL; 12286212Saw148015 probtabent_t *ptelist_end = NULL; 12296212Saw148015 12306212Saw148015 for (pte = $1; pte != NULL; 12316212Saw148015 pte = pte->pte_next) 12326212Saw148015 ptelist_end = pte; /* Find end of prob table entry list */ 12336212Saw148015 12346212Saw148015 ptelist_end->pte_next = $3; 12356212Saw148015 12366212Saw148015 $$ = $1; 12376212Saw148015 }; 12386212Saw148015 12396212Saw148015 /* attribute parsing for define thread and process */ 12406212Saw148015 pt_attr_ops: pt_attr_op 12416212Saw148015 { 12426212Saw148015 $$ = $1; 12436212Saw148015 } 12446212Saw148015 | pt_attr_ops FSK_SEPLST pt_attr_op 12456212Saw148015 { 12466212Saw148015 attr_t *attr = NULL; 12476212Saw148015 attr_t *list_end = NULL; 12486212Saw148015 12496212Saw148015 for (attr = $1; attr != NULL; 12506212Saw148015 attr = attr->attr_next) 12516212Saw148015 list_end = attr; /* Find end of list */ 12526212Saw148015 12536212Saw148015 list_end->attr_next = $3; 12546212Saw148015 12556212Saw148015 $$ = $1; 12566212Saw148015 }; 12576212Saw148015 12586212Saw148015 pt_attr_op: pt_attr_name FSK_ASSIGN attr_value 12596212Saw148015 { 12606212Saw148015 $$ = $3; 12616212Saw148015 $$->attr_name = $1; 12626212Saw148015 } 12636212Saw148015 | pt_attr_name 12646212Saw148015 { 12656212Saw148015 if (($$ = alloc_attr()) == NULL) 12666212Saw148015 YYERROR; 12676212Saw148015 $$->attr_name = $1; 12686212Saw148015 }; 12696212Saw148015 12706212Saw148015 /* attribute parsing for flowops */ 12716212Saw148015 fo_attr_ops: fo_attr_op 12726212Saw148015 { 12736212Saw148015 $$ = $1; 12746212Saw148015 } 12756212Saw148015 | fo_attr_ops FSK_SEPLST fo_attr_op 12765184Sek110237 { 12775184Sek110237 attr_t *attr = NULL; 12785184Sek110237 attr_t *list_end = NULL; 12795184Sek110237 12805184Sek110237 for (attr = $1; attr != NULL; 12815184Sek110237 attr = attr->attr_next) 12825184Sek110237 list_end = attr; /* Find end of list */ 12835184Sek110237 12845184Sek110237 list_end->attr_next = $3; 12855184Sek110237 12865184Sek110237 $$ = $1; 12876550Saw148015 } 12886550Saw148015 | fo_attr_ops FSK_SEPLST comp_lvar_def 12896550Saw148015 { 12906550Saw148015 attr_t *attr = NULL; 12916550Saw148015 attr_t *list_end = NULL; 12926550Saw148015 12936550Saw148015 for (attr = $1; attr != NULL; 12946550Saw148015 attr = attr->attr_next) 12956550Saw148015 list_end = attr; /* Find end of list */ 12966550Saw148015 12976550Saw148015 list_end->attr_next = $3; 12986550Saw148015 12996550Saw148015 $$ = $1; 13005184Sek110237 }; 13015184Sek110237 13026212Saw148015 fo_attr_op: fo_attr_name FSK_ASSIGN attr_value 13035184Sek110237 { 13045184Sek110237 $$ = $3; 13055184Sek110237 $$->attr_name = $1; 13065184Sek110237 } 13076212Saw148015 | fo_attr_name 13085184Sek110237 { 13095184Sek110237 if (($$ = alloc_attr()) == NULL) 13105184Sek110237 YYERROR; 13115184Sek110237 $$->attr_name = $1; 13126212Saw148015 }; 13136212Saw148015 13146212Saw148015 /* attribute parsing for Event Generator */ 13156212Saw148015 ev_attr_ops: ev_attr_op 13166212Saw148015 { 13176212Saw148015 $$ = $1; 13185184Sek110237 } 13196212Saw148015 | ev_attr_ops FSK_SEPLST ev_attr_op 13206212Saw148015 { 13216212Saw148015 attr_t *attr = NULL; 13226212Saw148015 attr_t *list_end = NULL; 13236212Saw148015 13246212Saw148015 for (attr = $1; attr != NULL; 13256212Saw148015 attr = attr->attr_next) 13266212Saw148015 list_end = attr; /* Find end of list */ 13276212Saw148015 13286212Saw148015 list_end->attr_next = $3; 13296212Saw148015 13306212Saw148015 $$ = $1; 13316212Saw148015 }; 13326212Saw148015 13336212Saw148015 ev_attr_op: ev_attr_name FSK_ASSIGN attr_value 13346212Saw148015 { 13356212Saw148015 $$ = $3; 13366212Saw148015 $$->attr_name = $1; 13376212Saw148015 } 13386212Saw148015 | ev_attr_name 13396212Saw148015 { 13406212Saw148015 if (($$ = alloc_attr()) == NULL) 13416212Saw148015 YYERROR; 13426212Saw148015 $$->attr_name = $1; 13436212Saw148015 }; 13446212Saw148015 13456212Saw148015 files_attr_name: attrs_define_file 13466212Saw148015 |attrs_define_fileset; 13476212Saw148015 13486212Saw148015 pt_attr_name: attrs_define_thread 13496212Saw148015 |attrs_define_proc; 13506212Saw148015 13516212Saw148015 fo_attr_name: attrs_flowop; 13526212Saw148015 13536212Saw148015 ev_attr_name: attrs_eventgen; 13545184Sek110237 13555184Sek110237 attrs_define_proc: 13566212Saw148015 FSA_NICE { $$ = FSA_NICE;} 13576212Saw148015 | FSA_NAME { $$ = FSA_NAME;} 13586212Saw148015 | FSA_INSTANCES { $$ = FSA_INSTANCES;}; 13595184Sek110237 13605184Sek110237 attrs_define_file: 13616212Saw148015 FSA_SIZE { $$ = FSA_SIZE;} 13626212Saw148015 | FSA_NAME { $$ = FSA_NAME;} 13635184Sek110237 | FSA_PATH { $$ = FSA_PATH;} 13645184Sek110237 | FSA_REUSE { $$ = FSA_REUSE;} 13655184Sek110237 | FSA_PREALLOC { $$ = FSA_PREALLOC;} 13665184Sek110237 | FSA_PARALLOC { $$ = FSA_PARALLOC;}; 13675184Sek110237 13685184Sek110237 attrs_define_fileset: 13696212Saw148015 FSA_SIZE { $$ = FSA_SIZE;} 13706212Saw148015 | FSA_NAME { $$ = FSA_NAME;} 13715184Sek110237 | FSA_PATH { $$ = FSA_PATH;} 13725184Sek110237 | FSA_DIRWIDTH { $$ = FSA_DIRWIDTH;} 13736212Saw148015 | FSA_DIRDEPTHRV { $$ = FSA_DIRDEPTHRV;} 13745184Sek110237 | FSA_PREALLOC { $$ = FSA_PREALLOC;} 13755184Sek110237 | FSA_FILESIZEGAMMA { $$ = FSA_FILESIZEGAMMA;} 13765184Sek110237 | FSA_DIRGAMMA { $$ = FSA_DIRGAMMA;} 13775184Sek110237 | FSA_CACHED { $$ = FSA_CACHED;} 13785184Sek110237 | FSA_ENTRIES { $$ = FSA_ENTRIES;}; 13795184Sek110237 13806212Saw148015 randvar_attr_name: 13816212Saw148015 FSA_NAME { $$ = FSA_NAME;} 13826212Saw148015 | FSA_RANDSEED { $$ = FSA_RANDSEED;} 13836212Saw148015 | FSA_RANDGAMMA { $$ = FSA_RANDGAMMA;} 13846212Saw148015 | FSA_RANDMEAN { $$ = FSA_RANDMEAN;} 13856212Saw148015 | FSA_RANDMIN { $$ = FSA_RANDMIN;} 13866212Saw148015 | FSA_RANDROUND { $$ = FSA_RANDROUND;}; 13876212Saw148015 13886212Saw148015 randvar_attr_tsp: 13896212Saw148015 FSS_TYPE { $$ = FSS_TYPE;} 13906212Saw148015 | FSS_SRC { $$ = FSS_SRC;} 13916212Saw148015 | FSS_SEED { $$ = FSS_SEED;} 13926212Saw148015 | FSS_GAMMA { $$ = FSS_GAMMA;} 13936212Saw148015 | FSS_MEAN { $$ = FSS_MEAN;} 13946212Saw148015 | FSS_MIN { $$ = FSS_MIN;} 13956212Saw148015 | FSS_ROUND { $$ = FSS_ROUND;}; 13966212Saw148015 13976212Saw148015 13986212Saw148015 randvar_attr_param: 13996212Saw148015 FSS_SEED { $$ = FSS_SEED;} 14006212Saw148015 | FSS_GAMMA { $$ = FSS_GAMMA;} 14016212Saw148015 | FSS_MEAN { $$ = FSS_MEAN;} 14026212Saw148015 | FSS_MIN { $$ = FSS_MIN;} 14036212Saw148015 | FSS_ROUND { $$ = FSS_ROUND;}; 14046212Saw148015 14056212Saw148015 randvar_attr_typop: randtype_name 14066212Saw148015 { 14076212Saw148015 if (($$ = alloc_attr()) == NULL) 14086212Saw148015 YYERROR; 14096212Saw148015 $$->attr_avd = avd_int_alloc($1); 14106212Saw148015 }; 14116212Saw148015 14126212Saw148015 randtype_name: 14136212Saw148015 FSV_RANDUNI { $$ = FSV_RANDUNI;} 14146212Saw148015 | FSV_RANDTAB { $$ = FSV_RANDTAB;} 14156212Saw148015 | FSA_RANDGAMMA { $$ = FSA_RANDGAMMA;}; 14166212Saw148015 14176212Saw148015 randvar_attr_srcop: randsrc_name 14186212Saw148015 { 14196212Saw148015 if (($$ = alloc_attr()) == NULL) 14206212Saw148015 YYERROR; 14216212Saw148015 $$->attr_avd = avd_int_alloc($1); 14226212Saw148015 }; 14236212Saw148015 14246212Saw148015 randsrc_name: 14256212Saw148015 FSV_URAND { $$ = FSV_URAND;} 14266212Saw148015 | FSV_RAND48 { $$ = FSV_RAND48;}; 14276212Saw148015 14285184Sek110237 attrs_define_thread: 14296212Saw148015 FSA_PROCESS { $$ = FSA_PROCESS;} 14306212Saw148015 | FSA_NAME { $$ = FSA_NAME;} 14316212Saw148015 | FSA_MEMSIZE { $$ = FSA_MEMSIZE;} 14326212Saw148015 | FSA_USEISM { $$ = FSA_USEISM;} 14336212Saw148015 | FSA_INSTANCES { $$ = FSA_INSTANCES;}; 14345184Sek110237 14355184Sek110237 attrs_flowop: 14366212Saw148015 FSA_WSS { $$ = FSA_WSS;} 14376212Saw148015 | FSA_FILE { $$ = FSA_FILE;} 14386212Saw148015 | FSA_NAME { $$ = FSA_NAME;} 14396212Saw148015 | FSA_RANDOM { $$ = FSA_RANDOM;} 14406212Saw148015 | FSA_FD { $$ = FSA_FD;} 14416212Saw148015 | FSA_SRCFD { $$ = FSA_SRCFD;} 14426212Saw148015 | FSA_ROTATEFD { $$ = FSA_ROTATEFD;} 14436212Saw148015 | FSA_DSYNC { $$ = FSA_DSYNC;} 14446212Saw148015 | FSA_DIRECTIO { $$ = FSA_DIRECTIO;} 14456212Saw148015 | FSA_TARGET { $$ = FSA_TARGET;} 14466212Saw148015 | FSA_ITERS { $$ = FSA_ITERS;} 14476212Saw148015 | FSA_VALUE { $$ = FSA_VALUE;} 14486212Saw148015 | FSA_BLOCKING { $$ = FSA_BLOCKING;} 14496212Saw148015 | FSA_HIGHWATER { $$ = FSA_HIGHWATER;} 14506212Saw148015 | FSA_IOSIZE { $$ = FSA_IOSIZE;}; 14515184Sek110237 14525184Sek110237 attrs_eventgen: 14536212Saw148015 FSA_RATE { $$ = FSA_RATE;}; 14546212Saw148015 14556550Saw148015 comp_attr_ops: comp_attr_op 14566550Saw148015 { 14576550Saw148015 $$ = $1; 14586550Saw148015 } 14596550Saw148015 | comp_attr_ops FSK_SEPLST comp_attr_op 14606550Saw148015 { 14616550Saw148015 attr_t *attr = NULL; 14626550Saw148015 attr_t *list_end = NULL; 14636550Saw148015 14646550Saw148015 for (attr = $1; attr != NULL; 14656550Saw148015 attr = attr->attr_next) 14666550Saw148015 list_end = attr; /* Find end of list */ 14676550Saw148015 14686550Saw148015 list_end->attr_next = $3; 14696550Saw148015 14706550Saw148015 $$ = $1; 14716550Saw148015 } 14726550Saw148015 | comp_attr_ops FSK_SEPLST comp_lvar_def 14736550Saw148015 { 14746550Saw148015 attr_t *attr = NULL; 14756550Saw148015 attr_t *list_end = NULL; 14766550Saw148015 14776550Saw148015 for (attr = $1; attr != NULL; 14786550Saw148015 attr = attr->attr_next) 14796550Saw148015 list_end = attr; /* Find end of list */ 14806550Saw148015 14816550Saw148015 list_end->attr_next = $3; 14826550Saw148015 14836550Saw148015 $$ = $1; 14846550Saw148015 }; 14856550Saw148015 14866550Saw148015 comp_attr_op: attrs_define_comp FSK_ASSIGN attr_value 14876550Saw148015 { 14886550Saw148015 $$ = $3; 14896550Saw148015 $$->attr_name = $1; 14906550Saw148015 }; 14916550Saw148015 14926550Saw148015 comp_lvar_def: FSV_VARIABLE FSK_ASSIGN FSV_VAL_BOOLEAN 14936550Saw148015 { 14946550Saw148015 if (($$ = alloc_lvar_attr(var_lvar_assign_boolean($1, $3))) == NULL) 14956550Saw148015 YYERROR; 14966550Saw148015 } 14976550Saw148015 | FSV_VARIABLE FSK_ASSIGN FSV_VAL_INT 14986550Saw148015 { 14996550Saw148015 if (($$ = alloc_lvar_attr(var_lvar_assign_integer($1, $3))) == NULL) 15006550Saw148015 YYERROR; 15016550Saw148015 } 15026550Saw148015 | FSV_VARIABLE FSK_ASSIGN FSK_QUOTE FSV_WHITESTRING FSK_QUOTE 15036550Saw148015 { 15046550Saw148015 if (($$ = alloc_lvar_attr(var_lvar_assign_string($1, $4))) == NULL) 15056550Saw148015 YYERROR; 15066550Saw148015 } 15076550Saw148015 | FSV_VARIABLE FSK_ASSIGN FSV_STRING 15086550Saw148015 { 15096550Saw148015 if (($$ = alloc_lvar_attr(var_lvar_assign_string($1, $3))) == NULL) 15106550Saw148015 YYERROR; 15116550Saw148015 } 15126550Saw148015 | FSV_VARIABLE FSK_ASSIGN FSV_VARIABLE 15136550Saw148015 { 15146550Saw148015 if (($$ = alloc_lvar_attr(var_lvar_assign_var($1, $3))) == NULL) 15156550Saw148015 YYERROR; 15166550Saw148015 } 15176550Saw148015 | FSV_VARIABLE 15186550Saw148015 { 15196550Saw148015 if (($$ = alloc_lvar_attr(var_lvar_alloc_local($1))) == NULL) 15206550Saw148015 YYERROR; 15216550Saw148015 }; 15226550Saw148015 15236550Saw148015 15246550Saw148015 attrs_define_comp: 15256550Saw148015 FSA_NAME { $$ = FSA_NAME;} 15266550Saw148015 | FSA_ITERS { $$ = FSA_ITERS;}; 15276550Saw148015 15286212Saw148015 attr_value: FSV_STRING 15296212Saw148015 { 15306212Saw148015 if (($$ = alloc_attr()) == NULL) 15316212Saw148015 YYERROR; 15326212Saw148015 $$->attr_avd = avd_str_alloc($1); 15336212Saw148015 } | FSV_VAL_INT { 15346212Saw148015 if (($$ = alloc_attr()) == NULL) 15356212Saw148015 YYERROR; 15366212Saw148015 $$->attr_avd = avd_int_alloc($1); 15376212Saw148015 } | FSV_VAL_BOOLEAN { 15386212Saw148015 if (($$ = alloc_attr()) == NULL) 15396212Saw148015 YYERROR; 15406212Saw148015 $$->attr_avd = avd_bool_alloc($1); 15416212Saw148015 } | FSV_VARIABLE { 15426212Saw148015 if (($$ = alloc_attr()) == NULL) 15436212Saw148015 YYERROR; 15446212Saw148015 $$->attr_avd = var_ref_attr($1); 15456212Saw148015 }; 15466212Saw148015 15476212Saw148015 attr_list_value: var_string_list { 15485184Sek110237 if (($$ = alloc_attr()) == NULL) 15495184Sek110237 YYERROR; 15505184Sek110237 $$->attr_param_list = $1; 15515184Sek110237 } | FSV_STRING 15525184Sek110237 { 15535184Sek110237 if (($$ = alloc_attr()) == NULL) 15545184Sek110237 YYERROR; 15556212Saw148015 $$->attr_avd = avd_str_alloc($1); 15565184Sek110237 } | FSV_VAL_INT { 15575184Sek110237 if (($$ = alloc_attr()) == NULL) 15585184Sek110237 YYERROR; 15596212Saw148015 $$->attr_avd = avd_int_alloc($1); 15606212Saw148015 } | FSV_VAL_BOOLEAN { 15616212Saw148015 if (($$ = alloc_attr()) == NULL) 15626212Saw148015 YYERROR; 15636212Saw148015 $$->attr_avd = avd_bool_alloc($1); 15645184Sek110237 } | FSV_VARIABLE { 15655184Sek110237 if (($$ = alloc_attr()) == NULL) 15665184Sek110237 YYERROR; 15676212Saw148015 $$->attr_avd = var_ref_attr($1); 15686212Saw148015 }; 15696212Saw148015 15706212Saw148015 var_int_val: FSV_VAL_INT 15716212Saw148015 { 15726212Saw148015 $$ = avd_int_alloc($1); 15736212Saw148015 } | FSV_VARIABLE 15746212Saw148015 { 15756212Saw148015 $$ = var_ref_attr($1); 15765184Sek110237 }; 15775184Sek110237 15785184Sek110237 %% 15795184Sek110237 15805184Sek110237 /* 15815184Sek110237 * The following 'c' routines implement the various commands defined in the 15825184Sek110237 * above yacc parser code. The yacc portion checks the syntax of the commands 15835184Sek110237 * found in a workload file, or typed on interactive command lines, parsing 15845184Sek110237 * the commands' parameters into lists. The lists are then passed in a cmd_t 15855184Sek110237 * struct for each command to its related routine in the following section 15865184Sek110237 * for actual execution. This section also includes a few utility routines 15875184Sek110237 * and the main entry point for the program. 15885184Sek110237 */ 15895184Sek110237 15905184Sek110237 /* 15915184Sek110237 * Entry point for filebench. Processes command line arguements. The -f 15925184Sek110237 * option will read in a workload file (the full name and extension must 15935184Sek110237 * must be given). The -a, -s, -m and -i options are used by worker process 15945184Sek110237 * to receive their name, the base address of shared memory, its path, and 15955184Sek110237 * the process' instance number, respectively. This information is supplied 15965184Sek110237 * by the master process when it execs worker processes under the process 15975184Sek110237 * model of execution. If the worker process arguments are passed then main 15985184Sek110237 * will call the procflow_exec routine which creates worker threadflows and 15995184Sek110237 * flowops and executes the procflow's portion of the workload model until 16005184Sek110237 * completion. If worker process arguments are not passed to the process, 16015184Sek110237 * then it becomes the master process for a filebench run. It initializes 16025184Sek110237 * the various filebench components and either executes the supplied workload 16035184Sek110237 * file, or enters interactive mode. 16045184Sek110237 */ 16055184Sek110237 16065184Sek110237 int 16075184Sek110237 main(int argc, char *argv[]) 16085184Sek110237 { 16095184Sek110237 int opt; 16105184Sek110237 int docmd = FS_FALSE; 16115184Sek110237 int instance; 16125184Sek110237 char procname[128]; 16135184Sek110237 caddr_t shmaddr; 16145184Sek110237 char dir[MAXPATHLEN]; 16155184Sek110237 #ifdef HAVE_SETRLIMIT 16165184Sek110237 struct rlimit rlp; 16175184Sek110237 #endif 16185184Sek110237 #ifdef HAVE_LIBTECLA 16195184Sek110237 char *line; 16205184Sek110237 #else 16215184Sek110237 char line[1024]; 16225184Sek110237 #endif 16235184Sek110237 char shmpathtmp[1024]; 16245184Sek110237 16255184Sek110237 #ifdef HAVE_SETRLIMIT 16265184Sek110237 /* Set resource limits */ 16275184Sek110237 (void) getrlimit(RLIMIT_NOFILE, &rlp); 16285184Sek110237 rlp.rlim_cur = rlp.rlim_max; 16295184Sek110237 setrlimit(RLIMIT_NOFILE, &rlp); 16305184Sek110237 #endif 16315184Sek110237 16325184Sek110237 yydebug = 0; 16335184Sek110237 execname = argv[0]; 16345184Sek110237 *procname = 0; 16355184Sek110237 cwd = getcwd(dir, MAXPATHLEN); 16365184Sek110237 16375184Sek110237 while ((opt = getopt(argc, argv, cmd_options)) != (int)EOF) { 16385184Sek110237 16395184Sek110237 switch (opt) { 16405184Sek110237 case 'h': 16415184Sek110237 usage(2); 16425184Sek110237 break; 16435184Sek110237 16445184Sek110237 case 'p': 16455184Sek110237 noproc = 1; 16465184Sek110237 break; 16475184Sek110237 16485184Sek110237 case 'f': 16495184Sek110237 if (optarg == NULL) 16505184Sek110237 usage(1); 16515184Sek110237 if ((yyin = fopen(optarg, "r")) == NULL) { 16525184Sek110237 (void) fprintf(stderr, 16535184Sek110237 "Cannot open file %s", optarg); 16545184Sek110237 exit(1); 16555184Sek110237 } 16565184Sek110237 dofile = FS_TRUE; 16575184Sek110237 fscriptname = optarg; 16585184Sek110237 16595184Sek110237 break; 16605184Sek110237 16615184Sek110237 case 'a': 16625184Sek110237 if (optarg == NULL) 16635184Sek110237 usage(1); 16645184Sek110237 sscanf(optarg, "%s", &procname[0]); 16655184Sek110237 break; 16665184Sek110237 16675184Sek110237 case 's': 16685184Sek110237 if (optarg == NULL) 16695184Sek110237 usage(1); 16705184Sek110237 #if defined(_LP64) || (__WORDSIZE == 64) 16715184Sek110237 sscanf(optarg, "%llx", &shmaddr); 16725184Sek110237 #else 16735184Sek110237 sscanf(optarg, "%x", &shmaddr); 16745184Sek110237 #endif 16755184Sek110237 break; 16765184Sek110237 16775184Sek110237 case 'm': 16785184Sek110237 if (optarg == NULL) 16795184Sek110237 usage(1); 16805184Sek110237 sscanf(optarg, "%s", shmpathtmp); 16815184Sek110237 shmpath = shmpathtmp; 16825184Sek110237 break; 16835184Sek110237 16845184Sek110237 case 'i': 16855184Sek110237 if (optarg == NULL) 16865184Sek110237 usage(1); 16875184Sek110237 sscanf(optarg, "%d", &instance); 16885184Sek110237 break; 16895184Sek110237 16905184Sek110237 case '?': 16915184Sek110237 default: 16925184Sek110237 usage(1); 16935184Sek110237 break; 16945184Sek110237 } 16955184Sek110237 } 16965184Sek110237 16975184Sek110237 #ifdef USE_PROCESS_MODEL 16985184Sek110237 if (!(*procname)) 16995184Sek110237 #endif 17005184Sek110237 printf("FileBench Version %s\n", FILEBENCH_VERSION); 17015184Sek110237 filebench_init(); 17025184Sek110237 17036084Saw148015 /* get process pid for use with message logging */ 17046084Saw148015 my_pid = getpid(); 17056084Saw148015 17065184Sek110237 #ifdef USE_PROCESS_MODEL 17075184Sek110237 if (*procname) { 17086084Saw148015 /* A child FileBench instance */ 17095184Sek110237 if (ipc_attach(shmaddr) < 0) { 17105184Sek110237 filebench_log(LOG_ERROR, "Cannot attach shm for %s", 17115184Sek110237 procname); 17125184Sek110237 exit(1); 17135184Sek110237 } 17145184Sek110237 17156212Saw148015 if (procflow_exec(procname, instance) < 0) { 17166212Saw148015 filebench_log(LOG_ERROR, "Cannot startup process %s", 17176212Saw148015 procname); 17185184Sek110237 exit(1); 17196212Saw148015 } 17206084Saw148015 17216084Saw148015 exit(0); 17225184Sek110237 } 17235184Sek110237 #endif 17245184Sek110237 17256084Saw148015 /* master (or only) process */ 17265184Sek110237 ipc_init(); 17275184Sek110237 17285184Sek110237 if (fscriptname) 17296391Saw148015 (void) strcpy(filebench_shm->shm_fscriptname, fscriptname); 17305184Sek110237 17315184Sek110237 flowop_init(); 17325184Sek110237 stats_init(); 17335184Sek110237 eventgen_init(); 17345184Sek110237 17355184Sek110237 signal(SIGINT, parser_abort); 17365184Sek110237 17375184Sek110237 if (dofile) 17385184Sek110237 yyparse(); 17395184Sek110237 else { 17405184Sek110237 #ifdef HAVE_LIBTECLA 17415184Sek110237 if ((gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL) { 17425184Sek110237 filebench_log(LOG_ERROR, 17435184Sek110237 "Failed to create GetLine object"); 17445184Sek110237 filebench_shutdown(1); 17455184Sek110237 } 17465184Sek110237 17475184Sek110237 if (gl_customize_completion(gl, NULL, command_complete)) { 17485184Sek110237 filebench_log(LOG_ERROR, 17495184Sek110237 "Failed to register auto-completion function"); 17505184Sek110237 filebench_shutdown(1); 17515184Sek110237 } 17525184Sek110237 17535184Sek110237 while (line = gl_get_line(gl, FILEBENCH_PROMPT, NULL, -1)) { 17545184Sek110237 arg_parse(line); 17555184Sek110237 yyparse(); 17565184Sek110237 } 17575184Sek110237 17585184Sek110237 del_GetLine(gl); 17595184Sek110237 #else 17605184Sek110237 while (!feof(stdin)) { 17615184Sek110237 printf(FILEBENCH_PROMPT); 17625184Sek110237 fflush(stdout); 17635184Sek110237 if (fgets(line, sizeof (line), stdin) == NULL) { 17645184Sek110237 if (errno == EINTR) 17655184Sek110237 continue; 17665184Sek110237 else 17675184Sek110237 break; 17685184Sek110237 } 17695184Sek110237 arg_parse(line); 17705184Sek110237 yyparse(); 17715184Sek110237 } 17725184Sek110237 printf("\n"); 17735184Sek110237 #endif /* HAVE_LIBTECLA */ 17745184Sek110237 } 17755184Sek110237 17765184Sek110237 parser_filebench_shutdown((cmd_t *)0); 17775184Sek110237 17785184Sek110237 return (0); 17795184Sek110237 } 17805184Sek110237 17815184Sek110237 /* 17825184Sek110237 * arg_parse() puts the parser into command parsing mode. Create a tmpfile 17835184Sek110237 * and instruct the parser to read instructions from this location by setting 17845184Sek110237 * yyin to the value returned by tmpfile. Write the command into the file. 17855184Sek110237 * Then seek back to to the start of the file so that the parser can read 17865184Sek110237 * the instructions. 17875184Sek110237 */ 17885184Sek110237 static void 17895184Sek110237 arg_parse(const char *command) 17905184Sek110237 { 1791*6750Sek110237 if ((yyin = tmpfile()) == NULL) { 17925184Sek110237 filebench_log(LOG_FATAL, 1793*6750Sek110237 "Exiting: Cannot create tmpfile: %s", strerror(errno)); 1794*6750Sek110237 exit(1); 1795*6750Sek110237 } 17965184Sek110237 17975184Sek110237 if (fwrite(command, strlen(command), 1, yyin) != 1) 17985184Sek110237 filebench_log(LOG_FATAL, 17995184Sek110237 "Cannot write tmpfile: %s", strerror(errno)); 18005184Sek110237 18015184Sek110237 if (fseek(yyin, 0, SEEK_SET) != 0) 18025184Sek110237 filebench_log(LOG_FATAL, 18035184Sek110237 "Cannot seek tmpfile: %s", strerror(errno)); 18045184Sek110237 } 18055184Sek110237 18065184Sek110237 /* 18075184Sek110237 * Converts a list of var_strings or ordinary strings to a single ordinary 18085184Sek110237 * string. It returns a pointer to the string (in malloc'd memory) if found, 18095184Sek110237 * or NULL otherwise. 18105184Sek110237 */ 18115184Sek110237 char * 18125184Sek110237 parser_list2string(list_t *list) 18135184Sek110237 { 18145184Sek110237 list_t *l; 18155184Sek110237 char *string; 18165184Sek110237 char *tmp; 18176212Saw148015 fbint_t *integer; 18185184Sek110237 if ((string = malloc(MAXPATHLEN)) == NULL) { 18195184Sek110237 filebench_log(LOG_ERROR, "Failed to allocate memory"); 18205184Sek110237 return (NULL); 18215184Sek110237 } 18225184Sek110237 18235184Sek110237 *string = 0; 18245184Sek110237 18255184Sek110237 18265184Sek110237 /* Format args */ 18276212Saw148015 for (l = list; l != NULL; l = l->list_next) { 18286212Saw148015 char *lstr = avd_get_str(l->list_string); 18296212Saw148015 18305184Sek110237 filebench_log(LOG_DEBUG_SCRIPT, 18316212Saw148015 "converting string '%s'", lstr); 18326212Saw148015 18336212Saw148015 /* see if it is a random variable */ 18346212Saw148015 if (l->list_integer) { 18356212Saw148015 fbint_t param_name; 18366212Saw148015 18376212Saw148015 tmp = NULL; 18386212Saw148015 param_name = avd_get_int(l->list_integer); 18396212Saw148015 switch (param_name) { 18406212Saw148015 case FSS_TYPE: 18416212Saw148015 tmp = var_randvar_to_string(lstr, 18426212Saw148015 RAND_PARAM_TYPE); 18436212Saw148015 break; 18446212Saw148015 18456212Saw148015 case FSS_SRC: 18466212Saw148015 tmp = var_randvar_to_string(lstr, 18476212Saw148015 RAND_PARAM_SRC); 18486212Saw148015 break; 18496212Saw148015 18506212Saw148015 case FSS_SEED: 18516212Saw148015 tmp = var_randvar_to_string(lstr, 18526212Saw148015 RAND_PARAM_SEED); 18536212Saw148015 break; 18546212Saw148015 18556212Saw148015 case FSS_MIN: 18566212Saw148015 tmp = var_randvar_to_string(lstr, 18576212Saw148015 RAND_PARAM_MIN); 18586212Saw148015 break; 18596212Saw148015 18606212Saw148015 case FSS_MEAN: 18616212Saw148015 tmp = var_randvar_to_string(lstr, 18626212Saw148015 RAND_PARAM_MEAN); 18636212Saw148015 break; 18646212Saw148015 18656212Saw148015 case FSS_GAMMA: 18666212Saw148015 tmp = var_randvar_to_string(lstr, 18676212Saw148015 RAND_PARAM_GAMMA); 18686212Saw148015 break; 18696212Saw148015 18706212Saw148015 case FSS_ROUND: 18716212Saw148015 tmp = var_randvar_to_string(lstr, 18726212Saw148015 RAND_PARAM_ROUND); 18736212Saw148015 break; 18746212Saw148015 } 18756212Saw148015 18766212Saw148015 if (tmp) { 18776212Saw148015 (void) strcat(string, tmp); 18786212Saw148015 free(tmp); 18796212Saw148015 } else { 18806212Saw148015 (void) strcat(string, lstr); 18816212Saw148015 } 18825184Sek110237 } else { 18836212Saw148015 /* perhaps a normal variable? */ 18846212Saw148015 if ((tmp = var_to_string(lstr)) != NULL) { 18856212Saw148015 (void) strcat(string, tmp); 18866212Saw148015 free(tmp); 18876212Saw148015 } else { 18886212Saw148015 (void) strcat(string, lstr); 18896212Saw148015 } 18905184Sek110237 } 18915184Sek110237 } 18925184Sek110237 return (string); 18935184Sek110237 } 18945184Sek110237 18955184Sek110237 /* 18965184Sek110237 * If the list just contains a single string starting with '$', then find 18975184Sek110237 * or create the named var and return the var's var_string component. 18985184Sek110237 * Otherwise, convert the list to a string, and allocate a var_string 18995184Sek110237 * containing a copy of that string. On failure either returns NULL 19005184Sek110237 * or shuts down the run. 19015184Sek110237 */ 19026212Saw148015 avd_t 19035184Sek110237 parser_list2varstring(list_t *list) 19045184Sek110237 { 19056212Saw148015 char *lstr = avd_get_str(list->list_string); 19066212Saw148015 19075184Sek110237 /* Special case - variable name */ 19086212Saw148015 if ((list->list_next == NULL) && (*lstr == '$')) 19096212Saw148015 return (var_ref_attr(lstr)); 19106212Saw148015 19116212Saw148015 return (avd_str_alloc(parser_list2string(list))); 19125184Sek110237 } 19135184Sek110237 19145184Sek110237 /* 19155184Sek110237 * Looks for the var named in list_string of the first element of the 19166212Saw148015 * supplied list. If found, returns the var_val portion of the var in 19176212Saw148015 * an attribute value descriptor. If the var is not found, cannot be 19186212Saw148015 * allocated, the supplied list is NULL, or the list_string filed is 19196212Saw148015 * empty, returns NULL. 19205184Sek110237 */ 19216212Saw148015 avd_t 19226212Saw148015 parser_list2avd(list_t *list) 19235184Sek110237 { 19246212Saw148015 avd_t avd; 19256212Saw148015 char *lstr; 19266212Saw148015 19276212Saw148015 if (list && ((lstr = avd_get_str(list->list_string)) != NULL)) { 19286212Saw148015 avd = var_ref_attr(lstr); 19296212Saw148015 return (avd); 19305184Sek110237 } 19315184Sek110237 19325184Sek110237 return (NULL); 19335184Sek110237 } 19345184Sek110237 19355184Sek110237 /* 19365184Sek110237 * Sets the event generator rate from the attribute supplied with the 19375184Sek110237 * command. If the attribute doesn't exist the routine does nothing. 19385184Sek110237 */ 19395184Sek110237 static void 19405184Sek110237 parser_eventgen(cmd_t *cmd) 19415184Sek110237 { 19425184Sek110237 attr_t *attr; 19436212Saw148015 fbint_t rate; 19445184Sek110237 19455184Sek110237 /* Get the rate from attribute */ 19465184Sek110237 if (attr = get_attr_integer(cmd, FSA_RATE)) { 19476212Saw148015 if (attr->attr_avd) { 19486212Saw148015 rate = avd_get_int(attr->attr_avd); 19495184Sek110237 filebench_log(LOG_VERBOSE, 19506286Saw148015 "Eventgen: %llu per second", 19516286Saw148015 (u_longlong_t)rate); 19526212Saw148015 eventgen_setrate(rate); 19535184Sek110237 } 19545184Sek110237 } 19555184Sek110237 } 19565184Sek110237 19575184Sek110237 /* 19585184Sek110237 * Assigns the designated integer variable successive values from the 19595184Sek110237 * supplied comma seperated integer list. After each successive integer 19605184Sek110237 * assignment, it executes the bracket enclosed list of commands. For 19615184Sek110237 * example, repeated runs of a workload with increasing io sizes can 19625184Sek110237 * be done using the following command line: 19635184Sek110237 * foreach $iosize in 2k, 4k, 8k {run 60} 19645184Sek110237 */ 19655184Sek110237 static void 19665184Sek110237 parser_foreach_integer(cmd_t *cmd) 19675184Sek110237 { 19685184Sek110237 list_t *list = cmd->cmd_param_list; 19695184Sek110237 cmd_t *inner_cmd; 19705184Sek110237 19715184Sek110237 for (; list != NULL; list = list->list_next) { 19726212Saw148015 fbint_t list_int = avd_get_int(list->list_integer); 19736212Saw148015 19746212Saw148015 var_assign_integer(cmd->cmd_tgt1, list_int); 19756286Saw148015 filebench_log(LOG_VERBOSE, "Iterating %s=%llu", 19766286Saw148015 cmd->cmd_tgt1, (u_longlong_t)list_int); 19775184Sek110237 for (inner_cmd = cmd->cmd_list; inner_cmd != NULL; 19785184Sek110237 inner_cmd = inner_cmd->cmd_next) { 19795184Sek110237 inner_cmd->cmd(inner_cmd); 19805184Sek110237 } 19815184Sek110237 } 19825184Sek110237 } 19835184Sek110237 19845184Sek110237 /* 19855184Sek110237 * Similar to parser_foreach_integer(), except takes a list of strings after 19865184Sek110237 * the "in" token. For example, to run twice using a different directory, 19875184Sek110237 * perhaps using a different filesystem, the following command line 19885184Sek110237 * could be used: 19895184Sek110237 * foreach $dir in "/ufs_top/fbt", "/zfs_top/fbt" {run 60) 19905184Sek110237 */ 19915184Sek110237 static void 19925184Sek110237 parser_foreach_string(cmd_t *cmd) 19935184Sek110237 { 19945184Sek110237 list_t *list = cmd->cmd_param_list; 19955184Sek110237 19965184Sek110237 for (; list != NULL; list = list->list_next) { 19976212Saw148015 cmd_t *inner_cmd; 19986212Saw148015 char *lstr = avd_get_str(list->list_string); 19996212Saw148015 var_assign_string(cmd->cmd_tgt1, lstr); 20005184Sek110237 filebench_log(LOG_VERBOSE, "Iterating %s=%s", 20016212Saw148015 cmd->cmd_tgt1, lstr); 20025184Sek110237 for (inner_cmd = cmd->cmd_list; inner_cmd != NULL; 20035184Sek110237 inner_cmd = inner_cmd->cmd_next) { 20045184Sek110237 inner_cmd->cmd(inner_cmd); 20055184Sek110237 } 20065184Sek110237 } 20075184Sek110237 } 20085184Sek110237 20095184Sek110237 /* 20105673Saw148015 * Lists the fileset name, path name and average size for all defined 20115673Saw148015 * filesets. 20125184Sek110237 */ 20135184Sek110237 static void 20145184Sek110237 parser_list(cmd_t *cmd) 20155184Sek110237 { 20165673Saw148015 (void) fileset_iter(fileset_print); 20175184Sek110237 } 20185184Sek110237 20195184Sek110237 /* 20206212Saw148015 * Lists the flowop name and instance number for all flowops. 20216212Saw148015 */ 20226212Saw148015 static void 20236212Saw148015 parser_flowop_list(cmd_t *cmd) 20246212Saw148015 { 20256212Saw148015 flowop_printall(); 20266212Saw148015 } 20276212Saw148015 20286212Saw148015 /* 20295184Sek110237 * Calls procflow_define() to allocate "instances" number of procflow(s) 20305184Sek110237 * (processes) with the supplied name. The default number of instances is 20315184Sek110237 * one. An optional priority level attribute can be supplied and is stored in 20325184Sek110237 * pf_nice. Finally the routine loops through the list of inner commands, if 20335184Sek110237 * any, which are defines for threadflows, and passes them one at a time to 20345184Sek110237 * parser_thread_define() to allocate threadflow entities for the process(es). 20355184Sek110237 */ 20365184Sek110237 static void 20375184Sek110237 parser_proc_define(cmd_t *cmd) 20385184Sek110237 { 20395184Sek110237 procflow_t *procflow, template; 20405184Sek110237 char *name; 20415184Sek110237 attr_t *attr; 20426212Saw148015 avd_t var_instances; 20436212Saw148015 fbint_t instances; 20445184Sek110237 cmd_t *inner_cmd; 20455184Sek110237 20465184Sek110237 /* Get the name of the process */ 20475184Sek110237 if (attr = get_attr(cmd, FSA_NAME)) { 20486212Saw148015 name = avd_get_str(attr->attr_avd); 20495184Sek110237 } else { 20505184Sek110237 filebench_log(LOG_ERROR, 20515184Sek110237 "define proc: proc specifies no name"); 20525184Sek110237 filebench_shutdown(1); 20535184Sek110237 } 20545184Sek110237 20555184Sek110237 /* Get the memory size from attribute */ 20565184Sek110237 if (attr = get_attr_integer(cmd, FSA_INSTANCES)) { 20576212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 20586212Saw148015 filebench_log(LOG_ERROR, 20596212Saw148015 "proc_define: Instances attr cannot be random"); 20606212Saw148015 filebench_shutdown(1); 20616212Saw148015 } 20626212Saw148015 var_instances = attr->attr_avd; 20636212Saw148015 instances = avd_get_int(var_instances); 20645184Sek110237 filebench_log(LOG_DEBUG_IMPL, 20656286Saw148015 "Setting instances = %llu", (u_longlong_t)instances); 20666212Saw148015 } else { 20676212Saw148015 filebench_log(LOG_DEBUG_IMPL, 20686212Saw148015 "Defaulting to instances = 1"); 20696212Saw148015 var_instances = avd_int_alloc(1); 20706212Saw148015 instances = 1; 20715184Sek110237 } 20725184Sek110237 20736212Saw148015 if ((procflow = procflow_define(name, NULL, var_instances)) == NULL) { 20745184Sek110237 filebench_log(LOG_ERROR, 20755184Sek110237 "Failed to instantiate %d %s process(es)\n", 20765184Sek110237 instances, name); 20775184Sek110237 filebench_shutdown(1); 20785184Sek110237 } 20795184Sek110237 20805184Sek110237 /* Get the pri from attribute */ 20815184Sek110237 if (attr = get_attr_integer(cmd, FSA_NICE)) { 20826212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 20836212Saw148015 filebench_log(LOG_ERROR, 20846212Saw148015 "proc_define: priority cannot be random"); 20856212Saw148015 filebench_shutdown(1); 20866212Saw148015 } 20876286Saw148015 filebench_log(LOG_DEBUG_IMPL, "Setting pri = %llu", 20886286Saw148015 (u_longlong_t)avd_get_int(attr->attr_avd)); 20896212Saw148015 procflow->pf_nice = attr->attr_avd; 20905184Sek110237 } else 20916212Saw148015 procflow->pf_nice = avd_int_alloc(0); 20925184Sek110237 20935184Sek110237 20945184Sek110237 /* Create the list of threads for this process */ 20955184Sek110237 for (inner_cmd = cmd->cmd_list; inner_cmd != NULL; 20965184Sek110237 inner_cmd = inner_cmd->cmd_next) { 20976212Saw148015 parser_thread_define(inner_cmd, procflow, instances); 20985184Sek110237 } 20995184Sek110237 } 21005184Sek110237 21015184Sek110237 /* 21025184Sek110237 * Calls threadflow_define() to allocate "instances" number of threadflow(s) 21035184Sek110237 * (threads) with the supplied name. The default number of instances is 21045184Sek110237 * one. Two other optional attributes may be supplied, one to set the memory 21055184Sek110237 * size, stored in tf_memsize, and to select the use of Interprocess Shared 21065184Sek110237 * Memory, which sets the THREADFLOW_USEISM flag in tf_attrs. Finally 21075184Sek110237 * the routine loops through the list of inner commands, if any, which are 21085184Sek110237 * defines for flowops, and passes them one at a time to 21095184Sek110237 * parser_flowop_define() to allocate flowop entities for the threadflows. 21105184Sek110237 */ 21115184Sek110237 static void 21125184Sek110237 parser_thread_define(cmd_t *cmd, procflow_t *procflow, int procinstances) 21135184Sek110237 { 21145184Sek110237 threadflow_t *threadflow, template; 21155184Sek110237 attr_t *attr; 21166212Saw148015 avd_t instances; 21175184Sek110237 cmd_t *inner_cmd; 21185184Sek110237 char *name; 21195184Sek110237 21205184Sek110237 memset(&template, 0, sizeof (threadflow_t)); 21215184Sek110237 21225184Sek110237 /* Get the name of the thread */ 21235184Sek110237 if (attr = get_attr(cmd, FSA_NAME)) { 21246212Saw148015 name = avd_get_str(attr->attr_avd); 21255184Sek110237 } else { 21265184Sek110237 filebench_log(LOG_ERROR, 21275184Sek110237 "define thread: thread in process %s specifies no name", 21285184Sek110237 procflow->pf_name); 21295184Sek110237 filebench_shutdown(1); 21305184Sek110237 } 21315184Sek110237 21325184Sek110237 /* Get the number of instances from attribute */ 21335184Sek110237 if (attr = get_attr_integer(cmd, FSA_INSTANCES)) { 21346212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 21356212Saw148015 filebench_log(LOG_ERROR, 21366212Saw148015 "define thread: Instances attr cannot be random"); 21376212Saw148015 filebench_shutdown(1); 21386212Saw148015 } 21395184Sek110237 filebench_log(LOG_DEBUG_IMPL, 21406286Saw148015 "define thread: Setting instances = %llu", 21416286Saw148015 (u_longlong_t)avd_get_int(attr->attr_avd)); 21426212Saw148015 instances = attr->attr_avd; 21436212Saw148015 } else 21446212Saw148015 instances = avd_int_alloc(1); 21455184Sek110237 21465184Sek110237 /* Get the memory size from attribute */ 21475184Sek110237 if (attr = get_attr_integer(cmd, FSA_MEMSIZE)) { 21486212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 21496212Saw148015 filebench_log(LOG_ERROR, 21506212Saw148015 "define thread: Memory size cannot be random"); 21516212Saw148015 filebench_shutdown(1); 21526212Saw148015 } 21535184Sek110237 filebench_log(LOG_DEBUG_IMPL, 21546286Saw148015 "define thread: Setting memsize = %llu", 21556286Saw148015 (u_longlong_t)avd_get_int(attr->attr_avd)); 21566212Saw148015 template.tf_memsize = attr->attr_avd; 21575184Sek110237 } else 21586212Saw148015 template.tf_memsize = avd_int_alloc(0); 21595184Sek110237 21605184Sek110237 if ((threadflow = threadflow_define(procflow, name, 21615184Sek110237 &template, instances)) == NULL) { 21625184Sek110237 filebench_log(LOG_ERROR, 21635184Sek110237 "define thread: Failed to instantiate thread\n"); 21645184Sek110237 filebench_shutdown(1); 21655184Sek110237 } 21665184Sek110237 21675184Sek110237 /* Use ISM Memory? */ 21685184Sek110237 if (attr = get_attr(cmd, FSA_USEISM)) { 21695184Sek110237 threadflow->tf_attrs |= THREADFLOW_USEISM; 21705184Sek110237 } 21715184Sek110237 21725184Sek110237 /* Create the list of flowops */ 21735184Sek110237 for (inner_cmd = cmd->cmd_list; inner_cmd != NULL; 21745184Sek110237 inner_cmd = inner_cmd->cmd_next) { 21756212Saw148015 parser_flowop_define(inner_cmd, threadflow, 21766550Saw148015 &threadflow->tf_thrd_fops, FLOW_MASTER); 21775184Sek110237 } 21785184Sek110237 } 21795184Sek110237 21805184Sek110237 /* 21816212Saw148015 * Files in the attributes for a newly allocated flowop 21826212Saw148015 */ 21836212Saw148015 static void 21846212Saw148015 parser_flowop_get_attrs(cmd_t *cmd, flowop_t *flowop) 21856212Saw148015 { 21866212Saw148015 attr_t *attr; 21876212Saw148015 21886212Saw148015 /* Get the filename from attribute */ 21896212Saw148015 if (attr = get_attr(cmd, FSA_FILE)) { 21906212Saw148015 flowop->fo_filename = attr->attr_avd; 21916212Saw148015 if (flowop->fo_filename == NULL) { 21926212Saw148015 filebench_log(LOG_ERROR, 21936212Saw148015 "define flowop: no filename specfied"); 21946212Saw148015 filebench_shutdown(1); 21956212Saw148015 } 21966212Saw148015 } 21976212Saw148015 21986212Saw148015 /* Get the iosize of the op */ 21996212Saw148015 if (attr = get_attr_integer(cmd, FSA_IOSIZE)) 22006212Saw148015 flowop->fo_iosize = attr->attr_avd; 22016212Saw148015 else 22026212Saw148015 flowop->fo_iosize = avd_int_alloc(0); 22036212Saw148015 22046212Saw148015 /* Get the working set size of the op */ 22056212Saw148015 if (attr = get_attr_integer(cmd, FSA_WSS)) 22066212Saw148015 flowop->fo_wss = attr->attr_avd; 22076212Saw148015 else 22086212Saw148015 flowop->fo_wss = avd_int_alloc(0); 22096212Saw148015 22106212Saw148015 /* Random I/O? */ 22116212Saw148015 if (attr = get_attr_bool(cmd, FSA_RANDOM)) 22126212Saw148015 flowop->fo_random = attr->attr_avd; 22136212Saw148015 else 22146212Saw148015 flowop->fo_random = avd_bool_alloc(FALSE); 22156212Saw148015 22166212Saw148015 /* Sync I/O? */ 22176212Saw148015 if (attr = get_attr_bool(cmd, FSA_DSYNC)) 22186212Saw148015 flowop->fo_dsync = attr->attr_avd; 22196212Saw148015 else 22206212Saw148015 flowop->fo_dsync = avd_bool_alloc(FALSE); 22216212Saw148015 22226212Saw148015 /* Target, for wakeup etc */ 22236212Saw148015 if (attr = get_attr(cmd, FSA_TARGET)) 22246212Saw148015 (void) strcpy(flowop->fo_targetname, 22256212Saw148015 avd_get_str(attr->attr_avd)); 22266212Saw148015 22276212Saw148015 /* Value */ 22286212Saw148015 if (attr = get_attr_integer(cmd, FSA_VALUE)) 22296212Saw148015 flowop->fo_value = attr->attr_avd; 22306212Saw148015 else 22316212Saw148015 flowop->fo_value = avd_int_alloc(0); 22326212Saw148015 22336212Saw148015 /* FD */ 22346212Saw148015 if (attr = get_attr_integer(cmd, FSA_FD)) 22356212Saw148015 flowop->fo_fdnumber = avd_get_int(attr->attr_avd); 22366212Saw148015 22376212Saw148015 /* Rotatefd? */ 22386212Saw148015 if (attr = get_attr_bool(cmd, FSA_ROTATEFD)) 22396212Saw148015 flowop->fo_rotatefd = attr->attr_avd; 22406212Saw148015 else 22416212Saw148015 flowop->fo_rotatefd = avd_bool_alloc(FALSE); 22426212Saw148015 22436212Saw148015 /* SRC FD, for copies etc... */ 22446212Saw148015 if (attr = get_attr_integer(cmd, FSA_SRCFD)) 22456212Saw148015 flowop->fo_srcfdnumber = avd_get_int(attr->attr_avd); 22466212Saw148015 22476212Saw148015 /* Blocking operation? */ 22486212Saw148015 if (attr = get_attr_bool(cmd, FSA_BLOCKING)) 22496212Saw148015 flowop->fo_blocking = attr->attr_avd; 22506212Saw148015 else 22516212Saw148015 flowop->fo_blocking = avd_bool_alloc(FALSE); 22526212Saw148015 22536212Saw148015 /* Direct I/O Operation */ 22546212Saw148015 if (attr = get_attr_bool(cmd, FSA_DIRECTIO)) 22556212Saw148015 flowop->fo_directio = attr->attr_avd; 22566212Saw148015 else 22576212Saw148015 flowop->fo_directio = avd_bool_alloc(FALSE); 22586212Saw148015 22596212Saw148015 /* Highwater mark */ 22606212Saw148015 if (attr = get_attr_integer(cmd, FSA_HIGHWATER)) { 22616212Saw148015 flowop->fo_highwater = attr->attr_avd; 22626212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 22636212Saw148015 filebench_log(LOG_ERROR, 22646212Saw148015 "define flowop: Highwater attr cannot be random"); 22656212Saw148015 filebench_shutdown(1); 22666212Saw148015 } 22676212Saw148015 } else { 22686212Saw148015 flowop->fo_highwater = avd_int_alloc(1); 22696212Saw148015 } 22706212Saw148015 } 22716212Saw148015 22726550Saw148015 /* 22736550Saw148015 * defines the FLOW_MASTER flowops within a FLOW_MASTER instance of 22746550Saw148015 * a composit flowop. Default attributes from the FLOW_INNER_DEF instances 22756550Saw148015 * of the composit flowop's inner flowops are used if set. Otherwise 22766550Saw148015 * default attributes from the FLOW_MASTER instance of the composit flowop 22776550Saw148015 * are used, which may include defaults from the original FLOW_DEFINITION 22786550Saw148015 * of the composit flowop. 22796550Saw148015 */ 22806550Saw148015 static void 22816550Saw148015 parser_inner_flowop_define(threadflow_t *thread, flowop_t *comp0_flow, 22826550Saw148015 flowop_t *comp_mstr_flow) 22836550Saw148015 { 22846550Saw148015 flowop_t *inner_flowtype, *inner_flowop; 22856550Saw148015 22866550Saw148015 /* follow flowop list, creating composit names */ 22876550Saw148015 inner_flowtype = comp0_flow->fo_comp_fops; 22886550Saw148015 comp_mstr_flow->fo_comp_fops = NULL; 22896550Saw148015 22906550Saw148015 while (inner_flowtype) { 22916550Saw148015 char fullname[MAXPATHLEN]; 22926550Saw148015 22936550Saw148015 /* create composite_name.name for new flowop */ 22946613Sek110237 snprintf(fullname, MAXPATHLEN, "%s.%s", 22956613Sek110237 comp_mstr_flow->fo_name, inner_flowtype->fo_name); 22966550Saw148015 22976550Saw148015 if ((inner_flowop = flowop_define(thread, fullname, 22986550Saw148015 inner_flowtype, &comp_mstr_flow->fo_comp_fops, 22996550Saw148015 FLOW_MASTER, 0)) == NULL) { 23006550Saw148015 filebench_log(LOG_ERROR, 23016550Saw148015 "define flowop: Failed to instantiate flowop %s\n", 23026550Saw148015 fullname); 23036550Saw148015 filebench_shutdown(1); 23046550Saw148015 } 23056550Saw148015 23066550Saw148015 /* if applicable, update filename attribute */ 23076550Saw148015 if (inner_flowop->fo_filename) { 23086550Saw148015 char *name; 23096550Saw148015 23106550Saw148015 /* fix up avd_t */ 23116550Saw148015 avd_update(&inner_flowop->fo_filename, 23126550Saw148015 comp_mstr_flow->fo_lvar_list); 23136550Saw148015 23146550Saw148015 /* see if ready to get the file or fileset */ 23156550Saw148015 name = avd_get_str(inner_flowop->fo_filename); 23166550Saw148015 if (name) { 23176550Saw148015 23186550Saw148015 inner_flowop->fo_fileset = fileset_find(name); 23196550Saw148015 23206550Saw148015 if (inner_flowop->fo_fileset == NULL) { 23216550Saw148015 filebench_log(LOG_ERROR, 23226550Saw148015 "inr flowop %s: file %s not found", 23236550Saw148015 inner_flowop->fo_name, name); 23246550Saw148015 filebench_shutdown(1); 23256550Saw148015 } 23266550Saw148015 } 23276550Saw148015 } 23286550Saw148015 23296550Saw148015 /* update attributes from local variables */ 23306550Saw148015 avd_update(&inner_flowop->fo_iters, 23316550Saw148015 comp_mstr_flow->fo_lvar_list); 23326550Saw148015 23336550Saw148015 /* if the inner flowop is a composit flowop, recurse */ 23346550Saw148015 if (inner_flowtype->fo_type == FLOW_TYPE_COMPOSITE) { 23356550Saw148015 var_t *newlvar, *proto_lvars, *lvar_ptr; 23366550Saw148015 23376550Saw148015 proto_lvars = inner_flowop->fo_lvar_list; 23386550Saw148015 inner_flowop->fo_lvar_list = 0; 23396550Saw148015 23406550Saw148015 for (lvar_ptr = inner_flowtype->fo_lvar_list; lvar_ptr; 23416550Saw148015 lvar_ptr = lvar_ptr->var_next) { 23426550Saw148015 23436550Saw148015 if ((newlvar = var_lvar_alloc_local( 23446550Saw148015 lvar_ptr->var_name)) != NULL) { 23456550Saw148015 23466550Saw148015 add_lvar_to_list(newlvar, 23476550Saw148015 &inner_flowop->fo_lvar_list); 23486550Saw148015 23496550Saw148015 var_update_comp_lvars(newlvar, 23506550Saw148015 proto_lvars, 23516550Saw148015 comp_mstr_flow->fo_lvar_list); 23526550Saw148015 } 23536550Saw148015 } 23546550Saw148015 23556550Saw148015 parser_inner_flowop_define(thread, 23566550Saw148015 inner_flowtype, 23576550Saw148015 inner_flowop); 23586550Saw148015 23596550Saw148015 inner_flowtype = inner_flowtype->fo_exec_next; 23606550Saw148015 continue; 23616550Saw148015 } 23626550Saw148015 23636550Saw148015 avd_update(&inner_flowop->fo_iosize, 23646550Saw148015 comp_mstr_flow->fo_lvar_list); 23656550Saw148015 avd_update(&inner_flowop->fo_wss, 23666550Saw148015 comp_mstr_flow->fo_lvar_list); 23676550Saw148015 avd_update(&inner_flowop->fo_iters, 23686550Saw148015 comp_mstr_flow->fo_lvar_list); 23696550Saw148015 avd_update(&inner_flowop->fo_value, 23706550Saw148015 comp_mstr_flow->fo_lvar_list); 23716550Saw148015 avd_update(&inner_flowop->fo_random, 23726550Saw148015 comp_mstr_flow->fo_lvar_list); 23736550Saw148015 avd_update(&inner_flowop->fo_dsync, 23746550Saw148015 comp_mstr_flow->fo_lvar_list); 23756550Saw148015 avd_update(&inner_flowop->fo_rotatefd, 23766550Saw148015 comp_mstr_flow->fo_lvar_list); 23776550Saw148015 avd_update(&inner_flowop->fo_blocking, 23786550Saw148015 comp_mstr_flow->fo_lvar_list); 23796550Saw148015 avd_update(&inner_flowop->fo_directio, 23806550Saw148015 comp_mstr_flow->fo_lvar_list); 23816550Saw148015 avd_update(&inner_flowop->fo_highwater, 23826550Saw148015 comp_mstr_flow->fo_lvar_list); 23836550Saw148015 23846550Saw148015 inner_flowtype = inner_flowtype->fo_exec_next; 23856550Saw148015 } 23866550Saw148015 } 23876212Saw148015 23886212Saw148015 /* 23895184Sek110237 * Calls flowop_define() to allocate a flowop with the supplied name. 23905184Sek110237 * The allocated flowop inherits attributes from a base flowop of the 23915184Sek110237 * same type. If the new flowop has a file or fileset attribute specified, 23925184Sek110237 * it must specify a defined fileobj or fileset or an error will be logged. 23935184Sek110237 * The new flowop may also have the following attributes set by 23945184Sek110237 * the program: 23955184Sek110237 * - file size (fo_iosize) 23965184Sek110237 * - working set size (fo_wss) 23975184Sek110237 * - do random io (fo_random) 23985184Sek110237 * - do synchronous io (fo_dsync) 23995184Sek110237 * - perform each operation multiple times before advancing (fo_iter) 24005184Sek110237 * - target name (fo_targetname) 24015184Sek110237 * - An integer value (fo_value) 24025184Sek110237 * - a file descriptor (fo_fd) 24035184Sek110237 * - specify to rotate file descriptors (fo_rotatefd) 24045184Sek110237 * - a source fd (fo_srcfdnumber) 24055184Sek110237 * - specify a blocking operation (fo_blocking) 24065184Sek110237 * - specify a highwater mark (fo_highwater) 24075184Sek110237 * 24085184Sek110237 * After all the supplied attributes are stored in their respective locations 24095184Sek110237 * in the flowop object, the flowop's init function is called. No errors are 24105184Sek110237 * returned, but the filebench run will be terminated if the flowtype is not 24115184Sek110237 * specified, a name for the new flowop is not supplied, the flowop_define 24125184Sek110237 * call fails, or a file or fileset name is supplied but the corresponding 24135184Sek110237 * fileobj or fileset cannot be located. 24145184Sek110237 */ 24155184Sek110237 static void 24166212Saw148015 parser_flowop_define(cmd_t *cmd, threadflow_t *thread, 24176212Saw148015 flowop_t **flowoplist_hdp, int category) 24185184Sek110237 { 24195184Sek110237 flowop_t *flowop, *flowop_type; 24205184Sek110237 char *type = (char *)cmd->cmd_name; 24215184Sek110237 char *name; 24225184Sek110237 attr_t *attr; 24235184Sek110237 24245184Sek110237 /* Get the inherited flowop */ 24255184Sek110237 flowop_type = flowop_find(type); 24265184Sek110237 if (flowop_type == NULL) { 24275184Sek110237 filebench_log(LOG_ERROR, 24285184Sek110237 "define flowop: flowop type %s not found", 24295184Sek110237 type); 24305184Sek110237 filebench_shutdown(1); 24315184Sek110237 } 24325184Sek110237 24335184Sek110237 /* Get the name of the flowop */ 24345184Sek110237 if (attr = get_attr(cmd, FSA_NAME)) { 24356212Saw148015 name = avd_get_str(attr->attr_avd); 24365184Sek110237 } else { 24375184Sek110237 filebench_log(LOG_ERROR, 24385184Sek110237 "define flowop: flowop %s specifies no name", 24395184Sek110237 flowop_type->fo_name); 24405184Sek110237 filebench_shutdown(1); 24415184Sek110237 } 24425184Sek110237 24435184Sek110237 if ((flowop = flowop_define(thread, name, 24446550Saw148015 flowop_type, flowoplist_hdp, category, 0)) == NULL) { 24455184Sek110237 filebench_log(LOG_ERROR, 24465184Sek110237 "define flowop: Failed to instantiate flowop %s\n", 24475184Sek110237 cmd->cmd_name); 24485184Sek110237 filebench_shutdown(1); 24495184Sek110237 } 24505184Sek110237 24515184Sek110237 /* Iterations */ 24525184Sek110237 if (attr = get_attr_integer(cmd, FSA_ITERS)) 24536212Saw148015 flowop->fo_iters = attr->attr_avd; 24545184Sek110237 else 24556212Saw148015 flowop->fo_iters = avd_int_alloc(1); 24566212Saw148015 24576550Saw148015 24586550Saw148015 /* if this is a use of a composit flowop, create inner FLOW MASTERS */ 24596550Saw148015 if (flowop_type->fo_type == FLOW_TYPE_COMPOSITE) { 24606550Saw148015 get_attr_lvars(cmd, flowop); 24616550Saw148015 if (category == FLOW_MASTER) 24626550Saw148015 parser_inner_flowop_define(thread, 24636550Saw148015 flowop_type, flowop); 24646550Saw148015 } 24656550Saw148015 else { 24666550Saw148015 parser_flowop_get_attrs(cmd, flowop); 24676550Saw148015 } 24685184Sek110237 } 24695184Sek110237 24706550Saw148015 static void 24716550Saw148015 parser_composite_flowop_define(cmd_t *cmd) 24726550Saw148015 { 24736550Saw148015 flowop_t *flowop; 24746550Saw148015 cmd_t *inner_cmd; 24756550Saw148015 char *name; 24766550Saw148015 attr_t *attr; 24776550Saw148015 24786550Saw148015 /* Get the name of the flowop */ 24796550Saw148015 if (attr = get_attr(cmd, FSA_NAME)) { 24806550Saw148015 name = avd_get_str(attr->attr_avd); 24816550Saw148015 } else { 24826550Saw148015 filebench_log(LOG_ERROR, 24836550Saw148015 "define flowop: Composit flowop specifies no name"); 24846550Saw148015 24856550Saw148015 filebench_shutdown(1); 24866550Saw148015 } 24876550Saw148015 24886550Saw148015 if ((flowop = flowop_new_composite_define(name)) == NULL) { 24896550Saw148015 filebench_log(LOG_ERROR, 24906550Saw148015 "define flowop: Failed to instantiate flowop %s\n", 24916550Saw148015 cmd->cmd_name); 24926550Saw148015 filebench_shutdown(1); 24936550Saw148015 } 24946550Saw148015 24956550Saw148015 /* place any local var_t variables on the flowop's local list */ 24966550Saw148015 get_attr_lvars(cmd, flowop); 24976550Saw148015 24986550Saw148015 /* Iterations */ 24996550Saw148015 if (attr = get_attr_integer(cmd, FSA_ITERS)) 25006550Saw148015 flowop->fo_iters = attr->attr_avd; 25016550Saw148015 else 25026550Saw148015 flowop->fo_iters = avd_int_alloc(1); 25036550Saw148015 25046550Saw148015 /* define inner flowops */ 25056550Saw148015 for (inner_cmd = cmd->cmd_list; inner_cmd != NULL; 25066550Saw148015 inner_cmd = inner_cmd->cmd_next) { 25076550Saw148015 parser_flowop_define(inner_cmd, NULL, 25086550Saw148015 &flowop->fo_comp_fops, FLOW_INNER_DEF); 25096550Saw148015 } 25106550Saw148015 } 25116550Saw148015 25126550Saw148015 25135184Sek110237 /* 25145184Sek110237 * Calls fileset_define() to allocate a fileset with the supplied name and 25156212Saw148015 * initializes the fileset's pathname attribute, and optionally the 25166212Saw148015 * fileset_cached, fileset_reuse, fileset_prealloc and fileset_size attributes. 25175673Saw148015 * 25185184Sek110237 */ 25195673Saw148015 static fileset_t * 25205673Saw148015 parser_fileset_define_common(cmd_t *cmd) 25215184Sek110237 { 25225184Sek110237 fileset_t *fileset; 25236212Saw148015 avd_t name; 25245184Sek110237 attr_t *attr; 25256212Saw148015 avd_t pathname; 25265184Sek110237 25275184Sek110237 /* Get the name of the file */ 25285184Sek110237 if (attr = get_attr(cmd, FSA_NAME)) { 25296212Saw148015 name = attr->attr_avd; 25305184Sek110237 } else { 25315184Sek110237 filebench_log(LOG_ERROR, 25325673Saw148015 "define fileset: file or fileset specifies no name"); 25335673Saw148015 return (NULL); 25345184Sek110237 } 25355184Sek110237 25365184Sek110237 if ((fileset = fileset_define(name)) == NULL) { 25375184Sek110237 filebench_log(LOG_ERROR, 25385184Sek110237 "define file: failed to instantiate file %s\n", 25396212Saw148015 avd_get_str(name)); 25405673Saw148015 return (NULL); 25415184Sek110237 } 25425184Sek110237 25435184Sek110237 /* Get the pathname from attribute */ 25445184Sek110237 if ((attr = get_attr(cmd, FSA_PATH)) == NULL) { 25455184Sek110237 filebench_log(LOG_ERROR, "define file: no pathname specified"); 25465673Saw148015 return (NULL); 25475184Sek110237 } 25485184Sek110237 25495184Sek110237 /* Expand variables in pathname */ 25505673Saw148015 if ((pathname = parser_list2varstring(attr->attr_param_list)) 25515673Saw148015 == NULL) { 25525184Sek110237 filebench_log(LOG_ERROR, "Cannot interpret path"); 25535673Saw148015 return (NULL); 25545184Sek110237 } 25555184Sek110237 25565184Sek110237 fileset->fs_path = pathname; 25575184Sek110237 25585673Saw148015 /* Should we prealloc in parallel? */ 25596212Saw148015 if (attr = get_attr_bool(cmd, FSA_PARALLOC)) 25606212Saw148015 fileset->fs_paralloc = attr->attr_avd; 25616212Saw148015 else 25626212Saw148015 fileset->fs_paralloc = avd_bool_alloc(FALSE); 25635673Saw148015 25645673Saw148015 /* Should we reuse the existing file? */ 25655673Saw148015 if (attr = get_attr_bool(cmd, FSA_REUSE)) { 25666212Saw148015 fileset->fs_reuse = attr->attr_avd; 25675673Saw148015 } else 25686212Saw148015 fileset->fs_reuse = avd_bool_alloc(FALSE); 25695673Saw148015 25705184Sek110237 /* Should we leave in cache? */ 25715184Sek110237 if (attr = get_attr_bool(cmd, FSA_CACHED)) { 25726212Saw148015 fileset->fs_cached = attr->attr_avd; 25735184Sek110237 } else 25746212Saw148015 fileset->fs_cached = avd_bool_alloc(FALSE); 25755184Sek110237 25765673Saw148015 /* Get the mean or absolute size of the file */ 25775673Saw148015 if (attr = get_attr_integer(cmd, FSA_SIZE)) { 25786212Saw148015 fileset->fs_size = attr->attr_avd; 25795184Sek110237 } else 25806212Saw148015 fileset->fs_size = avd_int_alloc(0); 25815673Saw148015 25825673Saw148015 return (fileset); 25835673Saw148015 } 25845673Saw148015 25855673Saw148015 /* 25865673Saw148015 * Calls parser_fileset_define_common() to allocate a fileset with 25876212Saw148015 * one entry and optionally the fileset_prealloc. Sets the 25886212Saw148015 * fileset_preallocpercent, fileset_entries, fileset_dirwidth, 25896212Saw148015 * fileset_dirgamma, and fileset_sizegamma attributes 25905673Saw148015 * to appropriate values for emulating the old "fileobj" entity 25915673Saw148015 */ 25925673Saw148015 static void 25935673Saw148015 parser_file_define(cmd_t *cmd) 25945673Saw148015 { 25955673Saw148015 fileset_t *fileset; 25965673Saw148015 attr_t *attr; 25975673Saw148015 25985673Saw148015 if ((fileset = parser_fileset_define_common(cmd)) == NULL) { 25995673Saw148015 filebench_log(LOG_ERROR, 26005673Saw148015 "define file: failed to instantiate file"); 26015673Saw148015 filebench_shutdown(1); 26025673Saw148015 return; 26035673Saw148015 } 26045673Saw148015 26055673Saw148015 /* fileset is emulating a single file */ 26065673Saw148015 fileset->fs_attrs = FILESET_IS_FILE; 26075673Saw148015 26085673Saw148015 /* Set the size of the fileset to 1 */ 26096212Saw148015 fileset->fs_entries = avd_int_alloc(1); 26105673Saw148015 26115673Saw148015 /* Set the mean dir width to more than 1 */ 26126212Saw148015 fileset->fs_dirwidth = avd_int_alloc(10); 26135673Saw148015 26145673Saw148015 /* Set the dir and size gammas to 0 */ 26156212Saw148015 fileset->fs_dirgamma = avd_int_alloc(0); 26166212Saw148015 fileset->fs_sizegamma = avd_int_alloc(0); 26175673Saw148015 26185673Saw148015 /* Does file need to be preallocated? */ 26195673Saw148015 if (attr = get_attr_bool(cmd, FSA_PREALLOC)) { 26205673Saw148015 /* yes */ 26216212Saw148015 fileset->fs_prealloc = attr->attr_avd; 26226212Saw148015 fileset->fs_preallocpercent = avd_int_alloc(100); 26235673Saw148015 } else { 26245673Saw148015 /* no */ 26256212Saw148015 fileset->fs_prealloc = avd_bool_alloc(FALSE); 26266212Saw148015 fileset->fs_preallocpercent = avd_int_alloc(0); 26275673Saw148015 } 26285673Saw148015 } 26295673Saw148015 26305673Saw148015 /* 26315673Saw148015 * Calls parser_fileset_define_common() to allocate a fileset with the 26326212Saw148015 * supplied name and initializes the fileset's fileset_preallocpercent, 26336212Saw148015 * fileset_prealloc, fileset_entries, fileset_dirwidth, fileset_dirgamma, 26346212Saw148015 * and fileset_sizegamma attributes. 26355673Saw148015 */ 26365673Saw148015 static void 26375673Saw148015 parser_fileset_define(cmd_t *cmd) 26385673Saw148015 { 26395673Saw148015 fileset_t *fileset; 26405673Saw148015 attr_t *attr; 26415673Saw148015 26425673Saw148015 if ((fileset = parser_fileset_define_common(cmd)) == NULL) { 26435673Saw148015 filebench_log(LOG_ERROR, 26445673Saw148015 "define fileset: failed to instantiate fileset"); 26455673Saw148015 filebench_shutdown(1); 26465673Saw148015 return; 26475673Saw148015 } 26485673Saw148015 26495673Saw148015 /* How much should we preallocate? */ 26505184Sek110237 if ((attr = get_attr_integer(cmd, FSA_PREALLOC)) && 26516212Saw148015 attr->attr_avd) { 26526212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 26536212Saw148015 filebench_log(LOG_ERROR, 26546212Saw148015 "define fileset: Prealloc attr cannot be random"); 26556212Saw148015 filebench_shutdown(1); 26566212Saw148015 } 26576212Saw148015 fileset->fs_preallocpercent = attr->attr_avd; 26586212Saw148015 } else if (attr && !attr->attr_avd) { 26596212Saw148015 fileset->fs_preallocpercent = avd_int_alloc(100); 26605184Sek110237 } else { 26616212Saw148015 fileset->fs_preallocpercent = avd_int_alloc(0); 26625184Sek110237 } 26635184Sek110237 26645184Sek110237 /* Should we preallocate? */ 26655184Sek110237 if (attr = get_attr_bool(cmd, FSA_PREALLOC)) { 26666212Saw148015 fileset->fs_prealloc = attr->attr_avd; 26675184Sek110237 } else 26686212Saw148015 fileset->fs_prealloc = avd_bool_alloc(FALSE); 26695184Sek110237 26705673Saw148015 /* Get the number of files in the fileset */ 26715184Sek110237 if (attr = get_attr_integer(cmd, FSA_ENTRIES)) { 26726212Saw148015 fileset->fs_entries = attr->attr_avd; 26735184Sek110237 } else { 26745184Sek110237 filebench_log(LOG_ERROR, "Fileset has zero entries"); 26756212Saw148015 fileset->fs_entries = avd_int_alloc(0); 26765184Sek110237 } 26775184Sek110237 26785184Sek110237 /* Get the mean dir width of the fileset */ 26795184Sek110237 if (attr = get_attr_integer(cmd, FSA_DIRWIDTH)) { 26806212Saw148015 fileset->fs_dirwidth = attr->attr_avd; 26815184Sek110237 } else { 26825184Sek110237 filebench_log(LOG_ERROR, "Fileset has zero directory width"); 26836212Saw148015 fileset->fs_dirwidth = avd_int_alloc(0); 26845184Sek110237 } 26855184Sek110237 26866212Saw148015 /* Get the random variable for dir depth, if supplied */ 26876212Saw148015 if (attr = get_attr_integer(cmd, FSA_DIRDEPTHRV)) { 26886212Saw148015 if (!AVD_IS_RANDOM(attr->attr_avd)) { 26896212Saw148015 filebench_log(LOG_ERROR, 26906212Saw148015 "Define fileset: dirdepthrv must be random var"); 26916212Saw148015 filebench_shutdown(1); 26926212Saw148015 } 26936212Saw148015 fileset->fs_dirdepthrv = attr->attr_avd; 26946212Saw148015 } else { 26956212Saw148015 fileset->fs_dirdepthrv = NULL; 26966212Saw148015 } 26976212Saw148015 26986212Saw148015 /* Get the gamma value for dir depth distributions */ 26995184Sek110237 if (attr = get_attr_integer(cmd, FSA_DIRGAMMA)) { 27006212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 27016212Saw148015 filebench_log(LOG_ERROR, 27026212Saw148015 "Define fileset: dirgamma attr cannot be random"); 27036212Saw148015 filebench_shutdown(1); 27046212Saw148015 } 27056212Saw148015 fileset->fs_dirgamma = attr->attr_avd; 27065184Sek110237 } else 27076212Saw148015 fileset->fs_dirgamma = avd_int_alloc(1500); 27085184Sek110237 27095184Sek110237 /* Get the gamma value for dir width distributions */ 27105184Sek110237 if (attr = get_attr_integer(cmd, FSA_FILESIZEGAMMA)) { 27116212Saw148015 if (AVD_IS_RANDOM(attr->attr_avd)) { 27126212Saw148015 filebench_log(LOG_ERROR, 27136212Saw148015 "Define fileset: filesizegamma cannot be random"); 27146212Saw148015 filebench_shutdown(1); 27156212Saw148015 } 27166212Saw148015 fileset->fs_sizegamma = attr->attr_avd; 27175184Sek110237 } else 27186212Saw148015 fileset->fs_sizegamma = avd_int_alloc(1500); 27195184Sek110237 } 27205184Sek110237 27215184Sek110237 /* 27225184Sek110237 * Creates and starts all defined procflow processes. The call to 27235184Sek110237 * procflow_init() results in creation of the requested number of 27245184Sek110237 * process instances for each previously defined procflow. The 27255184Sek110237 * child processes exec() a new instance of filebench, passing it 27265184Sek110237 * the instance number and address of the shared memory region. 27275184Sek110237 * The child processes will then create their threads and flowops. 27285184Sek110237 * The routine then unlocks the run_lock to allow all the processes' 27295184Sek110237 * threads to start and waits for all of them to begin execution. 27305184Sek110237 * Finally, it records the start time and resets the event generation 27315184Sek110237 * system. 27325184Sek110237 */ 27335184Sek110237 static void 27345184Sek110237 parser_proc_create(cmd_t *cmd) 27355184Sek110237 { 27366084Saw148015 filebench_shm->shm_1st_err = 0; 27375184Sek110237 if (procflow_init() != 0) { 27385184Sek110237 filebench_log(LOG_ERROR, "Failed to create processes\n"); 27395184Sek110237 filebench_shutdown(1); 27405184Sek110237 } 27415184Sek110237 27425184Sek110237 /* Release the read lock, allowing threads to start */ 27436391Saw148015 (void) pthread_rwlock_unlock(&filebench_shm->shm_run_lock); 27445184Sek110237 27455184Sek110237 /* Wait for all threads to start */ 27465184Sek110237 if (procflow_allstarted() != 0) { 27475184Sek110237 filebench_log(LOG_ERROR, "Could not start run"); 27485184Sek110237 return; 27495184Sek110237 } 27505184Sek110237 27515184Sek110237 27525184Sek110237 if (filebench_shm->shm_required && 27535184Sek110237 (ipc_ismcreate(filebench_shm->shm_required) < 0)) { 27545184Sek110237 filebench_log(LOG_ERROR, "Could not allocate shared memory"); 27555184Sek110237 return; 27565184Sek110237 } 27575184Sek110237 27586305Saw148015 filebench_shm->shm_starttime = gethrtime(); 27595184Sek110237 eventgen_reset(); 27605184Sek110237 } 27615184Sek110237 27625184Sek110237 /* 27635673Saw148015 * Calls fileset_createset() to populate all files and filesets and 27645673Saw148015 * create all associated, initially existant, files and subdirectories. 27655184Sek110237 * If errors are encountered, calls filebench_shutdown() 27665184Sek110237 * to exit filebench. 27675184Sek110237 */ 27685184Sek110237 static void 27695184Sek110237 parser_fileset_create(cmd_t *cmd) 27705184Sek110237 { 27715673Saw148015 if (!filecreate_done) { 27725673Saw148015 filecreate_done = 1; 27736212Saw148015 27746212Saw148015 /* initialize the random number system first */ 27756212Saw148015 randdist_init(); 27766212Saw148015 27776212Saw148015 /* create all the filesets */ 27785673Saw148015 if (fileset_createset(NULL) != 0) { 27795673Saw148015 filebench_log(LOG_ERROR, "Failed to create filesets"); 27805673Saw148015 filebench_shutdown(1); 27815673Saw148015 } 27825673Saw148015 } else { 27835673Saw148015 filebench_log(LOG_INFO, 27845673Saw148015 "Attempting to create fileset more than once, ignoring"); 27855184Sek110237 } 27865673Saw148015 27875184Sek110237 } 27885184Sek110237 27895184Sek110237 /* 27905184Sek110237 * Shuts down all processes and their associated threads. When finished 27915184Sek110237 * it deletes interprocess shared memory and resets the event generator. 27925184Sek110237 * It does not exit the filebench program though. 27935184Sek110237 */ 27945184Sek110237 static void 27955184Sek110237 parser_proc_shutdown(cmd_t *cmd) 27965184Sek110237 { 27975184Sek110237 filebench_log(LOG_INFO, "Shutting down processes"); 27985673Saw148015 filecreate_done = 0; 27995184Sek110237 procflow_shutdown(); 28005184Sek110237 if (filebench_shm->shm_required) 28015184Sek110237 ipc_ismdelete(); 28025184Sek110237 eventgen_reset(); 28035184Sek110237 } 28045184Sek110237 28055184Sek110237 /* 28065184Sek110237 * Ends filebench run after first destoring any interprocess 28075184Sek110237 * shared memory. The call to filebench_shutdown() 28085184Sek110237 * also causes filebench to exit. 28095184Sek110237 */ 28105184Sek110237 static void 28115184Sek110237 parser_filebench_shutdown(cmd_t *cmd) 28125184Sek110237 { 28136391Saw148015 int f_abort = filebench_shm->shm_f_abort; 28146391Saw148015 2815*6750Sek110237 ipc_fini(); 28166391Saw148015 28176391Saw148015 if (f_abort == FILEBENCH_ABORT_ERROR) 28186391Saw148015 filebench_shutdown(1); 28196391Saw148015 else 28206391Saw148015 filebench_shutdown(0); 28215184Sek110237 } 28225184Sek110237 28235184Sek110237 /* 28246084Saw148015 * This is Used for timing runs.Pauses the master thread in one second 28256084Saw148015 * intervals until the supplied ptime runs out or the f_abort flag 28266084Saw148015 * is raised. If given a time of zero or less, or the mode is stop on 28276084Saw148015 * lack of resources, it will pause until f_abort is raised. 28285184Sek110237 */ 28295184Sek110237 static void 28306084Saw148015 parser_pause(int ptime) 28315184Sek110237 { 28326084Saw148015 int timeslept = 0; 28336084Saw148015 28346084Saw148015 if ((filebench_shm->shm_rmode == FILEBENCH_MODE_TIMEOUT) && 28356084Saw148015 (ptime > 0)) { 28366084Saw148015 while (timeslept < ptime) { 28376084Saw148015 (void) sleep(1); 28386084Saw148015 timeslept++; 28396391Saw148015 if (filebench_shm->shm_f_abort) 28406084Saw148015 break; 28416084Saw148015 } 28426084Saw148015 } else { 28436084Saw148015 /* initial runtime of 0 means run till abort */ 28446084Saw148015 /* CONSTCOND */ 28456084Saw148015 while (1) { 28466084Saw148015 (void) sleep(1); 28476084Saw148015 timeslept++; 28486391Saw148015 if (filebench_shm->shm_f_abort) 28496084Saw148015 break; 28506084Saw148015 } 28515184Sek110237 } 28526084Saw148015 28536286Saw148015 filebench_log(LOG_INFO, "Run took %d seconds...", timeslept); 28545184Sek110237 } 28555184Sek110237 28565184Sek110237 /* 28575184Sek110237 * Do a file bench run. Calls routines to create file sets, files, and 28585184Sek110237 * processes. It resets the statistics counters, then sleeps for the runtime 28595184Sek110237 * passed as an argument to it on the command line in 1 second increments. 28605184Sek110237 * When it is finished sleeping, it collects a snapshot of the statistics 28615184Sek110237 * and ends the run. 28625184Sek110237 */ 28635184Sek110237 static void 28645184Sek110237 parser_run(cmd_t *cmd) 28655184Sek110237 { 28665184Sek110237 int runtime; 28675184Sek110237 28685184Sek110237 runtime = cmd->cmd_qty; 28696084Saw148015 28705184Sek110237 parser_fileset_create(cmd); 28715184Sek110237 parser_proc_create(cmd); 28725184Sek110237 28735184Sek110237 /* check for startup errors */ 28746391Saw148015 if (filebench_shm->shm_f_abort) 28755184Sek110237 return; 28765184Sek110237 28775184Sek110237 filebench_log(LOG_INFO, "Running..."); 28785184Sek110237 stats_clear(); 28796084Saw148015 28806084Saw148015 parser_pause(runtime); 28816084Saw148015 28825184Sek110237 parser_statssnap(cmd); 28835184Sek110237 parser_proc_shutdown(cmd); 28845184Sek110237 } 28855184Sek110237 28865184Sek110237 /* 28875184Sek110237 * Similar to parser_run, but gets the sleep time from a variable 28885184Sek110237 * whose name is supplied as an argument to the command. 28895184Sek110237 */ 28905184Sek110237 static void 28915184Sek110237 parser_run_variable(cmd_t *cmd) 28925184Sek110237 { 28936212Saw148015 avd_t integer = var_ref_attr(cmd->cmd_tgt1); 28945184Sek110237 int runtime; 28955184Sek110237 28965184Sek110237 if (integer == NULL) { 28975184Sek110237 filebench_log(LOG_ERROR, "Unknown variable %s", 28985184Sek110237 cmd->cmd_tgt1); 28995184Sek110237 return; 29005184Sek110237 } 29015184Sek110237 29026212Saw148015 runtime = avd_get_int(integer); 29035184Sek110237 29045184Sek110237 /* check for startup errors */ 29056391Saw148015 if (filebench_shm->shm_f_abort) 29065184Sek110237 return; 29075184Sek110237 29085184Sek110237 filebench_log(LOG_INFO, "Running..."); 29095184Sek110237 stats_clear(); 29106084Saw148015 29116084Saw148015 parser_pause(runtime); 29126084Saw148015 29135184Sek110237 parser_statssnap(cmd); 29146084Saw148015 parser_proc_shutdown(cmd); 29155184Sek110237 } 29165184Sek110237 29175184Sek110237 char *usagestr = NULL; 29185184Sek110237 29195184Sek110237 /* 29205184Sek110237 * Prints usage string if defined, else just a message requesting load of a 29215184Sek110237 * personality. 29225184Sek110237 */ 29235184Sek110237 static void 29245184Sek110237 parser_help(cmd_t *cmd) 29255184Sek110237 { 29265184Sek110237 if (usagestr) { 29275184Sek110237 filebench_log(LOG_INFO, "%s", usagestr); 29285184Sek110237 } else { 29295184Sek110237 filebench_log(LOG_INFO, 29305184Sek110237 "load <personality> (ls " 29316613Sek110237 FILEBENCHDIR "/workloads for list)"); 29325184Sek110237 } 29335184Sek110237 } 29345184Sek110237 29355184Sek110237 char *varstr = NULL; 29365184Sek110237 29375184Sek110237 /* 29385184Sek110237 * Prints the string of all var definitions, if there is one. 29395184Sek110237 */ 29405184Sek110237 static void 29415184Sek110237 parser_printvars(cmd_t *cmd) 29425184Sek110237 { 29435184Sek110237 char *str, *c; 29445184Sek110237 29455184Sek110237 if (varstr) { 29465184Sek110237 str = strdup(varstr); 29475184Sek110237 for (c = str; *c != '\0'; c++) { 29485184Sek110237 if ((char)*c == '$') 29495184Sek110237 *c = ' '; 29505184Sek110237 } 29515184Sek110237 filebench_log(LOG_INFO, "%s", str); 29525184Sek110237 free(str); 29535184Sek110237 } 29545184Sek110237 } 29555184Sek110237 29565184Sek110237 /* 29575184Sek110237 * Used by the SET command to add a var and default value string to the 29585184Sek110237 * varstr string. It allocates a new, larger varstr string, copies the 29595184Sek110237 * old contents of varstr into it, then adds the new var string on the end. 29605184Sek110237 */ 29615184Sek110237 static void 29625184Sek110237 parser_vars(cmd_t *cmd) 29635184Sek110237 { 29645184Sek110237 char *string = cmd->cmd_tgt1; 29655184Sek110237 char *newvars; 29665184Sek110237 29675184Sek110237 if (string == NULL) 29685184Sek110237 return; 29695184Sek110237 29705184Sek110237 if (dofile) 29715184Sek110237 return; 29725184Sek110237 29735184Sek110237 if (varstr == NULL) { 29745184Sek110237 newvars = malloc(strlen(string) + 2); 29755184Sek110237 *newvars = 0; 29765184Sek110237 } else { 29775184Sek110237 newvars = malloc(strlen(varstr) + strlen(string) + 2); 29785184Sek110237 (void) strcpy(newvars, varstr); 29795184Sek110237 } 29805184Sek110237 (void) strcat(newvars, string); 29815184Sek110237 (void) strcat(newvars, " "); 29825184Sek110237 29835184Sek110237 if (varstr) 29845184Sek110237 free(varstr); 29855184Sek110237 29865184Sek110237 varstr = newvars; 29875184Sek110237 } 29885184Sek110237 29895184Sek110237 /* 29906084Saw148015 * Sleeps for cmd->cmd_qty seconds, one second at a time. 29916084Saw148015 */ 29926084Saw148015 static void 29936084Saw148015 parser_sleep(cmd_t *cmd) 29946084Saw148015 { 29956084Saw148015 int sleeptime; 29966084Saw148015 29976084Saw148015 /* check for startup errors */ 29986391Saw148015 if (filebench_shm->shm_f_abort) 29996084Saw148015 return; 30006084Saw148015 30016084Saw148015 sleeptime = cmd->cmd_qty; 30026084Saw148015 filebench_log(LOG_INFO, "Running..."); 30036084Saw148015 30046084Saw148015 parser_pause(sleeptime); 30056084Saw148015 } 30066084Saw148015 30076084Saw148015 /* 30086212Saw148015 * used by the set command to set the integer part of a regular 30096212Saw148015 * variable, or the appropriate field of a random variable 30106212Saw148015 */ 30116212Saw148015 static void 30126212Saw148015 parser_set_integer(char *name, fbint_t integer) 30136212Saw148015 { 30146212Saw148015 var_assign_integer(name, integer); 30156212Saw148015 } 30166212Saw148015 30176212Saw148015 /* 30186212Saw148015 * used by the set command to set the integer part of a regular 30196212Saw148015 * variable from another variable, or the appropriate field of a 30206212Saw148015 * random variable from another variable 30216212Saw148015 */ 30226212Saw148015 static void 30236212Saw148015 parser_set_var(char *dst_name, char *src_name) 30246212Saw148015 { 30256212Saw148015 var_assign_var(dst_name, src_name); 30266212Saw148015 } 30276212Saw148015 30286212Saw148015 30296212Saw148015 /* 30305184Sek110237 * Same as parser_sleep, except the sleep time is obtained from a variable 30315184Sek110237 * whose name is passed to it as an argument on the command line. 30325184Sek110237 */ 30335184Sek110237 static void 30345184Sek110237 parser_sleep_variable(cmd_t *cmd) 30355184Sek110237 { 30366212Saw148015 avd_t integer = var_ref_attr(cmd->cmd_tgt1); 30375184Sek110237 int sleeptime; 30385184Sek110237 30395184Sek110237 if (integer == NULL) { 30405184Sek110237 filebench_log(LOG_ERROR, "Unknown variable %s", 30415184Sek110237 cmd->cmd_tgt1); 30425184Sek110237 return; 30435184Sek110237 } 30445184Sek110237 30456212Saw148015 sleeptime = avd_get_int(integer); 30465184Sek110237 30475184Sek110237 /* check for startup errors */ 30486391Saw148015 if (filebench_shm->shm_f_abort) 30495184Sek110237 return; 30505184Sek110237 30515184Sek110237 filebench_log(LOG_INFO, "Running..."); 30526084Saw148015 30536084Saw148015 parser_pause(sleeptime); 30545184Sek110237 } 30555184Sek110237 30565184Sek110237 /* 30575184Sek110237 * Parser log prints the values of a list of variables to the log file. 30585184Sek110237 * The list of variables is placed on the command line, separated 30595184Sek110237 * by comas and the entire list is enclosed in quotes. 30605184Sek110237 * For example, if $dir contains "/export/home/tmp" and $filesize = 1048576, 30615184Sek110237 * then typing: log "$dir, $filesize" prints: log /export/home/tmp, 1048576 30625184Sek110237 */ 30635184Sek110237 static void 30645184Sek110237 parser_log(cmd_t *cmd) 30655184Sek110237 { 30665184Sek110237 char *string; 30675184Sek110237 30685184Sek110237 if (cmd->cmd_param_list == NULL) 30695184Sek110237 return; 30705184Sek110237 30715184Sek110237 string = parser_list2string(cmd->cmd_param_list); 30725184Sek110237 30735184Sek110237 if (string == NULL) 30745184Sek110237 return; 30755184Sek110237 30765184Sek110237 filebench_log(LOG_VERBOSE, "log %s", string); 30775184Sek110237 filebench_log(LOG_LOG, "%s", string); 30785184Sek110237 } 30795184Sek110237 30805184Sek110237 /* 30815184Sek110237 * Implements the stats directory command. changes the directory for 30825184Sek110237 * dumping statistics to supplied directory path. For example: 30835184Sek110237 * stats directory /tmp 30845184Sek110237 * changes the stats directory to "/tmp". 30855184Sek110237 */ 30865184Sek110237 static void 30875184Sek110237 parser_directory(cmd_t *cmd) 30885184Sek110237 { 30895184Sek110237 char newdir[MAXPATHLEN]; 30905184Sek110237 char *dir; 30915184Sek110237 30925184Sek110237 if ((dir = parser_list2string(cmd->cmd_param_list)) == NULL) { 30935184Sek110237 filebench_log(LOG_ERROR, "Cannot interpret directory"); 30945184Sek110237 return; 30955184Sek110237 } 30965184Sek110237 30975184Sek110237 *newdir = 0; 30985184Sek110237 /* Change dir relative to cwd if path not fully qualified */ 30995184Sek110237 if (*dir != '/') { 31005184Sek110237 (void) strcat(newdir, cwd); 31015184Sek110237 (void) strcat(newdir, "/"); 31025184Sek110237 } 31035184Sek110237 (void) strcat(newdir, dir); 31045184Sek110237 (void) mkdir(newdir, 0755); 31055184Sek110237 filebench_log(LOG_VERBOSE, "Change dir to %s", newdir); 31065184Sek110237 chdir(newdir); 31075184Sek110237 free(dir); 31085184Sek110237 } 31095184Sek110237 31105184Sek110237 #define PIPE_PARENT 1 31115184Sek110237 #define PIPE_CHILD 0 31125184Sek110237 31135184Sek110237 /* 31145184Sek110237 * Runs the quoted unix command as a background process. Intended for 31155184Sek110237 * running statistics gathering utilities such as mpstat while the filebench 31165184Sek110237 * workload is running. Also records the pid's of the background processes 31175184Sek110237 * so that parser_statssnap() can terminate them when the run completes. 31185184Sek110237 */ 31195184Sek110237 static void 31205184Sek110237 parser_statscmd(cmd_t *cmd) 31215184Sek110237 { 31225184Sek110237 char *string; 31235184Sek110237 pid_t pid; 31245184Sek110237 pidlist_t *pidlistent; 31255184Sek110237 int pipe_fd[2]; 31265184Sek110237 int newstdout; 31275184Sek110237 31285184Sek110237 if (cmd->cmd_param_list == NULL) 31295184Sek110237 return; 31305184Sek110237 31315184Sek110237 string = parser_list2string(cmd->cmd_param_list); 31325184Sek110237 31335184Sek110237 if (string == NULL) 31345184Sek110237 return; 31355184Sek110237 31365184Sek110237 if ((pipe(pipe_fd)) < 0) { 31375184Sek110237 filebench_log(LOG_ERROR, "statscmd pipe failed"); 31385184Sek110237 return; 31395184Sek110237 } 31405184Sek110237 31415184Sek110237 #ifdef HAVE_FORK1 31425184Sek110237 if ((pid = fork1()) < 0) { 31435184Sek110237 filebench_log(LOG_ERROR, "statscmd fork failed"); 31445184Sek110237 return; 31455184Sek110237 } 31465184Sek110237 #elif HAVE_FORK 31475184Sek110237 if ((pid = fork()) < 0) { 31485184Sek110237 filebench_log(LOG_ERROR, "statscmd fork failed"); 31495184Sek110237 return; 31505184Sek110237 } 31515184Sek110237 #else 31525184Sek110237 Crash! - Need code to deal with no fork1! 31535184Sek110237 #endif /* HAVE_FORK1 */ 31545184Sek110237 31555184Sek110237 if (pid == 0) { 31565184Sek110237 31575184Sek110237 setsid(); 31585184Sek110237 31595184Sek110237 filebench_log(LOG_VERBOSE, 31605184Sek110237 "Backgrounding %s", string); 31615184Sek110237 /* 31625184Sek110237 * Child 31635184Sek110237 * - close stdout 31645184Sek110237 * - dup to create new stdout 31655184Sek110237 * - close pipe fds 31665184Sek110237 */ 31675184Sek110237 (void) close(1); 31685184Sek110237 31695184Sek110237 if ((newstdout = dup(pipe_fd[PIPE_CHILD])) < 0) { 31705184Sek110237 filebench_log(LOG_ERROR, 31715184Sek110237 "statscmd dup failed: %s", 31725184Sek110237 strerror(errno)); 31735184Sek110237 } 31745184Sek110237 31755184Sek110237 (void) close(pipe_fd[PIPE_PARENT]); 31765184Sek110237 (void) close(pipe_fd[PIPE_CHILD]); 31775184Sek110237 31785184Sek110237 if (system(string) < 0) { 31795184Sek110237 filebench_log(LOG_ERROR, 31805184Sek110237 "statscmd exec failed: %s", 31815184Sek110237 strerror(errno)); 31825184Sek110237 } 31835184Sek110237 /* Failed! */ 31845184Sek110237 exit(1); 31855184Sek110237 31865184Sek110237 } else { 31875184Sek110237 31885184Sek110237 /* Record pid in pidlist for subsequent reaping by stats snap */ 31895184Sek110237 if ((pidlistent = (pidlist_t *)malloc(sizeof (pidlist_t))) 31905184Sek110237 == NULL) { 31915184Sek110237 filebench_log(LOG_ERROR, "pidlistent malloc failed"); 31925184Sek110237 return; 31935184Sek110237 } 31945184Sek110237 31955184Sek110237 pidlistent->pl_pid = pid; 31965184Sek110237 pidlistent->pl_fd = pipe_fd[PIPE_PARENT]; 31975184Sek110237 (void) close(pipe_fd[PIPE_CHILD]); 31985184Sek110237 31995184Sek110237 /* Add fileobj to global list */ 32005184Sek110237 if (pidlist == NULL) { 32015184Sek110237 pidlist = pidlistent; 32025184Sek110237 pidlistent->pl_next = NULL; 32035184Sek110237 } else { 32045184Sek110237 pidlistent->pl_next = pidlist; 32055184Sek110237 pidlist = pidlistent; 32065184Sek110237 } 32075184Sek110237 } 32085184Sek110237 } 32095184Sek110237 32105184Sek110237 /* 32115184Sek110237 * Launches a shell to run the unix command supplied in the argument. 32125184Sek110237 * The command should be enclosed in quotes, as in: 32135184Sek110237 * system "rm xyz" 32145184Sek110237 * which would run the "rm" utility to delete the file "xyz". 32155184Sek110237 */ 32165184Sek110237 static void 32175184Sek110237 parser_system(cmd_t *cmd) 32185184Sek110237 { 32195184Sek110237 char *string; 32205184Sek110237 32215184Sek110237 if (cmd->cmd_param_list == NULL) 32225184Sek110237 return; 32235184Sek110237 32245184Sek110237 string = parser_list2string(cmd->cmd_param_list); 32255184Sek110237 32265184Sek110237 if (string == NULL) 32275184Sek110237 return; 32285184Sek110237 32295184Sek110237 filebench_log(LOG_VERBOSE, 32305184Sek110237 "Running '%s'", string); 32315184Sek110237 32325184Sek110237 if (system(string) < 0) { 32335184Sek110237 filebench_log(LOG_ERROR, 32345184Sek110237 "system exec failed: %s", 32355184Sek110237 strerror(errno)); 32365184Sek110237 } 32375184Sek110237 free(string); 32385184Sek110237 } 32395184Sek110237 32405184Sek110237 /* 32415184Sek110237 * Echos string supplied with command to the log. 32425184Sek110237 */ 32435184Sek110237 static void 32445184Sek110237 parser_echo(cmd_t *cmd) 32455184Sek110237 { 32465184Sek110237 char *string; 32475184Sek110237 32485184Sek110237 if (cmd->cmd_param_list == NULL) 32495184Sek110237 return; 32505184Sek110237 32515184Sek110237 string = parser_list2string(cmd->cmd_param_list); 32525184Sek110237 32535184Sek110237 if (string == NULL) 32545184Sek110237 return; 32555184Sek110237 32565184Sek110237 filebench_log(LOG_INFO, "%s", string); 32575184Sek110237 } 32585184Sek110237 3259*6750Sek110237 /* 3260*6750Sek110237 * Prints out the version of FileBench. 3261*6750Sek110237 */ 3262*6750Sek110237 static void 3263*6750Sek110237 parser_version(cmd_t *cmd) 3264*6750Sek110237 { 3265*6750Sek110237 filebench_log(LOG_INFO, "FileBench Version: %s", FILEBENCH_VERSION); 3266*6750Sek110237 } 32675184Sek110237 32685184Sek110237 /* 32695184Sek110237 * Adds the string supplied as the argument to the usage command 32705184Sek110237 * to the end of the string printed by the help command. 32715184Sek110237 */ 32725184Sek110237 static void 32735184Sek110237 parser_usage(cmd_t *cmd) 32745184Sek110237 { 32755184Sek110237 char *string; 32765184Sek110237 char *newusage; 32775184Sek110237 32785184Sek110237 if (cmd->cmd_param_list == NULL) 32795184Sek110237 return; 32805184Sek110237 32815184Sek110237 string = parser_list2string(cmd->cmd_param_list); 32825184Sek110237 32835184Sek110237 if (string == NULL) 32845184Sek110237 return; 32855184Sek110237 32865184Sek110237 if (dofile) 32875184Sek110237 return; 32885184Sek110237 32895184Sek110237 if (usagestr == NULL) { 32905184Sek110237 newusage = malloc(strlen(string) + 2); 32915184Sek110237 *newusage = 0; 32925184Sek110237 } else { 32935184Sek110237 newusage = malloc(strlen(usagestr) + strlen(string) + 2); 32945184Sek110237 (void) strcpy(newusage, usagestr); 32955184Sek110237 } 32965184Sek110237 (void) strcat(newusage, "\n"); 32975184Sek110237 (void) strcat(newusage, string); 32985184Sek110237 32995184Sek110237 if (usagestr) 33005184Sek110237 free(usagestr); 33015184Sek110237 33025184Sek110237 usagestr = newusage; 33035184Sek110237 33045184Sek110237 filebench_log(LOG_INFO, "%s", string); 33055184Sek110237 } 33065184Sek110237 33075184Sek110237 /* 33085184Sek110237 * Updates the global dump filename with the filename supplied 33095184Sek110237 * as the command's argument. Then dumps the statistics of each 33105184Sek110237 * worker flowop into the dump file, followed by a summary of 33115184Sek110237 * overall totals. 33125184Sek110237 */ 33135184Sek110237 static void 33145184Sek110237 parser_statsdump(cmd_t *cmd) 33155184Sek110237 { 33165184Sek110237 char *string; 33175184Sek110237 33185184Sek110237 if (cmd->cmd_param_list == NULL) 33195184Sek110237 return; 33205184Sek110237 33215184Sek110237 string = parser_list2string(cmd->cmd_param_list); 33225184Sek110237 33235184Sek110237 if (string == NULL) 33245184Sek110237 return; 33255184Sek110237 33265184Sek110237 filebench_log(LOG_VERBOSE, 33275184Sek110237 "Stats dump to file '%s'", string); 33285184Sek110237 33295184Sek110237 stats_dump(string); 33305184Sek110237 33315184Sek110237 free(string); 33325184Sek110237 } 33335184Sek110237 33345184Sek110237 /* 33355184Sek110237 * Same as parser_statsdump, but in xml format. 33365184Sek110237 */ 33375184Sek110237 static void 33385184Sek110237 parser_statsxmldump(cmd_t *cmd) 33395184Sek110237 { 33405184Sek110237 char *string; 33415184Sek110237 33425184Sek110237 if (cmd->cmd_param_list == NULL) 33435184Sek110237 return; 33445184Sek110237 33455184Sek110237 string = parser_list2string(cmd->cmd_param_list); 33465184Sek110237 33475184Sek110237 if (string == NULL) 33485184Sek110237 return; 33495184Sek110237 33505184Sek110237 filebench_log(LOG_VERBOSE, 33515184Sek110237 "Stats dump to file '%s'", string); 33525184Sek110237 33535184Sek110237 stats_xmldump(string); 33545184Sek110237 33555184Sek110237 free(string); 33565184Sek110237 } 33575184Sek110237 33585184Sek110237 /* 33595184Sek110237 * Kills off background statistics collection processes, then takes a snapshot 33605184Sek110237 * of the filebench run's collected statistics using stats_snap() from 33615184Sek110237 * stats.c. 33625184Sek110237 */ 33635184Sek110237 static void 33645184Sek110237 parser_statssnap(cmd_t *cmd) 33655184Sek110237 { 33665184Sek110237 pidlist_t *pidlistent; 33675184Sek110237 int stat; 33685184Sek110237 pid_t pid; 33695184Sek110237 33705184Sek110237 for (pidlistent = pidlist; pidlistent != NULL; 33715184Sek110237 pidlistent = pidlistent->pl_next) { 33725184Sek110237 filebench_log(LOG_VERBOSE, "Killing session %d for pid %d", 33735184Sek110237 getsid(pidlistent->pl_pid), 33745184Sek110237 pidlistent->pl_pid); 33755184Sek110237 if (pidlistent->pl_fd) 33765184Sek110237 (void) close(pidlistent->pl_fd); 33775184Sek110237 #ifdef HAVE_SIGSEND 33785184Sek110237 sigsend(P_SID, getsid(pidlistent->pl_pid), SIGTERM); 33795184Sek110237 #else 33805184Sek110237 (void) kill(-1, SIGTERM); 33815184Sek110237 #endif 33825184Sek110237 33835184Sek110237 /* Close pipe */ 33845184Sek110237 if (pidlistent->pl_fd) 33855184Sek110237 (void) close(pidlistent->pl_fd); 33865184Sek110237 33875184Sek110237 /* Wait for cmd and all its children */ 33885184Sek110237 while ((pid = waitpid(pidlistent->pl_pid * -1, &stat, 0)) > 0) 33895184Sek110237 filebench_log(LOG_DEBUG_IMPL, 33906286Saw148015 "Waited for pid %d", (int)pid); 33915184Sek110237 } 33925184Sek110237 33935184Sek110237 for (pidlistent = pidlist; pidlistent != NULL; 33945184Sek110237 pidlistent = pidlistent->pl_next) { 33955184Sek110237 free(pidlistent); 33965184Sek110237 } 33975184Sek110237 33985184Sek110237 pidlist = NULL; 33995184Sek110237 stats_snap(); 34005184Sek110237 } 34015184Sek110237 34025184Sek110237 /* 34035184Sek110237 * Shutdown filebench. 34045184Sek110237 */ 34055184Sek110237 static void 34065184Sek110237 parser_abort(int arg) 34075184Sek110237 { 34085184Sek110237 (void) sigignore(SIGINT); 34095184Sek110237 filebench_log(LOG_INFO, "Aborting..."); 34105184Sek110237 filebench_shutdown(1); 34115184Sek110237 } 34125184Sek110237 34135184Sek110237 /* 34146212Saw148015 * define a random variable and initialize the distribution parameters 34156212Saw148015 */ 34166212Saw148015 static void 34176212Saw148015 parser_randvar_define(cmd_t *cmd) 34186212Saw148015 { 34196212Saw148015 var_t *var; 34206212Saw148015 randdist_t *rndp; 34216212Saw148015 attr_t *attr; 34226212Saw148015 char *name; 34236212Saw148015 34246212Saw148015 /* Get the name for the random variable */ 34256212Saw148015 if (attr = get_attr(cmd, FSA_NAME)) { 34266212Saw148015 name = avd_get_str(attr->attr_avd); 34276212Saw148015 } else { 34286212Saw148015 filebench_log(LOG_ERROR, 34296212Saw148015 "define randvar: no name specified"); 34306212Saw148015 return; 34316212Saw148015 } 34326212Saw148015 34336212Saw148015 if ((var = var_define_randvar(name)) == NULL) { 34346212Saw148015 filebench_log(LOG_ERROR, 34356212Saw148015 "define randvar: failed for random variable %s", 34366212Saw148015 name); 34376212Saw148015 return; 34386212Saw148015 } 34396212Saw148015 34406212Saw148015 rndp = var->var_val.randptr; 34416212Saw148015 rndp->rnd_type = 0; 34426212Saw148015 34436212Saw148015 /* Get the source of the random numbers */ 34446212Saw148015 if (attr = get_attr_integer(cmd, FSA_RANDSRC)) { 34456212Saw148015 int randsrc = (int)avd_get_int(attr->attr_avd); 34466212Saw148015 34476212Saw148015 switch (randsrc) { 34486212Saw148015 case FSV_URAND: 34496212Saw148015 rndp->rnd_type |= RAND_SRC_URANDOM; 34506212Saw148015 break; 34516212Saw148015 case FSV_RAND48: 34526212Saw148015 rndp->rnd_type |= RAND_SRC_GENERATOR; 34536212Saw148015 break; 34546212Saw148015 } 34556212Saw148015 } else { 34566212Saw148015 /* default to rand48 random number generator */ 34576212Saw148015 rndp->rnd_type |= RAND_SRC_GENERATOR; 34586212Saw148015 } 34596212Saw148015 34606212Saw148015 /* Get the min value of the random distribution */ 34616212Saw148015 if (attr = get_attr_integer(cmd, FSA_RANDMIN)) 34626212Saw148015 rndp->rnd_min = attr->attr_avd; 34636212Saw148015 else 34646212Saw148015 rndp->rnd_min = avd_int_alloc(0); 34656212Saw148015 34666212Saw148015 /* Get the mean value of the random distribution */ 34676212Saw148015 if (attr = get_attr_integer(cmd, FSA_RANDMEAN)) 34686212Saw148015 rndp->rnd_mean = attr->attr_avd; 34696212Saw148015 else 34706212Saw148015 rndp->rnd_mean = avd_int_alloc(0); 34716212Saw148015 34726212Saw148015 /* Get the roundoff value for the random distribution */ 34736212Saw148015 if (attr = get_attr_integer(cmd, FSA_RANDROUND)) 34746212Saw148015 rndp->rnd_round = attr->attr_avd; 34756212Saw148015 else 34766212Saw148015 rndp->rnd_round = avd_int_alloc(0); 34776212Saw148015 34786212Saw148015 /* Get a tablular probablility distribution if there is one */ 34796212Saw148015 if (attr = get_attr(cmd, FSA_RANDTABLE)) { 34806212Saw148015 rndp->rnd_probtabs = (probtabent_t *)(attr->attr_obj); 34816212Saw148015 rndp->rnd_type |= RAND_TYPE_TABLE; 34826212Saw148015 34836212Saw148015 /* no need for the rest of the attributes */ 34846212Saw148015 return; 34856212Saw148015 } else { 34866212Saw148015 rndp->rnd_probtabs = NULL; 34876212Saw148015 } 34886212Saw148015 34896212Saw148015 /* Get the type for the random variable */ 34906212Saw148015 if (attr = get_attr(cmd, FSA_TYPE)) { 34916212Saw148015 int disttype = (int)avd_get_int(attr->attr_avd); 34926212Saw148015 34936212Saw148015 switch (disttype) { 34946212Saw148015 case FSV_RANDUNI: 34956212Saw148015 rndp->rnd_type |= RAND_TYPE_UNIFORM; 34966212Saw148015 break; 34976212Saw148015 case FSA_RANDGAMMA: 34986212Saw148015 rndp->rnd_type |= RAND_TYPE_GAMMA; 34996212Saw148015 break; 35006212Saw148015 case FSV_RANDTAB: 35016212Saw148015 filebench_log(LOG_ERROR, 35026212Saw148015 "Table distribution type without prob table"); 35036212Saw148015 break; 35046212Saw148015 } 35056212Saw148015 } else { 35066212Saw148015 /* default to gamma distribution type */ 35076212Saw148015 rndp->rnd_type |= RAND_TYPE_GAMMA; 35086212Saw148015 } 35096212Saw148015 35106212Saw148015 /* Get the seed for the random variable */ 35116212Saw148015 if (attr = get_attr_integer(cmd, FSA_RANDSEED)) 35126212Saw148015 rndp->rnd_seed = attr->attr_avd; 35136212Saw148015 else 35146212Saw148015 rndp->rnd_seed = avd_int_alloc(0); 35156212Saw148015 35166212Saw148015 /* Get the gamma value of the random distribution */ 35176212Saw148015 if (attr = get_attr_integer(cmd, FSA_RANDGAMMA)) 35186212Saw148015 rndp->rnd_gamma = attr->attr_avd; 35196212Saw148015 else 35206212Saw148015 rndp->rnd_gamma = avd_int_alloc(1500); 35216212Saw148015 } 35226212Saw148015 35236212Saw148015 /* 35246212Saw148015 * Set a specified random distribution parameter in a random variable. 35256212Saw148015 */ 35266212Saw148015 static void 35276212Saw148015 parser_randvar_set(cmd_t *cmd) 35286212Saw148015 { 35296212Saw148015 var_t *src_var, *randvar; 35306212Saw148015 randdist_t *rndp; 35316212Saw148015 avd_t value; 35326212Saw148015 35336212Saw148015 if ((randvar = var_find_randvar(cmd->cmd_tgt1)) == NULL) { 35346212Saw148015 filebench_log(LOG_ERROR, 35356212Saw148015 "set randvar: failed", 35366212Saw148015 cmd->cmd_tgt1); 35376212Saw148015 return; 35386212Saw148015 } 35396212Saw148015 35406212Saw148015 rndp = randvar->var_val.randptr; 35416212Saw148015 value = cmd->cmd_attr_list->attr_avd; 35426212Saw148015 35436212Saw148015 switch (cmd->cmd_qty) { 35446212Saw148015 case FSS_TYPE: 35456212Saw148015 { 35466212Saw148015 int disttype = (int)avd_get_int(value); 35476212Saw148015 35486212Saw148015 rndp->rnd_type &= (~RAND_TYPE_MASK); 35496212Saw148015 35506212Saw148015 switch (disttype) { 35516212Saw148015 case FSV_RANDUNI: 35526212Saw148015 rndp->rnd_type |= RAND_TYPE_UNIFORM; 35536212Saw148015 break; 35546212Saw148015 case FSA_RANDGAMMA: 35556212Saw148015 rndp->rnd_type |= RAND_TYPE_GAMMA; 35566212Saw148015 break; 35576212Saw148015 case FSV_RANDTAB: 35586212Saw148015 rndp->rnd_type |= RAND_TYPE_TABLE; 35596212Saw148015 break; 35606212Saw148015 } 35616212Saw148015 break; 35626212Saw148015 } 35636212Saw148015 35646212Saw148015 case FSS_SRC: 35656212Saw148015 { 35666212Saw148015 int randsrc = (int)avd_get_int(value); 35676212Saw148015 35686212Saw148015 rndp->rnd_type &= 35696212Saw148015 (~(RAND_SRC_URANDOM | RAND_SRC_GENERATOR)); 35706212Saw148015 35716212Saw148015 switch (randsrc) { 35726212Saw148015 case FSV_URAND: 35736212Saw148015 rndp->rnd_type |= RAND_SRC_URANDOM; 35746212Saw148015 break; 35756212Saw148015 case FSV_RAND48: 35766212Saw148015 rndp->rnd_type |= RAND_SRC_GENERATOR; 35776212Saw148015 break; 35786212Saw148015 } 35796212Saw148015 break; 35806212Saw148015 } 35816212Saw148015 35826212Saw148015 case FSS_SEED: 35836212Saw148015 rndp->rnd_seed = value; 35846212Saw148015 break; 35856212Saw148015 35866212Saw148015 case FSS_GAMMA: 35876212Saw148015 rndp->rnd_gamma = value; 35886212Saw148015 break; 35896212Saw148015 35906212Saw148015 case FSS_MEAN: 35916212Saw148015 rndp->rnd_mean = value; 35926212Saw148015 break; 35936212Saw148015 35946212Saw148015 case FSS_MIN: 35956212Saw148015 rndp->rnd_min = value; 35966212Saw148015 break; 35976212Saw148015 35986212Saw148015 case FSS_ROUND: 35996212Saw148015 rndp->rnd_round = value; 36006212Saw148015 break; 36016212Saw148015 36026212Saw148015 default: 36036212Saw148015 filebench_log(LOG_ERROR, "setrandvar: undefined attribute"); 36046212Saw148015 } 36056212Saw148015 } 36066212Saw148015 36076212Saw148015 /* 36085184Sek110237 * alloc_cmd() allocates the required resources for a cmd_t. On failure, a 36095184Sek110237 * filebench_log is issued and NULL is returned. 36105184Sek110237 */ 36115184Sek110237 static cmd_t * 36125184Sek110237 alloc_cmd(void) 36135184Sek110237 { 36145184Sek110237 cmd_t *cmd; 36155184Sek110237 36165184Sek110237 if ((cmd = malloc(sizeof (cmd_t))) == NULL) { 36175184Sek110237 filebench_log(LOG_ERROR, "Alloc cmd failed"); 36185184Sek110237 return (NULL); 36195184Sek110237 } 36205184Sek110237 36215184Sek110237 (void) memset(cmd, 0, sizeof (cmd_t)); 36225184Sek110237 36235184Sek110237 return (cmd); 36245184Sek110237 } 36255184Sek110237 36265184Sek110237 /* 36275184Sek110237 * Frees the resources of a cmd_t and then the cmd_t "cmd" itself. 36285184Sek110237 */ 36295184Sek110237 static void 36305184Sek110237 free_cmd(cmd_t *cmd) 36315184Sek110237 { 36325184Sek110237 free((void *)cmd->cmd_tgt1); 36335184Sek110237 free((void *)cmd->cmd_tgt2); 36345184Sek110237 free(cmd); 36355184Sek110237 } 36365184Sek110237 36375184Sek110237 /* 36385184Sek110237 * Allocates an attr_t structure and zeros it. Returns NULL on failure, or 36395184Sek110237 * a pointer to the attr_t. 36405184Sek110237 */ 36415184Sek110237 static attr_t * 36426550Saw148015 alloc_attr(void) 36435184Sek110237 { 36445184Sek110237 attr_t *attr; 36455184Sek110237 36465184Sek110237 if ((attr = malloc(sizeof (attr_t))) == NULL) { 36475184Sek110237 return (NULL); 36485184Sek110237 } 36495184Sek110237 36505184Sek110237 (void) memset(attr, 0, sizeof (attr_t)); 36515184Sek110237 return (attr); 36525184Sek110237 } 36535184Sek110237 36545184Sek110237 /* 36556212Saw148015 * Allocates a probtabent_t structure and zeros it. Returns NULL on failure, or 36566212Saw148015 * a pointer to the probtabent_t. 36576212Saw148015 */ 36586212Saw148015 static probtabent_t * 36596212Saw148015 alloc_probtabent(void) 36606212Saw148015 { 36616212Saw148015 probtabent_t *rte; 36626212Saw148015 36636212Saw148015 if ((rte = malloc(sizeof (probtabent_t))) == NULL) { 36646212Saw148015 return (NULL); 36656212Saw148015 } 36666212Saw148015 36676212Saw148015 (void) memset(rte, 0, sizeof (probtabent_t)); 36686212Saw148015 return (rte); 36696212Saw148015 } 36706212Saw148015 36716212Saw148015 /* 36726550Saw148015 * Allocates an attr_t structure and puts the supplied var_t into 36736550Saw148015 * its attr_avd location, and sets its name to FSA_LVAR_ASSIGN 36746550Saw148015 */ 36756550Saw148015 static attr_t * 36766550Saw148015 alloc_lvar_attr(var_t *var) 36776550Saw148015 { 36786550Saw148015 attr_t *attr; 36796550Saw148015 36806550Saw148015 if ((attr = alloc_attr()) == NULL) 36816550Saw148015 return (NULL); 36826550Saw148015 36836550Saw148015 attr->attr_name = FSA_LVAR_ASSIGN; 36846550Saw148015 attr->attr_avd = (avd_t)var; 36856550Saw148015 36866550Saw148015 return (attr); 36876550Saw148015 } 36886550Saw148015 36896550Saw148015 /* 36905184Sek110237 * Searches the attribute list for the command for the named attribute type. 36915184Sek110237 * The attribute list is created by the parser from the list of attributes 36925184Sek110237 * supplied with certain commands, such as the define and flowop commands. 36935184Sek110237 * Returns a pointer to the attribute structure if the named attribute is 36945184Sek110237 * found, otherwise returns NULL. If the attribute includes a parameter list, 36956212Saw148015 * the list is converted to a string and stored in the attr_avd field of 36965184Sek110237 * the returned attr_t struct. 36975184Sek110237 */ 36985184Sek110237 static attr_t * 36995184Sek110237 get_attr(cmd_t *cmd, int64_t name) 37005184Sek110237 { 37015184Sek110237 attr_t *attr; 37025184Sek110237 attr_t *rtn = NULL; 37035184Sek110237 char *string; 37045184Sek110237 37055184Sek110237 for (attr = cmd->cmd_attr_list; attr != NULL; 37065184Sek110237 attr = attr->attr_next) { 37075184Sek110237 filebench_log(LOG_DEBUG_IMPL, 37085184Sek110237 "attr %d = %d %llx?", 37095184Sek110237 attr->attr_name, 37105184Sek110237 name, 37116212Saw148015 attr->attr_avd); 37125184Sek110237 37135184Sek110237 if (attr->attr_name == name) 37145184Sek110237 rtn = attr; 37155184Sek110237 } 37165184Sek110237 37175184Sek110237 if (rtn == NULL) 37185184Sek110237 return (NULL); 37195184Sek110237 37205184Sek110237 if (rtn->attr_param_list) { 37215184Sek110237 filebench_log(LOG_DEBUG_SCRIPT, "attr is param list"); 37225184Sek110237 string = parser_list2string(rtn->attr_param_list); 37235184Sek110237 if (string != NULL) { 37246212Saw148015 rtn->attr_avd = avd_str_alloc(string); 37255184Sek110237 filebench_log(LOG_DEBUG_SCRIPT, 37265184Sek110237 "attr string %s", string); 37275184Sek110237 } 37285184Sek110237 } 37295184Sek110237 37305184Sek110237 return (rtn); 37315184Sek110237 } 37325184Sek110237 37335184Sek110237 /* 37345184Sek110237 * Similar to get_attr, but converts the parameter string supplied with the 37356212Saw148015 * named attribute to an integer and stores the integer in the attr_avd 37365184Sek110237 * portion of the returned attr_t struct. 37375184Sek110237 */ 37385184Sek110237 static attr_t * 37395184Sek110237 get_attr_integer(cmd_t *cmd, int64_t name) 37405184Sek110237 { 37415184Sek110237 attr_t *attr; 37425184Sek110237 attr_t *rtn = NULL; 37435184Sek110237 37445184Sek110237 for (attr = cmd->cmd_attr_list; attr != NULL; 37455184Sek110237 attr = attr->attr_next) { 37465184Sek110237 if (attr->attr_name == name) 37475184Sek110237 rtn = attr; 37485184Sek110237 } 37495184Sek110237 37505184Sek110237 if (rtn == NULL) 37515184Sek110237 return (NULL); 37525184Sek110237 37536212Saw148015 if (rtn->attr_param_list) 37546212Saw148015 rtn->attr_avd = parser_list2avd(rtn->attr_param_list); 37555184Sek110237 37565184Sek110237 return (rtn); 37575184Sek110237 } 37585184Sek110237 37595184Sek110237 /* 37605184Sek110237 * Similar to get_attr, but converts the parameter string supplied with the 37616212Saw148015 * named attribute to an integer and stores the integer in the attr_avd 37625184Sek110237 * portion of the returned attr_t struct. If no parameter string is supplied 37635184Sek110237 * then it defaults to TRUE (1). 37645184Sek110237 */ 37655184Sek110237 static attr_t * 37665184Sek110237 get_attr_bool(cmd_t *cmd, int64_t name) 37675184Sek110237 { 37685184Sek110237 attr_t *attr; 37695184Sek110237 attr_t *rtn = NULL; 37705184Sek110237 37715184Sek110237 for (attr = cmd->cmd_attr_list; attr != NULL; 37725184Sek110237 attr = attr->attr_next) { 37735184Sek110237 if (attr->attr_name == name) 37745184Sek110237 rtn = attr; 37755184Sek110237 } 37765184Sek110237 37775184Sek110237 if (rtn == NULL) 37785184Sek110237 return (NULL); 37795184Sek110237 37805184Sek110237 if (rtn->attr_param_list) { 37816212Saw148015 rtn->attr_avd = parser_list2avd(rtn->attr_param_list); 37826212Saw148015 37836212Saw148015 } else if (rtn->attr_avd == NULL) { 37846212Saw148015 rtn->attr_avd = avd_bool_alloc(TRUE); 37856212Saw148015 } 37866212Saw148015 37876212Saw148015 /* boolean attributes cannot point to random variables */ 37886212Saw148015 if (AVD_IS_RANDOM(rtn->attr_avd)) { 37896212Saw148015 filebench_log(LOG_ERROR, 37906212Saw148015 "define flowop: Boolean attr %s cannot be random", name); 37916212Saw148015 filebench_shutdown(1); 37926212Saw148015 return (NULL); 37935184Sek110237 } 37945184Sek110237 37955184Sek110237 return (rtn); 37965184Sek110237 } 37975184Sek110237 37985184Sek110237 /* 37996550Saw148015 * removes the newly allocated local var from the shared local var 38006550Saw148015 * list, then puts it at the head of the private local var list 38016550Saw148015 * supplied as the second argument. 38026550Saw148015 */ 38036550Saw148015 static void 38046550Saw148015 add_lvar_to_list(var_t *newlvar, var_t **lvar_list) 38056550Saw148015 { 38066550Saw148015 var_t *prev; 38076550Saw148015 38086550Saw148015 /* remove from shared local list, if there */ 38096550Saw148015 if (newlvar == filebench_shm->shm_var_loc_list) { 38106550Saw148015 /* on top of list, just grap */ 38116550Saw148015 filebench_shm->shm_var_loc_list = newlvar->var_next; 38126550Saw148015 } else { 38136550Saw148015 /* find newvar on list and remove */ 38146550Saw148015 for (prev = filebench_shm->shm_var_loc_list; prev; 38156550Saw148015 prev = prev->var_next) { 38166550Saw148015 if (prev->var_next == newlvar) 38176550Saw148015 prev->var_next = newlvar->var_next; 38186550Saw148015 } 38196550Saw148015 } 38206550Saw148015 newlvar->var_next = NULL; 38216550Saw148015 38226550Saw148015 /* add to flowop private local list at head */ 38236550Saw148015 newlvar->var_next = *lvar_list; 38246550Saw148015 *lvar_list = newlvar; 38256550Saw148015 } 38266550Saw148015 38276550Saw148015 /* 38286550Saw148015 * Searches the attribute list for the command for any allocated local 38296550Saw148015 * variables. The attribute list is created by the parser from the list of 38306550Saw148015 * attributes supplied with certain commands, such as the define and flowop 38316550Saw148015 * commands. Places all found local vars onto the flowop's local variable 38326550Saw148015 * list. 38336550Saw148015 */ 38346550Saw148015 static void 38356550Saw148015 get_attr_lvars(cmd_t *cmd, flowop_t *flowop) 38366550Saw148015 { 38376550Saw148015 attr_t *attr; 38386550Saw148015 var_t *list_tail, *orig_lvar_list; 38396550Saw148015 38406550Saw148015 /* save the local var list */ 38416550Saw148015 orig_lvar_list = flowop->fo_lvar_list; 38426550Saw148015 38436550Saw148015 for (attr = cmd->cmd_attr_list; attr != NULL; 38446550Saw148015 attr = attr->attr_next) { 38456550Saw148015 38466550Saw148015 if (attr->attr_name == FSA_LVAR_ASSIGN) { 38476550Saw148015 var_t *newvar, *prev; 38486550Saw148015 38496550Saw148015 if ((newvar = (var_t *)attr->attr_avd) == NULL) 38506550Saw148015 continue; 38516550Saw148015 38526550Saw148015 add_lvar_to_list(newvar, &flowop->fo_lvar_list); 38536550Saw148015 var_update_comp_lvars(newvar, orig_lvar_list, NULL); 38546550Saw148015 } 38556550Saw148015 } 38566550Saw148015 } 38576550Saw148015 38586550Saw148015 /* 38595184Sek110237 * Allocates memory for a list_t structure, initializes it to zero, and 38605184Sek110237 * returns a pointer to it. On failure, returns NULL. 38615184Sek110237 */ 38625184Sek110237 static list_t * 38635184Sek110237 alloc_list() 38645184Sek110237 { 38655184Sek110237 list_t *list; 38665184Sek110237 38675184Sek110237 if ((list = malloc(sizeof (list_t))) == NULL) { 38685184Sek110237 return (NULL); 38695184Sek110237 } 38705184Sek110237 38715184Sek110237 (void) memset(list, 0, sizeof (list_t)); 38725184Sek110237 return (list); 38735184Sek110237 } 38745184Sek110237 38755184Sek110237 38765184Sek110237 #define USAGE1 \ 38775184Sek110237 "Usage:\n" \ 38786613Sek110237 "go_filebench: interpret f script and generate file workload\n" \ 38795184Sek110237 "Options:\n" \ 38805184Sek110237 " [-h] Display verbose help\n" \ 38815184Sek110237 " [-p] Disable opening /proc to set uacct to enable truss\n" 38825184Sek110237 38835184Sek110237 #define PARSER_CMDS \ 38845184Sek110237 "create [files|filesets|processes]\n" \ 38855184Sek110237 "stats [clear|snap]\n" \ 38865184Sek110237 "stats command \"shell command $var1,$var2...\"\n" \ 38875184Sek110237 "stats directory <directory>\n" \ 38885184Sek110237 "sleep <sleep-value>\n" \ 38895184Sek110237 "quit\n\n" \ 38905184Sek110237 "Variables:\n" \ 38915184Sek110237 "set $var = value\n" \ 38925184Sek110237 " $var - regular variables\n" \ 38935184Sek110237 " ${var} - internal special variables\n" \ 38945184Sek110237 " $(var) - environment variables\n\n" 38955184Sek110237 38965184Sek110237 #define PARSER_EXAMPLE \ 38975184Sek110237 "Example:\n\n" \ 38986613Sek110237 "#!" FILEBENCHDIR "/bin/go_filebench -f\n" \ 38995184Sek110237 "\n" \ 39005184Sek110237 "define file name=bigfile,path=bigfile,size=1g,prealloc,reuse\n" \ 39015184Sek110237 "define process name=randomizer\n" \ 39025184Sek110237 "{\n" \ 39035184Sek110237 " thread random-thread procname=randomizer\n" \ 39045184Sek110237 " {\n" \ 39055184Sek110237 " flowop read name=random-read,filename=bigfile,iosize=16k,random\n" \ 39065184Sek110237 " }\n" \ 39075184Sek110237 "}\n" \ 39085184Sek110237 "create files\n" \ 39095184Sek110237 "create processes\n" \ 39105184Sek110237 "stats clear\n" \ 39115184Sek110237 "sleep 30\n" \ 39125184Sek110237 "stats snap\n" 39135184Sek110237 39145184Sek110237 /* 39155184Sek110237 * usage() display brief or verbose help for the filebench(1) command. 39165184Sek110237 */ 39175184Sek110237 static void 39185184Sek110237 usage(int help) 39195184Sek110237 { 39205184Sek110237 if (help >= 1) 39215184Sek110237 (void) fprintf(stderr, USAGE1, cmdname); 39225184Sek110237 if (help >= 2) { 39235184Sek110237 39245184Sek110237 (void) fprintf(stderr, 39255184Sek110237 "\n'f' language definition:\n\n"); 39265184Sek110237 fileset_usage(); 39275184Sek110237 procflow_usage(); 39285184Sek110237 threadflow_usage(); 39295184Sek110237 flowoplib_usage(); 39305184Sek110237 eventgen_usage(); 39315184Sek110237 (void) fprintf(stderr, PARSER_CMDS); 39325184Sek110237 (void) fprintf(stderr, PARSER_EXAMPLE); 39335184Sek110237 } 39345184Sek110237 exit(E_USAGE); 39355184Sek110237 } 39365184Sek110237 39375184Sek110237 int 39385184Sek110237 yywrap() 39395184Sek110237 { 39405184Sek110237 char buf[1024]; 39415184Sek110237 39425184Sek110237 if (parentscript) { 39435184Sek110237 yyin = parentscript; 39445184Sek110237 yy_switchfilescript(yyin); 39455184Sek110237 parentscript = NULL; 39465184Sek110237 return (0); 39475184Sek110237 } else 39485184Sek110237 return (1); 39495184Sek110237 } 3950