summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-05-05 16:53:20 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2014-05-05 16:53:20 +0000
commit87bf334d63e1ada54994c96af1e24a03a996e14f (patch)
tree9c61d8c6c0fe8f6c313f93414cbd53f18f3059f1
parent31c8acea680780c5223a2dd598f57536a0709f5d (diff)
parentf93d2c191d5ef071436181338612f79b8daa751c (diff)
downloadillumos-joyent-87bf334d63e1ada54994c96af1e24a03a996e14f.tar.gz
[illumos-gate merge]
commit f93d2c191d5ef071436181338612f79b8daa751c 1784 zone configuration passes zonecfg but not zoneadm for limitpriv property commit 14b7b4606a1faf7fc4c0bbcc2946782d6538850e 4838 Fix for 4596 has some inverted booleans commit d05b42383f649c1384ae2af878515cc2c6674ec6 4821 remove filebench Conflicts: usr/src/cmd/zonecfg/zonecfg.c
-rw-r--r--usr/src/Makefile.lint1
-rw-r--r--usr/src/cmd/Makefile1
-rw-r--r--usr/src/cmd/filebench/Makefile58
-rw-r--r--usr/src/cmd/filebench/Makefile.com107
-rw-r--r--usr/src/cmd/filebench/amd64/Makefile39
-rw-r--r--usr/src/cmd/filebench/common/auto_comp.c1046
-rw-r--r--usr/src/cmd/filebench/common/auto_comp.h43
-rw-r--r--usr/src/cmd/filebench/common/config.h86
-rw-r--r--usr/src/cmd/filebench/common/eventgen.c199
-rw-r--r--usr/src/cmd/filebench/common/eventgen.h49
-rw-r--r--usr/src/cmd/filebench/common/fb_avl.c1064
-rw-r--r--usr/src/cmd/filebench/common/fb_avl.h423
-rw-r--r--usr/src/cmd/filebench/common/fb_localfs.c697
-rw-r--r--usr/src/cmd/filebench/common/fb_random.c437
-rw-r--r--usr/src/cmd/filebench/common/fb_random.h116
-rw-r--r--usr/src/cmd/filebench/common/filebench.h154
-rw-r--r--usr/src/cmd/filebench/common/fileset.c1980
-rw-r--r--usr/src/cmd/filebench/common/fileset.h199
-rw-r--r--usr/src/cmd/filebench/common/flowop.c1210
-rw-r--r--usr/src/cmd/filebench/common/flowop.h175
-rw-r--r--usr/src/cmd/filebench/common/flowop_library.c2712
-rw-r--r--usr/src/cmd/filebench/common/fsplug.h148
-rw-r--r--usr/src/cmd/filebench/common/gamma_dist.c142
-rw-r--r--usr/src/cmd/filebench/common/gamma_dist.h43
-rw-r--r--usr/src/cmd/filebench/common/ipc.c862
-rw-r--r--usr/src/cmd/filebench/common/ipc.h250
-rw-r--r--usr/src/cmd/filebench/common/misc.c490
-rw-r--r--usr/src/cmd/filebench/common/misc.h76
-rw-r--r--usr/src/cmd/filebench/common/multi_client_sync.c111
-rw-r--r--usr/src/cmd/filebench/common/multi_client_sync.h36
-rw-r--r--usr/src/cmd/filebench/common/parser_gram.y4580
-rw-r--r--usr/src/cmd/filebench/common/parser_lex.l365
-rw-r--r--usr/src/cmd/filebench/common/parsertypes.h99
-rw-r--r--usr/src/cmd/filebench/common/procflow.c784
-rw-r--r--usr/src/cmd/filebench/common/procflow.h65
-rw-r--r--usr/src/cmd/filebench/common/stats.c905
-rw-r--r--usr/src/cmd/filebench/common/stats.h85
-rw-r--r--usr/src/cmd/filebench/common/threadflow.c458
-rw-r--r--usr/src/cmd/filebench/common/threadflow.h120
-rw-r--r--usr/src/cmd/filebench/common/utils.c128
-rw-r--r--usr/src/cmd/filebench/common/utils.h54
-rw-r--r--usr/src/cmd/filebench/common/vars.c1887
-rw-r--r--usr/src/cmd/filebench/common/vars.h268
-rw-r--r--usr/src/cmd/filebench/config/Makefile50
-rw-r--r--usr/src/cmd/filebench/config/fileio.prof125
-rw-r--r--usr/src/cmd/filebench/config/filemacro.prof129
-rw-r--r--usr/src/cmd/filebench/config/filemicro.prof143
-rw-r--r--usr/src/cmd/filebench/config/generic.func72
-rw-r--r--usr/src/cmd/filebench/config/multi_fileserver.prof52
-rw-r--r--usr/src/cmd/filebench/config/newfeatures.prof101
-rw-r--r--usr/src/cmd/filebench/config/randomread.prof41
-rw-r--r--usr/src/cmd/filebench/config/seqread.prof41
-rw-r--r--usr/src/cmd/filebench/config/videoserver.prof43
-rw-r--r--usr/src/cmd/filebench/fbscript/Makefile47
-rwxr-xr-xusr/src/cmd/filebench/fbscript/filebench.pl1189
-rw-r--r--usr/src/cmd/filebench/i386/Makefile38
-rw-r--r--usr/src/cmd/filebench/scripts/Makefile47
-rwxr-xr-xusr/src/cmd/filebench/scripts/filebench_compare.pl250
-rwxr-xr-xusr/src/cmd/filebench/scripts/fs_flush.pl116
-rw-r--r--usr/src/cmd/filebench/sparcv9/Makefile39
-rw-r--r--usr/src/cmd/filebench/workloads/Makefile95
-rw-r--r--usr/src/cmd/filebench/workloads/bringover.f58
-rw-r--r--usr/src/cmd/filebench/workloads/compflow_demo.f85
-rw-r--r--usr/src/cmd/filebench/workloads/copyfiles.f58
-rw-r--r--usr/src/cmd/filebench/workloads/createfiles.f56
-rw-r--r--usr/src/cmd/filebench/workloads/deletefiles.f54
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_create.f54
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_createfiles.f65
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_createrand.f59
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_delete.f63
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_rread.f58
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_rwrite.f60
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_rwritedsync.f56
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_rwritefsync.f60
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_seqread.f52
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_seqwrite.f57
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_seqwriterand.f57
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_seqwriterandvargam.f62
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_seqwriterandvartab.f65
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_statfile.f55
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_writefsync.f56
-rw-r--r--usr/src/cmd/filebench/workloads/fileserver.f64
-rw-r--r--usr/src/cmd/filebench/workloads/listdirs.f50
-rw-r--r--usr/src/cmd/filebench/workloads/makedirs.f51
-rw-r--r--usr/src/cmd/filebench/workloads/mongo.f63
-rw-r--r--usr/src/cmd/filebench/workloads/multistreamread.f70
-rw-r--r--usr/src/cmd/filebench/workloads/multistreamreaddirect.f68
-rw-r--r--usr/src/cmd/filebench/workloads/multistreamwrite.f70
-rw-r--r--usr/src/cmd/filebench/workloads/multistreamwritedirect.f67
-rw-r--r--usr/src/cmd/filebench/workloads/networkfs.f131
-rw-r--r--usr/src/cmd/filebench/workloads/oltp.f117
-rw-r--r--usr/src/cmd/filebench/workloads/openfiles.f51
-rw-r--r--usr/src/cmd/filebench/workloads/randomfileaccess.f89
-rw-r--r--usr/src/cmd/filebench/workloads/randomread.f60
-rw-r--r--usr/src/cmd/filebench/workloads/randomrw.f65
-rw-r--r--usr/src/cmd/filebench/workloads/randomwrite.f60
-rw-r--r--usr/src/cmd/filebench/workloads/ratelimcopyfiles.f81
-rw-r--r--usr/src/cmd/filebench/workloads/removedirs.f51
-rw-r--r--usr/src/cmd/filebench/workloads/singlestreamread.f53
-rw-r--r--usr/src/cmd/filebench/workloads/singlestreamreaddirect.f51
-rw-r--r--usr/src/cmd/filebench/workloads/singlestreamwrite.f49
-rw-r--r--usr/src/cmd/filebench/workloads/singlestreamwritedirect.f47
-rw-r--r--usr/src/cmd/filebench/workloads/tpcso.f268
-rw-r--r--usr/src/cmd/filebench/workloads/varmail.f70
-rw-r--r--usr/src/cmd/filebench/workloads/videoserver.f87
-rw-r--r--usr/src/cmd/filebench/workloads/webproxy.f74
-rw-r--r--usr/src/cmd/filebench/workloads/webserver.f82
-rw-r--r--usr/src/cmd/zonecfg/zonecfg.c15
-rw-r--r--usr/src/man/man1/Makefile1
-rw-r--r--usr/src/man/man1/filebench.1175
-rw-r--r--usr/src/pkg/manifests/benchmark-filebench.mf91
-rw-r--r--usr/src/uts/common/inet/ip/icmp.c4
-rw-r--r--usr/src/uts/common/inet/udp/udp.c6
113 files changed, 21 insertions, 28820 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index 96faacb9e9..f94ec8f84c 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -129,7 +129,6 @@ COMMON_SUBDIRS = \
cmd/fdisk \
cmd/fgrep \
cmd/file \
- cmd/filebench \
cmd/find \
cmd/fmthard \
cmd/fmtmsg \
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index fcd087bae6..e1725a776b 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -157,7 +157,6 @@ COMMON_SUBDIRS= \
filesync \
fgrep \
file \
- filebench \
find \
flowadm \
flowstat \
diff --git a/usr/src/cmd/filebench/Makefile b/usr/src/cmd/filebench/Makefile
deleted file mode 100644
index fd2294c39f..0000000000
--- a/usr/src/cmd/filebench/Makefile
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.cmd
-
-SUBDIRS = \
- config \
- fbscript \
- scripts \
- workloads
-
-$(64ONLY)SUBDIRS += $(MACH)
-$(BUILD64)SUBDIRS += $(MACH64)
-
-PROG = go_filebench
-ROOTCMDDIR = $(ROOT)/usr/benchmarks/filebench/bin
-
-.KEEP_STATE:
-
-all := TARGET = all
-clean := TARGET = clean
-clobber := TARGET = clobber
-install := TARGET = install
-lint := TARGET = lint
-
-all clean clobber lint: $(SUBDIRS)
-
-install: $(SUBDIRS)
- -$(RM) $(ROOTCMD)
- -$(LN) $(ISAEXEC) $(ROOTCMD)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
diff --git a/usr/src/cmd/filebench/Makefile.com b/usr/src/cmd/filebench/Makefile.com
deleted file mode 100644
index 0f0a51c654..0000000000
--- a/usr/src/cmd/filebench/Makefile.com
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-.KEEP_STATE:
-
-include ../../Makefile.cmd
-include ../../Makefile.targ
-
-SRCS = \
- auto_comp.c \
- eventgen.c \
- fb_avl.c \
- fb_localfs.c \
- fb_random.c \
- fileset.c \
- flowop.c \
- flowop_library.c \
- gamma_dist.c \
- ipc.c \
- misc.c \
- multi_client_sync.c \
- procflow.c \
- stats.c \
- threadflow.c \
- utils.c \
- vars.c
-
-PROG = go_filebench
-ROOTFBBINDIR = $(ROOT)/usr/benchmarks/filebench/bin
-OBJS = $(SRCS:%.c=%.o) parser_gram.o parser_lex.o
-LINTFLAGS += -erroff=E_FUNC_ARG_UNUSED -erroff=E_NAME_DEF_NOT_USED2 \
- -erroff=E_NAME_USED_NOT_DEF2 -erroff=E_INCONS_ARG_DECL2
-LINTFLAGS64 += -erroff=E_FUNC_ARG_UNUSED -erroff=E_NAME_DEF_NOT_USED2 \
- -erroff=E_NAME_USED_NOT_DEF2 -erroff=E_INCONS_ARG_DECL2
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-unused-function
-
-LINTFILES = $(SRCS:%.c=%.ln)
-CLEANFILES += parser_gram.c parser_gram.h parser_lex.c y.tab.h y.tab.c
-
-CPPFLAGS += -I. -I../common
-CFLAGS += $(CCVERBOSE) $(CTF_FLAGS)
-CFLAGS64 += $(CCVERBOSE) $(CTF_FLAGS)
-LDLIBS += -lkstat -lm -ltecla -lsocket -lnsl
-
-LFLAGS = -t -v
-YFLAGS = -d
-
-.PARALLEL: $(OBJS) $(LINTFILES)
-
-all: $(PROG)
-
-$(PROG): $(OBJS)
- $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
- $(CTFMERGE) -L VERSION -o $@ $(OBJS)
- $(POST_PROCESS)
-
-parser_lex.c: ../common/parser_lex.l
- $(FLEX) $(LFLAGS) ../common/parser_lex.l > $@
-
-parser_gram.c: ../common/parser_gram.y
- $(YACC) $(YFLAGS) ../common/parser_gram.y
- $(MV) y.tab.c parser_gram.c
- $(MV) y.tab.h parser_gram.h
-
-%.o: %.c
- $(COMPILE.c) $<
- $(CTFCONVERT_O)
-
-%.o: ../common/%.c
- $(COMPILE.c) $<
- $(CTFCONVERT_O)
-
-clean:
- $(RM) $(OBJS) $(LINTFILES) $(CLEANFILES)
-
-%.ln: ../common/%.c
- $(LINT.c) -c $<
-
-lint: $(LINTFILES)
- $(LINT.c) $(LINTFILES) $(LDLIBS)
diff --git a/usr/src/cmd/filebench/amd64/Makefile b/usr/src/cmd/filebench/amd64/Makefile
deleted file mode 100644
index 8dd1d0d4be..0000000000
--- a/usr/src/cmd/filebench/amd64/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.com
-include ../../Makefile.cmd.64
-
-FBBINDIRamd64 = $(ROOTFBBINDIR)/amd64
-PROGamd64 = $(PROG:%=$(FBBINDIRamd64)/%)
-
-$(FBBINDIRamd64):
- $(INS.dir)
-
-$(FBBINDIRamd64)/%: %
- $(INS.file)
-
-install: all .WAIT $(FBBINDIRamd64) .WAIT $(PROGamd64)
diff --git a/usr/src/cmd/filebench/common/auto_comp.c b/usr/src/cmd/filebench/common/auto_comp.c
deleted file mode 100644
index f8a6df1b55..0000000000
--- a/usr/src/cmd/filebench/common/auto_comp.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-#include <dirent.h>
-#include <strings.h>
-
-#include "filebench.h"
-#include "auto_comp.h"
-
-#define VARNAME_MAXLEN 128
-#define FILENAME_MAXLEN 128
-#define MALLOC_STEP 64
-
-#define CSUF_CMD " "
-#define CSUF_ARG " "
-#define CSUF_LVARNAME "="
-#define CSUF_RVARNAME ","
-#define CSUF_ATTRNAME "="
-
-#define ATTR_LIST_SEP ','
-#define ATTR_ASSIGN_OP '='
-#define VAR_ASSIGN_OP '='
-#define VAR_PREFIX '$'
-
-typedef char ac_fname_t[FILENAME_MAXLEN];
-
-typedef struct ac_fname_cache {
- ac_fname_t *fnc_buf;
- int fnc_bufsize;
- time_t fnc_mtime;
-} ac_fname_cache_t;
-
-typedef enum ac_match_result {
- MATCH_DONE,
- MATCH_CONT
-} ac_match_result_t;
-
-/*
- * We parse an user input line into multiple blank separated strings.
- * The last string is always the one user wants to complete, the other
- * preceding strings set up the context on how to complete the last one.
- *
- * ac_str_t repsents one such a string, which can be of the following
- * types:
- *
- * STRTYPE_COMPLETE - the string is one of the preceding strings.
- * STRTYPE_INCOMPLETE - the string is the one being completed, user
- * has inputted at least one character for it.
- * STRTYPE_NULL - the string is the one being completed, user
- * has inputted nothing for it.
- *
- * ac_str_t structure has the following members:
- *
- * startp - the start position of the string in the user input buffer
- * endp - the end position of the string in the user input buffer
- * strtype - the type of the string. It can be of the following values:
- * STRTYPE_COMPLETE, STRTYPE_INCOMPLETE, STRTYPE_NULL,
- * and STRTYPE_INVALID.
- */
-
-typedef enum ac_strtype {
- STRTYPE_COMPLETE,
- STRTYPE_INCOMPLETE,
- STRTYPE_NULL,
- STRTYPE_INVALID
-} ac_strtype_t;
-
-typedef struct ac_str {
- const char *startp;
- const char *endp;
- ac_strtype_t strtype;
-} ac_str_t;
-
-#define STR_NUM 3
-
-typedef struct ac_inputline {
- ac_str_t strs[STR_NUM];
-} ac_inputline_t;
-
-/*
- * ac_iter represents a general interface to access a list of values for
- * matching user input string. The structure has the following methods:
- *
- * bind - bind the iterator to a list, and save a pointer to user
- * passed space in nlistpp.
- * reset - reset internal index pointer to point to list head.
- * get_nextstr - this is the method that does the real work. It
- * walks through the list and returns string associated with
- * the current item. It can also return some other thing the
- * caller is interested via the user passed space pointed by
- * nlistpp. In our case, that is a pointer to a list which
- * contains all possible values for the next string in user
- * input.
- *
- * It has the following data members:
- *
- * listp - a pointer to the list to be iterated through
- * curp - index pointer to maintain position when iterating
- * nlistpp - a pointer to user passed space for returning a list of
- * values for the next string in user input
- */
-
-typedef struct ac_iter {
- void *listp;
- void *curp;
- void *nlistpp;
- void (*bind)(struct ac_iter *, void *, void *);
- void (*reset)(struct ac_iter *);
- const char *(*get_nextstr)(struct ac_iter *);
-} ac_iter_t;
-
-/*
- * We consider a filebench command is composed of a sequence of tokens
- * (ie., command name, argument name, attribute name, etc.). Many of
- * these tokens have limited string values. These values, as well as
- * their dependencies, are used to complete user input string.
- *
- * There are the following tokens:
- *
- * TOKTYPE_CMD - command name
- * TOKTYPE_ARG - argument name
- * TOKTYPE_ATTRNAME - attribute name
- * TOKTYPE_ATTRVAL - attribute value
- * TOKTYPE_LVARNAME - variable name, used on left side of assign
- * operator
- * TOKTYPE_RVARNAME - variable name, used on right side of assign
- * operator
- * TOKTYPE_VARVAL - variable value
- * TOKTYPE_LOADFILE - load file name
- * TOKTYPE_ATTRLIST - pseudo token type for attribute list
- * TOKTYPE_VARLIST - pseudo token type for variable list
- * TOKTYPE_NULL - pseudo token type for aborting auto-completion
- *
- * The reason why there are two different token types for variable name
- * is because, depending on its position, there are different requirements
- * on how to do completion and display matching results. See more details
- * in lvarname_iter and rvarname_iter definition.
- *
- * Attribute list and variable list are not really a single token. Instead
- * they contain multiple tokens, and thus have different requirements on
- * how to complete them. TOKTYPE_ATTRLIST and TOKTYPE_VARLIST are
- * introduced to to solve this issue. See more details below on
- * get_curtok() function in ac_tokinfo_t structure.
- *
- * ac_tokval_t represents a string value a token can have. The structure
- * also contains a pointer to a ac_tvlist_t structure, which represents
- * all possible values for the next token in the same command.
- *
- * str - the token's string value
- * nlistp - a list which contains string values for the token
- * that follows
- *
- * ac_tvlist_t represents all possible values for a token. These values
- * are stored in an ac_tokval_t array. The structure also has a member
- * toktype, which is used to index an ac_tokinfo_t array to get the
- * information on how to access and use the associated value list.
- *
- * vals - a list of string values for this token
- * toktype - the token's type
- *
- * ac_tokinfo_t contains information on how to access and use the
- * string values of a specific token. Among them, the most important
- * thing is an iterator to access the value list. The reason to use
- * iterator is to encapsulate list implementation details. That is
- * necessary because some tokens have dynamic values(for example,
- * argument of load command), which cannot be predefined using
- * ac_tokval_t array.
- *
- * ac_tokinfo_t structure has the following members:
- *
- * toktype - token type
- * iter - iterator to access the token's value list
- * cont_suffix - continuation suffix for this token. See note 1
- * below on what is continuation suffix.
- * get_curtok - a function to parse a multi-token user string.
- * It parse that string and returns the word being
- * completed and its token type. See note 2 below.
- *
- * Notes:
- *
- * 1) Continuation suffix is a convenient feature provided by libtecla.
- * A continuation suffix is a string which is automatically appended
- * to a fully completed string. For example, if a command name is
- * fully completed, a blank space will be appended to it. This is
- * very convenient because it not only saves typing, but also gives
- * user an indication to continue.
- *
- * 2) get_curtok() function is a trick to support user input strings
- * which have multiple tokens. Take attribute list as an example,
- * although we defined a token type TOKTYPE_ATTRLIST for it, it is
- * not a token actually, instead it contains multiple tokens like
- * attribute name, attribute value, etc., and attribute value can
- * be either a literal string or a variable name prefixed with a
- * '$' sign. For this reason, get_curtok() function is needed to
- * parse that string to get the word being completed and its token
- * type so that we can match the word against with the proper value
- * list.
- */
-
-typedef enum ac_toktype {
- TOKTYPE_CMD,
- TOKTYPE_ARG,
- TOKTYPE_ATTRNAME,
- TOKTYPE_ATTRVAL,
- TOKTYPE_LVARNAME,
- TOKTYPE_RVARNAME,
- TOKTYPE_VARVAL,
- TOKTYPE_LOADFILE,
- TOKTYPE_ATTRLIST,
- TOKTYPE_VARLIST,
- TOKTYPE_NULL
-} ac_toktype_t;
-
-typedef ac_toktype_t (*ac_get_curtok_func_t)(ac_str_t *);
-
-typedef struct ac_tokinfo {
- ac_toktype_t toktype;
- ac_iter_t *iter;
- char *cont_suffix;
- ac_get_curtok_func_t get_curtok;
-} ac_tokinfo_t;
-
-typedef struct ac_tokval {
- char *str;
- struct ac_tvlist *nlistp;
-} ac_tokval_t;
-
-typedef struct ac_tvlist {
- ac_tokval_t *vals;
- ac_toktype_t toktype;
-} ac_tvlist_t;
-
-/*
- * Variables and prototypes
- */
-
-static void common_bind(ac_iter_t *, void *, void *);
-static void common_reset(ac_iter_t *);
-static void varname_bind(ac_iter_t *, void *, void *);
-static void loadfile_bind(ac_iter_t *, void *, void *);
-static const char *get_next_tokval(ac_iter_t *);
-static const char *get_next_lvarname(ac_iter_t *);
-static const char *get_next_rvarname(ac_iter_t *);
-static const char *get_next_loadfile(ac_iter_t *);
-static ac_toktype_t parse_attr_list(ac_str_t *);
-static ac_toktype_t parse_var_list(ac_str_t *);
-
-static ac_iter_t tokval_iter = {
- NULL,
- NULL,
- NULL,
- common_bind,
- common_reset,
- get_next_tokval
-};
-
-static ac_iter_t lvarname_iter = {
- NULL,
- NULL,
- NULL,
- varname_bind,
- common_reset,
- get_next_lvarname
-};
-
-static ac_iter_t rvarname_iter = {
- NULL,
- NULL,
- NULL,
- varname_bind,
- common_reset,
- get_next_rvarname
-};
-
-static ac_iter_t loadfile_iter = {
- NULL,
- NULL,
- NULL,
- loadfile_bind,
- common_reset,
- get_next_loadfile
-};
-
-/*
- * Note: We use toktype to index into this array, so for each toktype,
- * there must be one element in the array, and in the same order
- * as that toktype is defined in ac_toktype.
- */
-static ac_tokinfo_t token_info[] = {
- { TOKTYPE_CMD, &tokval_iter, CSUF_CMD, NULL },
- { TOKTYPE_ARG, &tokval_iter, CSUF_ARG, NULL },
- { TOKTYPE_ATTRNAME, &tokval_iter, CSUF_ATTRNAME, NULL },
- { TOKTYPE_ATTRVAL, NULL, NULL, NULL },
- { TOKTYPE_LVARNAME, &lvarname_iter, CSUF_LVARNAME, NULL },
- { TOKTYPE_RVARNAME, &rvarname_iter, CSUF_RVARNAME, NULL },
- { TOKTYPE_VARVAL, NULL, NULL, NULL },
- { TOKTYPE_LOADFILE, &loadfile_iter, CSUF_ARG, NULL },
- { TOKTYPE_ATTRLIST, NULL, NULL, parse_attr_list },
- { TOKTYPE_VARLIST, NULL, NULL, parse_var_list },
- { TOKTYPE_NULL, NULL, NULL, NULL }
-};
-
-static ac_tokval_t event_attrnames[] = {
- { "rate", NULL},
- { NULL, NULL}
-};
-
-static ac_tvlist_t event_attrs = {
- event_attrnames,
- TOKTYPE_ATTRLIST
-};
-
-static ac_tokval_t file_attrnames[] = {
- { "path", NULL },
- { "reuse", NULL },
- { "prealloc", NULL },
- { "paralloc", NULL },
- { NULL, NULL }
-};
-
-static ac_tvlist_t file_attrs = {
- file_attrnames,
- TOKTYPE_ATTRLIST
-};
-
-static ac_tokval_t fileset_attrnames[] = {
- { "size", NULL },
- { "path", NULL },
- { "dirwidth", NULL },
- { "prealloc", NULL },
- { "filesizegamma", NULL },
- { "dirgamma", NULL },
- { "cached", NULL },
- { "entries", NULL },
- { NULL, NULL }
-};
-
-static ac_tvlist_t fileset_attrs = {
- fileset_attrnames,
- TOKTYPE_ATTRLIST
-};
-
-static ac_tokval_t process_attrnames[] = {
- { "nice", NULL },
- { "instances", NULL },
- { NULL, NULL }
-};
-
-static ac_tvlist_t process_attrs = {
- process_attrnames,
- TOKTYPE_ATTRLIST
-};
-
-static ac_tokval_t create_argnames[] = {
- { "file", NULL },
- { "fileset", NULL },
- { "process", NULL },
- { NULL, NULL }
-};
-
-static ac_tvlist_t create_args = {
- create_argnames,
- TOKTYPE_ARG
-};
-
-static ac_tokval_t define_argnames[] = {
- { "file", &file_attrs },
- { "fileset", &fileset_attrs },
- { "process", &process_attrs },
- { NULL, NULL }
-};
-
-static ac_tvlist_t define_args = {
- define_argnames,
- TOKTYPE_ARG
-};
-
-static ac_tvlist_t load_args = {
- NULL,
- TOKTYPE_LOADFILE
-};
-
-static ac_tvlist_t set_args = {
- NULL,
- TOKTYPE_VARLIST
-};
-
-static ac_tokval_t shutdown_argnames[] = {
- { "process", NULL },
- { NULL, NULL }
-};
-
-static ac_tvlist_t shutdown_args = {
- shutdown_argnames,
- TOKTYPE_ARG
-};
-
-static ac_tokval_t stats_argnames[] = {
- { "clear", NULL },
- { "directory", NULL },
- { "command", NULL },
- { "dump", NULL },
- { "xmldump", NULL },
- { NULL, NULL }
-};
-
-static ac_tvlist_t stats_args = {
- stats_argnames,
- TOKTYPE_ARG
-};
-
-static ac_tokval_t fb_cmdnames[] = {
- { "create", &create_args },
- { "define", &define_args },
- { "debug", NULL },
- { "echo", NULL },
- { "eventgen", &event_attrs },
- { "foreach", NULL },
- { "help", NULL },
- { "list", NULL },
- { "load", &load_args },
- { "log", NULL },
- { "quit", NULL },
- { "run", NULL },
- { "set", &set_args },
- { "shutdown", &shutdown_args },
- { "sleep", NULL },
- { "stats", &stats_args },
- { "system", NULL },
- { "usage", NULL },
- { "vars", NULL },
- { "version", NULL },
- { NULL, NULL },
-};
-
-static ac_tvlist_t fb_cmds = {
- fb_cmdnames,
- TOKTYPE_CMD
-};
-
-static ac_fname_cache_t loadnames = { NULL, 0, 0 };
-
-static int search_loadfiles(ac_fname_cache_t *);
-static void parse_user_input(const char *, int, ac_inputline_t *);
-static int compare_string(ac_str_t *, const char *, boolean_t, const char **);
-static ac_match_result_t match_string(WordCompletion *, const char *, int,
- ac_str_t *, ac_iter_t *, const char *);
-
-/*
- * Bind the iterator to the passed list
- */
-static void
-common_bind(ac_iter_t *iterp, void *listp, void *nlistpp)
-{
- iterp->listp = listp;
- iterp->nlistpp = nlistpp;
-}
-
-/*
- * Reset index pointer to point to list head
- */
-static void
-common_reset(ac_iter_t *iterp)
-{
- iterp->curp = iterp->listp;
-}
-
-/*
- * Walk through an array of ac_tokval_t structures and return string
- * of each item.
- */
-static const char *
-get_next_tokval(ac_iter_t *iterp)
-{
- ac_tokval_t *listp = iterp->listp; /* list head */
- ac_tokval_t *curp = iterp->curp; /* index pointer */
- /* user passed variable for returning value list for next token */
- ac_tvlist_t **nlistpp = iterp->nlistpp;
- const char *p;
-
- if (listp == NULL || curp == NULL)
- return (NULL);
-
- /* get the current item's string */
- p = curp->str;
-
- /*
- * save the current item's address into a user passed variable
- */
- if (nlistpp != NULL)
- *nlistpp = curp->nlistp;
-
- /* advance the index pointer */
- iterp->curp = ++curp;
-
- return (p);
-}
-
-/*
- * Bind the iterator to filebench_shm->shm_var_list
- */
-/* ARGSUSED */
-static void
-varname_bind(ac_iter_t *iterp, void *listp, void * nlistpp)
-{
- iterp->listp = filebench_shm->shm_var_list;
- iterp->nlistpp = nlistpp;
-}
-
-/*
- * Walk through a linked list of var_t type structures and return name
- * of each variable with a preceding '$' sign
- */
-static const char *
-get_next_lvarname(ac_iter_t *iterp)
-{
- static char buf[VARNAME_MAXLEN];
-
- var_t *listp = iterp->listp; /* list head */
- var_t *curp = iterp->curp; /* index pointer */
- /* User passed variable for returning value list for next token */
- ac_tvlist_t **nlistpp = iterp->nlistpp;
- const char *p;
-
- if (listp == NULL || curp == NULL)
- return (NULL);
-
- /* Get current variable's name, copy it to buf, with a '$' prefix */
- p = curp->var_name;
- (void) snprintf(buf, sizeof (buf), "$%s", p);
-
- /* No information for the next input string */
- if (nlistpp != NULL)
- *nlistpp = NULL;
-
- /* Advance the index pointer */
- iterp->curp = curp->var_next;
-
- return (buf);
-}
-
-/*
- * Walk through a linked list of var_t type structures and return name
- * of each variable
- */
-static const char *
-get_next_rvarname(ac_iter_t *iterp)
-{
- var_t *listp = iterp->listp; /* list head */
- var_t *curp = iterp->curp; /* index pointer */
- /* User passed variable for returning value list for next item */
- ac_tvlist_t **nlistpp = iterp->nlistpp;
- const char *p;
-
- if (listp == NULL || curp == NULL)
- return (NULL);
-
- /* Get current variable's name */
- p = curp->var_name;
-
- /* No information for the next input string */
- if (nlistpp != NULL)
- *nlistpp = NULL;
-
- /* Advance the index pointer */
- iterp->curp = curp->var_next;
-
- return (p);
-}
-
-/*
- * Bind the iterator to loadnames.fnc_buf, which is an ac_fname_t array
- * and contains up-to-date workload file names. The function calls
- * search_loadfiles() to update the cache before the binding.
- */
-/* ARGSUSED */
-static void
-loadfile_bind(ac_iter_t *iterp, void *listp, void * nlistpp)
-{
- /* Check loadfile name cache, update it if needed */
- (void) search_loadfiles(&loadnames);
-
- iterp->listp = loadnames.fnc_buf;
- iterp->nlistpp = nlistpp;
-}
-
-/*
- * Walk through a string(ac_fname_t, more exactly) array and return each
- * string, until a NULL iterm is encountered.
- */
-static const char *
-get_next_loadfile(ac_iter_t *iterp)
-{
- ac_fname_t *listp = iterp->listp; /* list head */
- ac_fname_t *curp = iterp->curp; /* index pointer */
- /* User passed variable for returning value list for next item */
- ac_tvlist_t **nlistpp = iterp->nlistpp;
- const char *p;
-
- if (listp == NULL || curp == NULL)
- return (NULL);
-
- /*
- * Get current file name. If an NULL item is encountered, it means
- * this is the end of the list. In that case, we need to set p to
- * NULL to indicate to the caller that the end of the list is reached.
- */
- p = (char *)curp;
- if (*p == NULL)
- p = NULL;
-
- /* No information for the next input string */
- if (nlistpp != NULL)
- *nlistpp = NULL;
-
- /* Advance the index pointer */
- iterp->curp = ++curp;
-
- return (p);
-}
-
-/*
- * Search for available workload files in workload direcotry and
- * update workload name cache.
- */
-static int
-search_loadfiles(ac_fname_cache_t *fnamecache)
-{
- DIR *dirp;
- struct dirent *fp;
- struct stat dstat;
- time_t mtime;
- ac_fname_t *buf;
- int bufsize = MALLOC_STEP;
- int len, i;
-
- if (stat(FILEBENCHDIR"/workloads", &dstat) != 0)
- return (-1);
- mtime = dstat.st_mtime;
-
- /* Return if there is no change since last time */
- if (mtime == fnamecache->fnc_mtime)
- return (0);
-
- /* Get loadfile names and cache it */
- if ((buf = malloc(sizeof (ac_fname_t) * bufsize)) == NULL)
- return (-1);
- if ((dirp = opendir(FILEBENCHDIR"/workloads")) == NULL)
- return (-1);
- i = 0;
- while ((fp = readdir(dirp)) != NULL) {
- len = strlen(fp->d_name);
- if (len <= 2 || (fp->d_name)[len - 2] != '.' ||
- (fp->d_name)[len - 1] != 'f')
- continue;
-
- if (i == bufsize) {
- bufsize += MALLOC_STEP;
- if ((buf = realloc(buf, sizeof (ac_fname_t) *
- bufsize)) == NULL)
- return (-1);
- }
-
- (void) snprintf(buf[i], FILENAME_MAXLEN, "%s", fp->d_name);
- if (len -2 <= FILENAME_MAXLEN - 1) {
- /* Remove .f suffix in file name */
- buf[i][len -2] = NULL;
- }
- i++;
- }
- /* Added a NULL iterm as the array's terminator */
- buf[i][0] = NULL;
-
- if (fnamecache->fnc_bufsize != 0)
- free(fnamecache->fnc_buf);
- fnamecache->fnc_buf = buf;
- fnamecache->fnc_bufsize = bufsize;
- fnamecache->fnc_mtime = mtime;
-
- return (0);
-}
-
-/*
- * Parse user input line into a list of blank separated strings, and
- * save the result in the passed ac_inputline_t structure. line and word_end
- * parameters are passed from libtecla library. line points to user input
- * buffer, and word_end is the index of the last character of user input.
- */
-/* ARGSUSED */
-static void
-parse_user_input(const char *line, int word_end, ac_inputline_t *input)
-{
- const char *p = line;
- int i;
-
- /* Reset all fileds */
- for (i = 0; i < STR_NUM; i++) {
- input->strs[i].startp = NULL;
- input->strs[i].endp = NULL;
- input->strs[i].strtype = STRTYPE_INVALID;
- }
-
- /*
- * Parse user input. We don't use word_end to do boundary checking,
- * instead we take advantage of the fact that the passed line
- * parameter is always terminated by '\0'.
- */
- for (i = 0; i < STR_NUM; i++) {
- /* Skip leading blank spaces */
- while (*p == ' ')
- p++;
-
- if (*p == NULL) {
- /*
- * User input nothing for the string being input
- * before he pressed TAB. We use STR_NULL flag
- * to indicate this so that match_str() will list
- * all available candidates.
- */
- input->strs[i].startp = p;
- input->strs[i].strtype = STRTYPE_NULL;
- return;
- }
-
- /* Recoard the start and end of the string */
- input->strs[i].startp = p;
- while ((*p != ' ') && (*p != NULL))
- p++;
- input->strs[i].endp = p - 1;
-
- if (*p == NULL) {
- input->strs[i].strtype = STRTYPE_INCOMPLETE;
- return;
- } else {
- /* The string is followed by a blank space */
- input->strs[i].strtype = STRTYPE_COMPLETE;
- }
- }
-}
-
-/*
- * Parse an input string which is an attribue list, get the current word
- * user wants to complete, and return its token type.
- *
- * An atribute list has the following format:
- *
- * name1=val,name2=$var,...
- *
- * The function modifies the passed acstr string on success to point to
- * the word being completed.
- */
-static ac_toktype_t
-parse_attr_list(ac_str_t *acstr)
-{
- const char *p;
-
- if (acstr->strtype == STRTYPE_COMPLETE) {
- /*
- * User has input a complete string for attribute list
- * return TOKTYPE_NULL to abort the matching.
- */
- return (TOKTYPE_ATTRLIST);
- } else if (acstr->strtype == STRTYPE_NULL) {
- /*
- * User haven't input anything for the attribute list,
- * he must be trying to list all attribute names.
- */
- return (TOKTYPE_ATTRNAME);
- }
-
- /*
- * The string may contain multiple comma separated "name=value"
- * items. Try to find the last one and move startp to point to it.
- */
- for (p = acstr->endp; p >= acstr->startp && *p != ATTR_LIST_SEP; p--) {}
-
- if (p == acstr->endp) {
- /*
- * The last character of the string is ',', which means
- * user is trying to list all attribute names.
- */
- acstr->startp = p + 1;
- acstr->strtype = STRTYPE_NULL;
- return (TOKTYPE_ATTRNAME);
- } else if (p > acstr->startp) {
- /*
- * Found ',' between starp and endp, move startp pointer
- * to point to the last item.
- */
- acstr->startp = p + 1;
- }
-
- /*
- * Now startp points to the last "name=value" item. Search in
- * the characters user has input for this item:
- *
- * a) if there isn't '=' character, user is inputting attribute name
- * b) if there is a '=' character and it is followed by a '$',
- * user is inputting variable name
- * c) if there is a '=' character and it isn't followed by a '$',
- * user is inputting a literal string as attribute value.
- */
- for (p = acstr->startp; p <= acstr->endp; p++) {
- if (*p == ATTR_ASSIGN_OP) {
- /* Found "=" operator in the string */
- if (*(p + 1) == VAR_PREFIX) {
- acstr->startp = p + 2;
- if (*acstr->startp != NULL)
- acstr->strtype = STRTYPE_INCOMPLETE;
- else
- acstr->strtype = STRTYPE_NULL;
- return (TOKTYPE_RVARNAME);
- } else {
- return (TOKTYPE_ATTRVAL);
- }
- }
- }
-
- /* Didn't find '=' operator, the string must be an attribute name */
- return (TOKTYPE_ATTRNAME);
-}
-
-/*
- * Parse an input string which is a variable list, get the current word
- * user wants to complete, and return its token type.
- *
- * A varaible list has the following format:
- *
- * $varname=value
- *
- * The function modifies the passed acstr string on success to point to
- * the word being completed.
- */
-static ac_toktype_t
-parse_var_list(ac_str_t *acstr)
-{
- const char *p;
-
- if (acstr->strtype == STRTYPE_COMPLETE) {
- /*
- * User has input a complete string for var list
- * return TOKTYPE_NULL to abort the matching.
- */
- return (TOKTYPE_NULL);
- } else if (acstr->strtype == STRTYPE_NULL) {
- /*
- * User haven't input anything for the attribute list,
- * he must be trying to list all available var names.
- */
- return (TOKTYPE_LVARNAME);
- }
-
- /*
- * Search in what user has input:
- *
- * a) if there isn't a '=' character, user is inputting var name
- * b) if there is a '=' character, user is inputting var value
- */
- for (p = acstr->startp; p <= acstr->endp; p++) {
- if (*p == VAR_ASSIGN_OP)
- return (TOKTYPE_VARVAL);
- }
-
- /* Didn't find '=' operator, user must be inputting an var name */
- return (TOKTYPE_LVARNAME);
-}
-
-/*
- * Compare two strings acstr and str. acstr is a string of ac_str_t type,
- * str is a normal string. If issub is B_TRUE, the function checks if
- * acstr is a sub-string of str, starting from index 0; otherwise it checks
- * if acstr and str are exactly the same.
- *
- * The function returns 0 on success and -1 on failure. When it succeeds,
- * it also set restp to point to the rest part of the normal string.
- */
-static int
-compare_string(ac_str_t *acstr, const char *str, boolean_t issub,
- const char **restp)
-{
- const char *p, *q;
-
- for (p = acstr->startp, q = str; (p <= acstr->endp) && (*q != '\0');
- p++, q++) {
- if (*p != *q)
- return (-1);
- }
-
- if (p == acstr->endp + 1) {
- if (*q == '\0' || issub == B_TRUE) {
- if (restp != NULL)
- *restp = q;
- return (0);
- }
- }
-
- return (-1);
-}
-
-/*
- * Use the passed iterp iterator to access a list of string values to
- * look for those matches with acstr, an user input string to be completed.
- *
- * cpl, line, work_end, and cont_suffix are parameters needed by
- * cpl_add_completion(), which adds matched entries to libtecla.
- *
- * Since user input line may have multiple strings, the function is
- * expected to be called multiple times to match those strings one
- * by one until the last one is reached.
- *
- * The multi-step matching process also means the function should provide
- * a way to indicate to the caller whether to continue or abort the
- * whole matching process. The function does that with the following
- * return values:
- *
- * MATCH_DONE - the matching for the whole user input is done. This
- * can mean either some items are found or none is found.
- * In either case, the caller shouldn't continue to
- * match the rest strings, either because there is
- * no strings left, or because the matching for the
- * current string failed so there is no need to check
- * further.
- * MATCH_CONT - the matching for the current string succeeds, but
- * user needs to continue to match the rest strings.
- */
-static ac_match_result_t
-match_string(WordCompletion *cpl, const char *line, int word_end,
- ac_str_t *acstr, ac_iter_t *iterp, const char *cont_suffix)
-{
- const char *str, *restp;
-
- iterp->reset(iterp);
-
- if (acstr->strtype == STRTYPE_COMPLETE) {
- while ((str = iterp->get_nextstr(iterp)) != NULL) {
- if (!compare_string(acstr, str, B_FALSE, NULL)) {
- /* Continue to check rest strings */
- return (MATCH_CONT);
- }
- }
- } else if (acstr->strtype == STRTYPE_NULL) {
- /* User input nothing. List all available strings */
- while ((str = iterp->get_nextstr(iterp)) != NULL) {
- (void) cpl_add_completion(cpl, line,
- acstr->startp - line, word_end, str,
- NULL, cont_suffix);
- }
- } else if (acstr->strtype == STRTYPE_INCOMPLETE) {
- while ((str = iterp->get_nextstr(iterp)) != NULL) {
- if (!compare_string(acstr, str, B_TRUE, &restp)) {
- /* It matches! Add it. */
- (void) cpl_add_completion(cpl, line,
- acstr->startp - line, word_end, restp,
- NULL, cont_suffix);
- }
- }
- }
-
- return (MATCH_DONE);
-}
-
-/*
- * This is the interface between filebench and libtecla for auto-
- * completion. It is called by libtecla whenever user initiates a
- * auto-completion request(ie., pressing TAB key).
- *
- * The function calls parse_user_input() to parse user input into
- * multiple strings, then it calls match_string() to match each
- * string in user input in sequence until either the last string
- * is reached and completed or the the matching fails.
- */
-/* ARGSUSED */
-CPL_MATCH_FN(command_complete)
-{
- ac_inputline_t inputline;
- ac_tvlist_t *clistp = &fb_cmds, *nlistp;
- ac_toktype_t toktype;
- ac_iter_t *iterp;
- char *cont_suffix;
- ac_get_curtok_func_t get_curtok;
- int i, ret;
-
- /* Parse user input and save the result in inputline variable. */
- parse_user_input(line, word_end, &inputline);
-
- /*
- * Match each string in user input against the proper token's
- * value list, and continue the loop until either the last string
- * is reached and completed or the matching aborts.
- */
- for (i = 0; i < STR_NUM &&
- inputline.strs[i].strtype != STRTYPE_INVALID && clistp != NULL;
- i++) {
- toktype = clistp->toktype;
-
- /*
- * If the current stirng can contain multiple tokens, modify
- * the stirng to point to the word being input and return
- * its token type.
- */
- get_curtok = token_info[toktype].get_curtok;
- if (get_curtok != NULL)
- toktype = (*get_curtok)(&inputline.strs[i]);
-
- iterp = token_info[toktype].iter;
- cont_suffix = token_info[toktype].cont_suffix;
- /* Return if there is no completion info for the token */
- if (iterp == NULL)
- break;
-
- iterp->bind(iterp, clistp->vals, &nlistp);
- /* Match user string against the token's list */
- ret = match_string(cpl, line, word_end, &inputline.strs[i],
- iterp, cont_suffix);
- if (ret == MATCH_DONE)
- return (0);
- clistp = nlistp;
- }
-
- return (0);
-}
diff --git a/usr/src/cmd/filebench/common/auto_comp.h b/usr/src/cmd/filebench/common/auto_comp.h
deleted file mode 100644
index e526f7650b..0000000000
--- a/usr/src/cmd/filebench/common/auto_comp.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifndef _FB_AUTOCOMP_H
-#define _FB_AUTOCOMP_H
-
-#include <libtecla.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern CPL_MATCH_FN(command_complete);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_AUTOCOMP_H */
diff --git a/usr/src/cmd/filebench/common/config.h b/usr/src/cmd/filebench/common/config.h
deleted file mode 100644
index 5423d160e4..0000000000
--- a/usr/src/cmd/filebench/common/config.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_CONFIG_H
-#define _FB_CONFIG_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define HAVE_AIO 1
-#define HAVE_AIOCB64_T 1
-#define HAVE_AIOWAITN 1
-#define HAVE_AIO_H 1
-#define HAVE_CADDR_T 1
-#define HAVE_FORK 1
-#define HAVE_FORK1 1
-#define HAVE_HRTIME 1
-#define HAVE_LIBKSTAT 1
-#define HAVE_LWPS 1
-#define HAVE_MKSTEMP 1
-#define HAVE_OFF64_T 1
-#define HAVE_PROCFS 1
-#define HAVE_PROCSCOPE_PTHREADS 1
-#define HAVE_PTHREAD 1
-#define HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL 1
-#define HAVE_ROBUST_MUTEX 1
-#define HAVE_SEMTIMEDOP 1
-#define HAVE_SETRLIMIT 1
-#define HAVE_SHM_SHARE_MMU 1
-#define HAVE_SIGSEND 1
-#define HAVE_STDINT_H 1
-#define HAVE_SYSV_SEM 1
-#define HAVE_SEM_RMID 1
-#define HAVE_SYS_INT_LIMITS_H 1
-#define HAVE_UINT64_MAX 1
-#define HAVE_UINT_T 1
-#define HAVE_BOOLEAN_T 1
-#define HAVE_U_LONGLONG_T 1
-#define HAVE_LIBTECLA 1
-#define HAVE_RAW_SUPPORT 1
-#define HAVE_FTRUNCATE64 1
-#define USE_PROCESS_MODEL 1
-
-/* Define to 1 if you have the <libaio.h> header file. */
-/* #undefHAVE_LIBAIO_H */
-
-/* Checking if you have /proc/stat */
-/* #undef HAVE_PROC_STAT */
-
-/* Define to 1 if you have the <sys/async.h> header file. */
-/* #undef HAVE_SYS_ASYNC_H */
-
-/* Define if you want support for RDTSC. */
-/* #undef USE_RDTSC */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_CONFIG_H */
diff --git a/usr/src/cmd/filebench/common/eventgen.c b/usr/src/cmd/filebench/common/eventgen.c
deleted file mode 100644
index fc967017af..0000000000
--- a/usr/src/cmd/filebench/common/eventgen.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-/*
- * The event generator in this module is the producer half of a
- * metering system which blocks flows using consumer routines in the
- * flowop_library.c module. Four routines in that module can limit rates
- * by event rate (flowoplib_eventlimit), by I/O operations rate
- * (flowoplib_iopslimit()), by operations rate (flowoplib_opslimit),
- * or by I/O bandwidth limit (flowoplib_bwlimit). By setting appropriate
- * event generation rates, required calls per second, I/O ops per second,
- * file system ops per second, or I/O bandwidth per second limits can
- * be set. Note, the generated events are shared with all consumer
- * flowops, of which their will be one for each process / thread
- * instance which has a consumer flowop defined in it.
- */
-
-#include <sys/time.h>
-
-#include "filebench.h"
-#include "vars.h"
-#include "eventgen.h"
-#include "flowop.h"
-#include "ipc.h"
-
-/*
- * Prints "how to use" information for the eventgen module
- */
-void
-eventgen_usage(void)
-{
- (void) fprintf(stderr, "eventgen rate=<rate>\n");
- (void) fprintf(stderr, "\n");
-}
-
-/*
- * The producer side of the event system.
- * Once eventgen_hz has been set by eventgen_setrate(),
- * the routine sends eventgen_hz events per second until
- * the program terminates. Events are posted by incrementing
- * filebench_shm->shm_eventgen_q by the number of generated
- * events then signalling the condition variable
- * filebench_shm->shm_eventgen_cv to indicate to event consumers
- * that more events are available.
- *
- * Eventgen_thread attempts to sleep for 10 event periods,
- * then, once awakened, determines how many periods actually
- * passed since sleeping, and issues a set of events equal
- * to the number of periods that it slept, thus keeping the
- * average rate at the requested rate.
- */
-static void
-eventgen_thread(void)
-{
- hrtime_t last;
-
- last = gethrtime();
- filebench_shm->shm_eventgen_enabled = FALSE;
-
- /* CONSTCOND */
- while (1) {
- struct timespec sleeptime;
- hrtime_t delta;
- int count, rate;
-
- if (filebench_shm->shm_eventgen_hz == NULL) {
- (void) sleep(1);
- continue;
- } else {
- rate = avd_get_int(filebench_shm->shm_eventgen_hz);
- if (rate > 0) {
- filebench_shm->shm_eventgen_enabled = TRUE;
- } else {
- continue;
- }
- }
-
- /* Sleep for 10xperiod */
- sleeptime.tv_sec = 0;
- sleeptime.tv_nsec = FB_SEC2NSEC / rate;
-
- sleeptime.tv_nsec *= 10;
- if (sleeptime.tv_nsec < 1000UL)
- sleeptime.tv_nsec = 1000UL;
-
- sleeptime.tv_sec = sleeptime.tv_nsec / FB_SEC2NSEC;
- if (sleeptime.tv_sec > 0)
- sleeptime.tv_nsec -= (sleeptime.tv_sec * FB_SEC2NSEC);
-
- (void) nanosleep(&sleeptime, NULL);
- delta = gethrtime() - last;
- last = gethrtime();
- count = (rate * delta) / FB_SEC2NSEC;
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "delta %llums count %d",
- (u_longlong_t)(delta / 1000000), count);
-
- /* Send 'count' events */
- (void) ipc_mutex_lock(&filebench_shm->shm_eventgen_lock);
- /* Keep the producer with a max of 5 second depth */
- if (filebench_shm->shm_eventgen_q < (5 * rate))
- filebench_shm->shm_eventgen_q += count;
-
- (void) pthread_cond_signal(&filebench_shm->shm_eventgen_cv);
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_eventgen_lock);
- }
-}
-
-/*
- * Creates a thread to run the event generator eventgen_thread
- * routine. Shuts down filebench if the eventgen thread cannot
- * be created.
- */
-void
-eventgen_init(void)
-{
- /*
- * Linux does not like it if the first
- * argument to pthread_create is null. It actually
- * segv's. -neel
- */
- pthread_t tid;
-
- if (pthread_create(&tid, NULL,
- (void *(*)(void*))eventgen_thread, 0) != 0) {
- filebench_log(LOG_ERROR, "create timer thread failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
-}
-
-/*
- * Puts the current event rate in the integer portion of the
- * supplied var_t. Returns a pointer to the var_t.
- */
-var_t *
-eventgen_ratevar(var_t *var)
-{
- VAR_SET_INT(var, avd_get_int(filebench_shm->shm_eventgen_hz));
- return (var);
-}
-
-/*
- * Sets the event generator rate to that supplied by
- * var_t *rate.
- */
-void
-eventgen_setrate(avd_t rate)
-{
- filebench_shm->shm_eventgen_hz = rate;
- if (rate == NULL) {
- filebench_log(LOG_ERROR,
- "eventgen_setrate() called without a rate");
- return;
- }
-
- if (AVD_IS_VAR(rate)) {
- filebench_log(LOG_VERBOSE,
- "Eventgen rate taken from variable");
- } else {
- filebench_log(LOG_VERBOSE, "Eventgen: %llu per second",
- (u_longlong_t)avd_get_int(rate));
- }
-}
-
-/*
- * Clears the event queue so we have a clean start
- */
-void
-eventgen_reset(void)
-{
- filebench_shm->shm_eventgen_q = 0;
-}
diff --git a/usr/src/cmd/filebench/common/eventgen.h b/usr/src/cmd/filebench/common/eventgen.h
deleted file mode 100644
index 4797714224..0000000000
--- a/usr/src/cmd/filebench/common/eventgen.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_EVENTGEN_H
-#define _FB_EVENTGEN_H
-
-#include "config.h"
-#include "vars.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define FB_SEC2NSEC 1000000000UL
-void eventgen_init(void);
-void eventgen_setrate(avd_t rate);
-var_t *eventgen_ratevar(var_t *var);
-void eventgen_usage(void);
-void eventgen_reset(void);
-
-#define EVENTGEN_VAR "rate"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_EVENTGEN_H */
diff --git a/usr/src/cmd/filebench/common/fb_avl.c b/usr/src/cmd/filebench/common/fb_avl.c
deleted file mode 100644
index 2f263bdd76..0000000000
--- a/usr/src/cmd/filebench/common/fb_avl.c
+++ /dev/null
@@ -1,1064 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * AVL - generic AVL tree implementation for FileBench use.
- * -Adapted from the avl.c open source code used in the Solaris Kernel-
- *
- * A complete description of AVL trees can be found in many CS textbooks.
- *
- * Here is a very brief overview. An AVL tree is a binary search tree that is
- * almost perfectly balanced. By "almost" perfectly balanced, we mean that at
- * any given node, the left and right subtrees are allowed to differ in height
- * by at most 1 level.
- *
- * This relaxation from a perfectly balanced binary tree allows doing
- * insertion and deletion relatively efficiently. Searching the tree is
- * still a fast operation, roughly O(log(N)).
- *
- * The key to insertion and deletion is a set of tree maniuplations called
- * rotations, which bring unbalanced subtrees back into the semi-balanced state.
- *
- * This implementation of AVL trees has the following peculiarities:
- *
- * - The AVL specific data structures are physically embedded as fields
- * in the "using" data structures. To maintain generality the code
- * must constantly translate between "avl_node_t *" and containing
- * data structure "void *"s by adding/subracting the avl_offset.
- *
- * - Since the AVL data is always embedded in other structures, there is
- * no locking or memory allocation in the AVL routines. This must be
- * provided for by the enclosing data structure's semantics. Typically,
- * avl_insert()/_add()/_remove()/avl_insert_here() require some kind of
- * exclusive write lock. Other operations require a read lock.
- *
- * - The implementation uses iteration instead of explicit recursion,
- * since it is intended to run on limited size kernel stacks. Since
- * there is no recursion stack present to move "up" in the tree,
- * there is an explicit "parent" link in the avl_node_t.
- *
- * - The left/right children pointers of a node are in an array.
- * In the code, variables (instead of constants) are used to represent
- * left and right indices. The implementation is written as if it only
- * dealt with left handed manipulations. By changing the value assigned
- * to "left", the code also works for right handed trees. The
- * following variables/terms are frequently used:
- *
- * int left; // 0 when dealing with left children,
- * // 1 for dealing with right children
- *
- * int left_heavy; // -1 when left subtree is taller at some node,
- * // +1 when right subtree is taller
- *
- * int right; // will be the opposite of left (0 or 1)
- * int right_heavy;// will be the opposite of left_heavy (-1 or 1)
- *
- * int direction; // 0 for "<" (ie. left child); 1 for ">" (right)
- *
- * Though it is a little more confusing to read the code, the approach
- * allows using half as much code (and hence cache footprint) for tree
- * manipulations and eliminates many conditional branches.
- *
- * - The avl_index_t is an opaque "cookie" used to find nodes at or
- * adjacent to where a new value would be inserted in the tree. The value
- * is a modified "avl_node_t *". The bottom bit (normally 0 for a
- * pointer) is set to indicate if that the new node has a value greater
- * than the value of the indicated "avl_node_t *".
- */
-
-#include "filebench.h"
-#include "fb_avl.h"
-
-/*
- * Small arrays to translate between balance (or diff) values and child indeces.
- *
- * Code that deals with binary tree data structures will randomly use
- * left and right children when examining a tree. C "if()" statements
- * which evaluate randomly suffer from very poor hardware branch prediction.
- * In this code we avoid some of the branch mispredictions by using the
- * following translation arrays. They replace random branches with an
- * additional memory reference. Since the translation arrays are both very
- * small the data should remain efficiently in cache.
- */
-static const int avl_child2balance[2] = {-1, 1};
-static const int avl_balance2child[] = {0, 0, 1};
-
-
-/*
- * Walk from one node to the previous valued node (ie. an infix walk
- * towards the left). At any given node we do one of 2 things:
- *
- * - If there is a left child, go to it, then to it's rightmost descendant.
- *
- * - otherwise we return thru parent nodes until we've come from a right child.
- *
- * Return Value:
- * NULL - if at the end of the nodes
- * otherwise next node
- */
-void *
-avl_walk(avl_tree_t *tree, void *oldnode, int left)
-{
- size_t off = tree->avl_offset;
- avl_node_t *node = AVL_DATA2NODE(oldnode, off);
- int right = 1 - left;
- int was_child;
-
-
- /*
- * nowhere to walk to if tree is empty
- */
- if (node == NULL)
- return (NULL);
-
- /*
- * Visit the previous valued node. There are two possibilities:
- *
- * If this node has a left child, go down one left, then all
- * the way right.
- */
- if (node->avl_child[left] != NULL) {
- for (node = node->avl_child[left];
- node->avl_child[right] != NULL;
- node = node->avl_child[right])
- ;
- /*
- * Otherwise, return thru left children as far as we can.
- */
- } else {
- for (;;) {
- was_child = AVL_XCHILD(node);
- node = AVL_XPARENT(node);
- if (node == NULL)
- return (NULL);
- if (was_child == right)
- break;
- }
- }
-
- return (AVL_NODE2DATA(node, off));
-}
-
-/*
- * Return the lowest valued node in a tree or NULL.
- * (leftmost child from root of tree)
- */
-void *
-avl_first(avl_tree_t *tree)
-{
- avl_node_t *node;
- avl_node_t *prev = NULL;
- size_t off = tree->avl_offset;
-
- for (node = tree->avl_root; node != NULL; node = node->avl_child[0])
- prev = node;
-
- if (prev != NULL)
- return (AVL_NODE2DATA(prev, off));
- return (NULL);
-}
-
-/*
- * Return the highest valued node in a tree or NULL.
- * (rightmost child from root of tree)
- */
-void *
-avl_last(avl_tree_t *tree)
-{
- avl_node_t *node;
- avl_node_t *prev = NULL;
- size_t off = tree->avl_offset;
-
- for (node = tree->avl_root; node != NULL; node = node->avl_child[1])
- prev = node;
-
- if (prev != NULL)
- return (AVL_NODE2DATA(prev, off));
- return (NULL);
-}
-
-/*
- * Access the node immediately before or after an insertion point.
- *
- * "avl_index_t" is a (avl_node_t *) with the bottom bit indicating a child
- *
- * Return value:
- * NULL: no node in the given direction
- * "void *" of the found tree node
- */
-void *
-avl_nearest(avl_tree_t *tree, avl_index_t where, int direction)
-{
- int child = AVL_INDEX2CHILD(where);
- avl_node_t *node = AVL_INDEX2NODE(where);
- void *data;
- size_t off = tree->avl_offset;
-
- if (node == NULL) {
- if (tree->avl_root != NULL)
- filebench_log(LOG_ERROR,
- "Null Node Pointer Supplied");
- return (NULL);
- }
- data = AVL_NODE2DATA(node, off);
- if (child != direction)
- return (data);
-
- return (avl_walk(tree, data, direction));
-}
-
-
-/*
- * Search for the node which contains "value". The algorithm is a
- * simple binary tree search.
- *
- * return value:
- * NULL: the value is not in the AVL tree
- * *where (if not NULL) is set to indicate the insertion point
- * "void *" of the found tree node
- */
-void *
-avl_find(avl_tree_t *tree, void *value, avl_index_t *where)
-{
- avl_node_t *node;
- avl_node_t *prev = NULL;
- int child = 0;
- int diff;
- size_t off = tree->avl_offset;
-
- for (node = tree->avl_root; node != NULL;
- node = node->avl_child[child]) {
-
- prev = node;
-
- diff = tree->avl_compar(value, AVL_NODE2DATA(node, off));
- if (!((-1 <= diff) && (diff <= 1))) {
- filebench_log(LOG_ERROR, "avl compare error");
- return (NULL);
- }
- if (diff == 0) {
- if (where != NULL)
- *where = 0;
-
- return (AVL_NODE2DATA(node, off));
- }
- child = avl_balance2child[1 + diff];
-
- }
-
- if (where != NULL)
- *where = AVL_MKINDEX(prev, child);
-
- return (NULL);
-}
-
-
-/*
- * Perform a rotation to restore balance at the subtree given by depth.
- *
- * This routine is used by both insertion and deletion. The return value
- * indicates:
- * 0 : subtree did not change height
- * !0 : subtree was reduced in height
- *
- * The code is written as if handling left rotations, right rotations are
- * symmetric and handled by swapping values of variables right/left[_heavy]
- *
- * On input balance is the "new" balance at "node". This value is either
- * -2 or +2.
- */
-static int
-avl_rotation(avl_tree_t *tree, avl_node_t *node, int balance)
-{
- int left = !(balance < 0); /* when balance = -2, left will be 0 */
- int right = 1 - left;
- int left_heavy = balance >> 1;
- int right_heavy = -left_heavy;
- avl_node_t *parent = AVL_XPARENT(node);
- avl_node_t *child = node->avl_child[left];
- avl_node_t *cright;
- avl_node_t *gchild;
- avl_node_t *gright;
- avl_node_t *gleft;
- int which_child = AVL_XCHILD(node);
- int child_bal = AVL_XBALANCE(child);
-
- /* BEGIN CSTYLED */
- /*
- * case 1 : node is overly left heavy, the left child is balanced or
- * also left heavy. This requires the following rotation.
- *
- * (node bal:-2)
- * / \
- * / \
- * (child bal:0 or -1)
- * / \
- * / \
- * cright
- *
- * becomes:
- *
- * (child bal:1 or 0)
- * / \
- * / \
- * (node bal:-1 or 0)
- * / \
- * / \
- * cright
- *
- * we detect this situation by noting that child's balance is not
- * right_heavy.
- */
- /* END CSTYLED */
- if (child_bal != right_heavy) {
-
- /*
- * compute new balance of nodes
- *
- * If child used to be left heavy (now balanced) we reduced
- * the height of this sub-tree -- used in "return...;" below
- */
- child_bal += right_heavy; /* adjust towards right */
-
- /*
- * move "cright" to be node's left child
- */
- cright = child->avl_child[right];
- node->avl_child[left] = cright;
- if (cright != NULL) {
- AVL_SETPARENT(cright, node);
- AVL_SETCHILD(cright, left);
- }
-
- /*
- * move node to be child's right child
- */
- child->avl_child[right] = node;
- AVL_SETBALANCE(node, -child_bal);
- AVL_SETCHILD(node, right);
- AVL_SETPARENT(node, child);
-
- /*
- * update the pointer into this subtree
- */
- AVL_SETBALANCE(child, child_bal);
- AVL_SETCHILD(child, which_child);
- AVL_SETPARENT(child, parent);
- if (parent != NULL)
- parent->avl_child[which_child] = child;
- else
- tree->avl_root = child;
-
- return (child_bal == 0);
- }
-
- /* BEGIN CSTYLED */
- /*
- * case 2 : When node is left heavy, but child is right heavy we use
- * a different rotation.
- *
- * (node b:-2)
- * / \
- * / \
- * / \
- * (child b:+1)
- * / \
- * / \
- * (gchild b: != 0)
- * / \
- * / \
- * gleft gright
- *
- * becomes:
- *
- * (gchild b:0)
- * / \
- * / \
- * / \
- * (child b:?) (node b:?)
- * / \ / \
- * / \ / \
- * gleft gright
- *
- * computing the new balances is more complicated. As an example:
- * if gchild was right_heavy, then child is now left heavy
- * else it is balanced
- */
- /* END CSTYLED */
- gchild = child->avl_child[right];
- gleft = gchild->avl_child[left];
- gright = gchild->avl_child[right];
-
- /*
- * move gright to left child of node and
- *
- * move gleft to right child of node
- */
- node->avl_child[left] = gright;
- if (gright != NULL) {
- AVL_SETPARENT(gright, node);
- AVL_SETCHILD(gright, left);
- }
-
- child->avl_child[right] = gleft;
- if (gleft != NULL) {
- AVL_SETPARENT(gleft, child);
- AVL_SETCHILD(gleft, right);
- }
-
- /*
- * move child to left child of gchild and
- *
- * move node to right child of gchild and
- *
- * fixup parent of all this to point to gchild
- */
- balance = AVL_XBALANCE(gchild);
- gchild->avl_child[left] = child;
- AVL_SETBALANCE(child, (balance == right_heavy ? left_heavy : 0));
- AVL_SETPARENT(child, gchild);
- AVL_SETCHILD(child, left);
-
- gchild->avl_child[right] = node;
- AVL_SETBALANCE(node, (balance == left_heavy ? right_heavy : 0));
- AVL_SETPARENT(node, gchild);
- AVL_SETCHILD(node, right);
-
- AVL_SETBALANCE(gchild, 0);
- AVL_SETPARENT(gchild, parent);
- AVL_SETCHILD(gchild, which_child);
- if (parent != NULL)
- parent->avl_child[which_child] = gchild;
- else
- tree->avl_root = gchild;
-
- return (1); /* the new tree is always shorter */
-}
-
-
-/*
- * Insert a new node into an AVL tree at the specified (from avl_find()) place.
- *
- * Newly inserted nodes are always leaf nodes in the tree, since avl_find()
- * searches out to the leaf positions. The avl_index_t indicates the node
- * which will be the parent of the new node.
- *
- * After the node is inserted, a single rotation further up the tree may
- * be necessary to maintain an acceptable AVL balance.
- */
-void
-avl_insert(avl_tree_t *tree, void *new_data, avl_index_t where)
-{
- avl_node_t *node;
- avl_node_t *parent = AVL_INDEX2NODE(where);
- int old_balance;
- int new_balance;
- int which_child = AVL_INDEX2CHILD(where);
- size_t off = tree->avl_offset;
-
- if (tree == NULL) {
- filebench_log(LOG_ERROR, "No Tree Supplied");
- return;
- }
-#ifdef _LP64
- if (((uintptr_t)new_data & 0x7) != 0) {
- filebench_log(LOG_ERROR, "Missaligned pointer to new data");
- return;
- }
-#endif
-
- node = AVL_DATA2NODE(new_data, off);
-
- /*
- * First, add the node to the tree at the indicated position.
- */
- ++tree->avl_numnodes;
-
- node->avl_child[0] = NULL;
- node->avl_child[1] = NULL;
-
- AVL_SETCHILD(node, which_child);
- AVL_SETBALANCE(node, 0);
- AVL_SETPARENT(node, parent);
- if (parent != NULL) {
- if (parent->avl_child[which_child] != NULL)
- filebench_log(LOG_DEBUG_IMPL,
- "Overwriting existing pointer");
-
- parent->avl_child[which_child] = node;
- } else {
- if (tree->avl_root != NULL)
- filebench_log(LOG_DEBUG_IMPL,
- "Overwriting existing pointer");
-
- tree->avl_root = node;
- }
- /*
- * Now, back up the tree modifying the balance of all nodes above the
- * insertion point. If we get to a highly unbalanced ancestor, we
- * need to do a rotation. If we back out of the tree we are done.
- * If we brought any subtree into perfect balance (0), we are also done.
- */
- for (;;) {
- node = parent;
- if (node == NULL)
- return;
-
- /*
- * Compute the new balance
- */
- old_balance = AVL_XBALANCE(node);
- new_balance = old_balance + avl_child2balance[which_child];
-
- /*
- * If we introduced equal balance, then we are done immediately
- */
- if (new_balance == 0) {
- AVL_SETBALANCE(node, 0);
- return;
- }
-
- /*
- * If both old and new are not zero we went
- * from -1 to -2 balance, do a rotation.
- */
- if (old_balance != 0)
- break;
-
- AVL_SETBALANCE(node, new_balance);
- parent = AVL_XPARENT(node);
- which_child = AVL_XCHILD(node);
- }
-
- /*
- * perform a rotation to fix the tree and return
- */
- (void) avl_rotation(tree, node, new_balance);
-}
-
-/*
- * Insert "new_data" in "tree" in the given "direction" either after or
- * before (AVL_AFTER, AVL_BEFORE) the data "here".
- *
- * Insertions can only be done at empty leaf points in the tree, therefore
- * if the given child of the node is already present we move to either
- * the AVL_PREV or AVL_NEXT and reverse the insertion direction. Since
- * every other node in the tree is a leaf, this always works.
- *
- * To help developers using this interface, we assert that the new node
- * is correctly ordered at every step of the way in DEBUG kernels.
- */
-void
-avl_insert_here(
- avl_tree_t *tree,
- void *new_data,
- void *here,
- int direction)
-{
- avl_node_t *node;
- int child = direction; /* rely on AVL_BEFORE == 0, AVL_AFTER == 1 */
-
- if ((tree == NULL) || (new_data == NULL) || (here == NULL) ||
- !((direction == AVL_BEFORE) || (direction == AVL_AFTER))) {
- filebench_log(LOG_ERROR,
- "avl_insert_here: Bad Parameters Passed");
- return;
- }
-
- /*
- * If corresponding child of node is not NULL, go to the neighboring
- * node and reverse the insertion direction.
- */
- node = AVL_DATA2NODE(here, tree->avl_offset);
-
- if (node->avl_child[child] != NULL) {
- node = node->avl_child[child];
- child = 1 - child;
- while (node->avl_child[child] != NULL)
- node = node->avl_child[child];
-
- }
- if (node->avl_child[child] != NULL)
- filebench_log(LOG_DEBUG_IMPL, "Overwriting existing pointer");
-
- avl_insert(tree, new_data, AVL_MKINDEX(node, child));
-}
-
-/*
- * Add a new node to an AVL tree.
- */
-void
-avl_add(avl_tree_t *tree, void *new_node)
-{
- avl_index_t where;
-
- /*
- * This is unfortunate. Give up.
- */
- if (avl_find(tree, new_node, &where) != NULL) {
- filebench_log(LOG_ERROR,
- "Attempting to insert already inserted node");
- return;
- }
- avl_insert(tree, new_node, where);
-}
-
-/*
- * Delete a node from the AVL tree. Deletion is similar to insertion, but
- * with 2 complications.
- *
- * First, we may be deleting an interior node. Consider the following subtree:
- *
- * d c c
- * / \ / \ / \
- * b e b e b e
- * / \ / \ /
- * a c a a
- *
- * When we are deleting node (d), we find and bring up an adjacent valued leaf
- * node, say (c), to take the interior node's place. In the code this is
- * handled by temporarily swapping (d) and (c) in the tree and then using
- * common code to delete (d) from the leaf position.
- *
- * Secondly, an interior deletion from a deep tree may require more than one
- * rotation to fix the balance. This is handled by moving up the tree through
- * parents and applying rotations as needed. The return value from
- * avl_rotation() is used to detect when a subtree did not change overall
- * height due to a rotation.
- */
-void
-avl_remove(avl_tree_t *tree, void *data)
-{
- avl_node_t *delete;
- avl_node_t *parent;
- avl_node_t *node;
- avl_node_t tmp;
- int old_balance;
- int new_balance;
- int left;
- int right;
- int which_child;
- size_t off = tree->avl_offset;
-
- if (tree == NULL) {
- filebench_log(LOG_ERROR, "No Tree Supplied");
- return;
- }
-
- delete = AVL_DATA2NODE(data, off);
-
- /*
- * Deletion is easiest with a node that has at most 1 child.
- * We swap a node with 2 children with a sequentially valued
- * neighbor node. That node will have at most 1 child. Note this
- * has no effect on the ordering of the remaining nodes.
- *
- * As an optimization, we choose the greater neighbor if the tree
- * is right heavy, otherwise the left neighbor. This reduces the
- * number of rotations needed.
- */
- if (delete->avl_child[0] != NULL && delete->avl_child[1] != NULL) {
-
- /*
- * choose node to swap from whichever side is taller
- */
- old_balance = AVL_XBALANCE(delete);
- left = avl_balance2child[old_balance + 1];
- right = 1 - left;
-
- /*
- * get to the previous value'd node
- * (down 1 left, as far as possible right)
- */
- for (node = delete->avl_child[left];
- node->avl_child[right] != NULL;
- node = node->avl_child[right])
- ;
-
- /*
- * create a temp placeholder for 'node'
- * move 'node' to delete's spot in the tree
- */
- tmp = *node;
-
- *node = *delete;
- if (node->avl_child[left] == node)
- node->avl_child[left] = &tmp;
-
- parent = AVL_XPARENT(node);
- if (parent != NULL)
- parent->avl_child[AVL_XCHILD(node)] = node;
- else
- tree->avl_root = node;
- AVL_SETPARENT(node->avl_child[left], node);
- AVL_SETPARENT(node->avl_child[right], node);
-
- /*
- * Put tmp where node used to be (just temporary).
- * It always has a parent and at most 1 child.
- */
- delete = &tmp;
- parent = AVL_XPARENT(delete);
- parent->avl_child[AVL_XCHILD(delete)] = delete;
- which_child = (delete->avl_child[1] != 0);
- if (delete->avl_child[which_child] != NULL)
- AVL_SETPARENT(delete->avl_child[which_child], delete);
- }
-
-
- /*
- * Here we know "delete" is at least partially a leaf node. It can
- * be easily removed from the tree.
- */
- if (tree->avl_numnodes == 0) {
- filebench_log(LOG_ERROR,
- "Deleting Node from already empty tree");
- return;
- }
-
- --tree->avl_numnodes;
- parent = AVL_XPARENT(delete);
- which_child = AVL_XCHILD(delete);
- if (delete->avl_child[0] != NULL)
- node = delete->avl_child[0];
- else
- node = delete->avl_child[1];
-
- /*
- * Connect parent directly to node (leaving out delete).
- */
- if (node != NULL) {
- AVL_SETPARENT(node, parent);
- AVL_SETCHILD(node, which_child);
- }
- if (parent == NULL) {
- tree->avl_root = node;
- return;
- }
- parent->avl_child[which_child] = node;
-
-
- /*
- * Since the subtree is now shorter, begin adjusting parent balances
- * and performing any needed rotations.
- */
- do {
-
- /*
- * Move up the tree and adjust the balance
- *
- * Capture the parent and which_child values for the next
- * iteration before any rotations occur.
- */
- node = parent;
- old_balance = AVL_XBALANCE(node);
- new_balance = old_balance - avl_child2balance[which_child];
- parent = AVL_XPARENT(node);
- which_child = AVL_XCHILD(node);
-
- /*
- * If a node was in perfect balance but isn't anymore then
- * we can stop, since the height didn't change above this point
- * due to a deletion.
- */
- if (old_balance == 0) {
- AVL_SETBALANCE(node, new_balance);
- break;
- }
-
- /*
- * If the new balance is zero, we don't need to rotate
- * else
- * need a rotation to fix the balance.
- * If the rotation doesn't change the height
- * of the sub-tree we have finished adjusting.
- */
- if (new_balance == 0)
- AVL_SETBALANCE(node, new_balance);
- else if (!avl_rotation(tree, node, new_balance))
- break;
- } while (parent != NULL);
-}
-
-#define AVL_REINSERT(tree, obj) \
- avl_remove((tree), (obj)); \
- avl_add((tree), (obj))
-
-boolean_t
-avl_update_lt(avl_tree_t *t, void *obj)
-{
- void *neighbor;
-
- if (!(((neighbor = AVL_NEXT(t, obj)) == NULL) ||
- (t->avl_compar(obj, neighbor) <= 0))) {
- filebench_log(LOG_ERROR,
- "avl_update_lt: Neighbor miss compare");
- return (B_FALSE);
- }
-
- neighbor = AVL_PREV(t, obj);
- if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
- AVL_REINSERT(t, obj);
- return (B_TRUE);
- }
-
- return (B_FALSE);
-}
-
-boolean_t
-avl_update_gt(avl_tree_t *t, void *obj)
-{
- void *neighbor;
-
- if (!(((neighbor = AVL_PREV(t, obj)) == NULL) ||
- (t->avl_compar(obj, neighbor) >= 0))) {
- filebench_log(LOG_ERROR,
- "avl_update_gt: Neighbor miss compare");
- return (B_FALSE);
- }
-
- neighbor = AVL_NEXT(t, obj);
- if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
- AVL_REINSERT(t, obj);
- return (B_TRUE);
- }
-
- return (B_FALSE);
-}
-
-boolean_t
-avl_update(avl_tree_t *t, void *obj)
-{
- void *neighbor;
-
- neighbor = AVL_PREV(t, obj);
- if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
- AVL_REINSERT(t, obj);
- return (B_TRUE);
- }
-
- neighbor = AVL_NEXT(t, obj);
- if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
- AVL_REINSERT(t, obj);
- return (B_TRUE);
- }
-
- return (B_FALSE);
-}
-
-/*
- * initialize a new AVL tree
- */
-void
-avl_create(avl_tree_t *tree, int (*compar) (const void *, const void *),
- size_t size, size_t offset)
-{
- if ((tree == NULL) || (compar == NULL) || (size == 0) ||
- (size < (offset + sizeof (avl_node_t)))) {
- filebench_log(LOG_ERROR,
- "avl_create: Bad Parameters Passed");
- return;
- }
-;
-#ifdef _LP64
- if ((offset & 0x7) != 0) {
- filebench_log(LOG_ERROR, "Missaligned pointer to new data");
- return;
- }
-#endif
-
- tree->avl_compar = compar;
- tree->avl_root = NULL;
- tree->avl_numnodes = 0;
- tree->avl_size = size;
- tree->avl_offset = offset;
-}
-
-/*
- * Delete a tree.
- */
-/* ARGSUSED */
-void
-avl_destroy(avl_tree_t *tree)
-{
- if ((tree == NULL) || (tree->avl_numnodes != 0) ||
- (tree->avl_root != NULL))
- filebench_log(LOG_DEBUG_IMPL, "avl_tree: Tree not destroyed");
-}
-
-
-/*
- * Return the number of nodes in an AVL tree.
- */
-unsigned long
-avl_numnodes(avl_tree_t *tree)
-{
- if (tree == NULL) {
- filebench_log(LOG_ERROR, "avl_numnodes: Null tree pointer");
- return (0);
- }
- return (tree->avl_numnodes);
-}
-
-boolean_t
-avl_is_empty(avl_tree_t *tree)
-{
- if (tree == NULL) {
- filebench_log(LOG_ERROR, "avl_is_empty: Null tree pointer");
- return (0);
- }
- return (tree->avl_numnodes == 0);
-}
-
-#define CHILDBIT (1L)
-
-/*
- * Post-order tree walk used to visit all tree nodes and destroy the tree
- * in post order. This is used for destroying a tree w/o paying any cost
- * for rebalancing it.
- *
- * example:
- *
- * void *cookie = NULL;
- * my_data_t *node;
- *
- * while ((node = avl_destroy_nodes(tree, &cookie)) != NULL)
- * free(node);
- * avl_destroy(tree);
- *
- * The cookie is really an avl_node_t to the current node's parent and
- * an indication of which child you looked at last.
- *
- * On input, a cookie value of CHILDBIT indicates the tree is done.
- */
-void *
-avl_destroy_nodes(avl_tree_t *tree, void **cookie)
-{
- avl_node_t *node;
- avl_node_t *parent;
- int child;
- void *first;
- size_t off = tree->avl_offset;
-
- /*
- * Initial calls go to the first node or it's right descendant.
- */
- if (*cookie == NULL) {
- first = avl_first(tree);
-
- /*
- * deal with an empty tree
- */
- if (first == NULL) {
- *cookie = (void *)CHILDBIT;
- return (NULL);
- }
-
- node = AVL_DATA2NODE(first, off);
- parent = AVL_XPARENT(node);
- goto check_right_side;
- }
-
- /*
- * If there is no parent to return to we are done.
- */
- parent = (avl_node_t *)((uintptr_t)(*cookie) & ~CHILDBIT);
- if (parent == NULL) {
- if (tree->avl_root != NULL) {
- if (tree->avl_numnodes != 1) {
- filebench_log(LOG_DEBUG_IMPL,
- "avl_destroy_nodes:"
- " number of nodes wrong");
- }
- tree->avl_root = NULL;
- tree->avl_numnodes = 0;
- }
- return (NULL);
- }
-
- /*
- * Remove the child pointer we just visited from the parent and tree.
- */
- child = (uintptr_t)(*cookie) & CHILDBIT;
- parent->avl_child[child] = NULL;
- if (tree->avl_numnodes <= 1)
- filebench_log(LOG_DEBUG_IMPL,
- "avl_destroy_nodes: number of nodes wrong");
-
- --tree->avl_numnodes;
-
- /*
- * If we just did a right child or there isn't one, go up to parent.
- */
- if (child == 1 || parent->avl_child[1] == NULL) {
- node = parent;
- parent = AVL_XPARENT(parent);
- goto done;
- }
-
- /*
- * Do parent's right child, then leftmost descendent.
- */
- node = parent->avl_child[1];
- while (node->avl_child[0] != NULL) {
- parent = node;
- node = node->avl_child[0];
- }
-
- /*
- * If here, we moved to a left child. It may have one
- * child on the right (when balance == +1).
- */
-check_right_side:
- if (node->avl_child[1] != NULL) {
- if (AVL_XBALANCE(node) != 1)
- filebench_log(LOG_DEBUG_IMPL,
- "avl_destroy_nodes: Tree inconsistency");
- parent = node;
- node = node->avl_child[1];
- if (node->avl_child[0] != NULL ||
- node->avl_child[1] != NULL)
- filebench_log(LOG_DEBUG_IMPL,
- "avl_destroy_nodes: Destroying non leaf node");
- } else {
-
- if (AVL_XBALANCE(node) > 0)
- filebench_log(LOG_DEBUG_IMPL,
- "avl_destroy_nodes: Tree inconsistency");
- }
-
-done:
- if (parent == NULL) {
- *cookie = (void *)CHILDBIT;
- if (node != tree->avl_root)
- filebench_log(LOG_DEBUG_IMPL,
- "avl_destroy_nodes: Dangling last node");
- } else {
- *cookie = (void *)((uintptr_t)parent | AVL_XCHILD(node));
- }
-
- return (AVL_NODE2DATA(node, off));
-}
diff --git a/usr/src/cmd/filebench/common/fb_avl.h b/usr/src/cmd/filebench/common/fb_avl.h
deleted file mode 100644
index 5604c02533..0000000000
--- a/usr/src/cmd/filebench/common/fb_avl.h
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef FB_AVL_H
-#define FB_AVL_H
-
-/*
- * derived from Solaris' sys/avl.h and sys/avl_impl.h
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-
-/*
- * generic AVL tree implementation for FileBench use
- *
- * The interfaces provide an efficient way of implementing an ordered set of
- * data structures.
- *
- * AVL trees provide an alternative to using an ordered linked list. Using AVL
- * trees will usually be faster, however they requires more storage. An ordered
- * linked list in general requires 2 pointers in each data structure. The
- * AVL tree implementation uses 3 pointers. The following chart gives the
- * approximate performance of operations with the different approaches:
- *
- * Operation Link List AVL tree
- * --------- -------- --------
- * lookup O(n) O(log(n))
- *
- * insert 1 node constant constant
- *
- * delete 1 node constant between constant and O(log(n))
- *
- * delete all nodes O(n) O(n)
- *
- * visit the next
- * or prev node constant between constant and O(log(n))
- *
- *
- * There are 5 pieces of information stored for each node in an AVL tree
- *
- * pointer to less than child
- * pointer to greater than child
- * a pointer to the parent of this node
- * an indication [0/1] of which child I am of my parent
- * a "balance" (-1, 0, +1) indicating which child tree is taller
- *
- * Since they only need 3 bits, the last two fields are packed into the
- * bottom bits of the parent pointer on 64 bit machines to save on space.
- */
-
-#ifndef _LP64
-
-struct avl_node {
- struct avl_node *avl_child[2]; /* left/right children */
- struct avl_node *avl_parent; /* this node's parent */
- unsigned short avl_child_index; /* my index in parent's avl_child[] */
- short avl_balance; /* balance value: -1, 0, +1 */
-};
-
-#define AVL_XPARENT(n) ((n)->avl_parent)
-#define AVL_SETPARENT(n, p) ((n)->avl_parent = (p))
-
-#define AVL_XCHILD(n) ((n)->avl_child_index)
-#define AVL_SETCHILD(n, c) ((n)->avl_child_index = (unsigned short)(c))
-
-#define AVL_XBALANCE(n) ((n)->avl_balance)
-#define AVL_SETBALANCE(n, b) ((n)->avl_balance = (short)(b))
-
-#else /* _LP64 */
-
-/*
- * for 64 bit machines, avl_pcb contains parent pointer, balance and child_index
- * values packed in the following manner:
- *
- * |63 3| 2 |1 0 |
- * |-------------------------------------|-----------------|-------------|
- * | avl_parent hi order bits | avl_child_index | avl_balance |
- * | | | + 1 |
- * |-------------------------------------|-----------------|-------------|
- *
- */
-struct avl_node {
- struct avl_node *avl_child[2]; /* left/right children nodes */
- uintptr_t avl_pcb; /* parent, child_index, balance */
-};
-
-/*
- * macros to extract/set fields in avl_pcb
- *
- * pointer to the parent of the current node is the high order bits
- */
-#define AVL_XPARENT(n) ((struct avl_node *)((n)->avl_pcb & ~7))
-#define AVL_SETPARENT(n, p) \
- ((n)->avl_pcb = (((n)->avl_pcb & 7) | (uintptr_t)(p)))
-
-/*
- * index of this node in its parent's avl_child[]: bit #2
- */
-#define AVL_XCHILD(n) (((n)->avl_pcb >> 2) & 1)
-#define AVL_SETCHILD(n, c) \
- ((n)->avl_pcb = (uintptr_t)(((n)->avl_pcb & ~4) | ((c) << 2)))
-
-/*
- * balance indication for a node, lowest 2 bits. A valid balance is
- * -1, 0, or +1, and is encoded by adding 1 to the value to get the
- * unsigned values of 0, 1, 2.
- */
-#define AVL_XBALANCE(n) ((int)(((n)->avl_pcb & 3) - 1))
-#define AVL_SETBALANCE(n, b) \
- ((n)->avl_pcb = (uintptr_t)((((n)->avl_pcb & ~3) | ((b) + 1))))
-
-#endif /* _LP64 */
-
-
-
-/*
- * switch between a node and data pointer for a given tree
- * the value of "o" is tree->avl_offset
- */
-#define AVL_NODE2DATA(n, o) ((void *)((uintptr_t)(n) - (o)))
-#define AVL_DATA2NODE(d, o) ((struct avl_node *)((uintptr_t)(d) + (o)))
-
-
-
-/*
- * macros used to create/access an avl_index_t
- */
-#define AVL_INDEX2NODE(x) ((avl_node_t *)((x) & ~1))
-#define AVL_INDEX2CHILD(x) ((x) & 1)
-#define AVL_MKINDEX(n, c) ((avl_index_t)(n) | (c))
-
-
-/*
- * The tree structure. The fields avl_root, avl_compar, and avl_offset come
- * first since they are needed for avl_find(). We want them to fit into
- * a single 64 byte cache line to make avl_find() as fast as possible.
- */
-struct avl_tree {
- struct avl_node *avl_root; /* root node in tree */
- int (*avl_compar)(const void *, const void *);
- size_t avl_offset; /* offsetof(type, avl_link_t field) */
- unsigned long avl_numnodes; /* number of nodes in the tree */
- size_t avl_size; /* sizeof user type struct */
-};
-
-
-/*
- * This will only by used via AVL_NEXT() or AVL_PREV()
- */
-extern void *avl_walk(struct avl_tree *, void *, int);
-
-
-/*
- * The data structure nodes are anchored at an "avl_tree_t" (the equivalent
- * of a list header) and the individual nodes will have a field of
- * type "avl_node_t" (corresponding to list pointers).
- *
- * The type "avl_index_t" is used to indicate a position in the list for
- * certain calls.
- *
- * The usage scenario is generally:
- *
- * 1. Create the list/tree with: avl_create()
- *
- * followed by any mixture of:
- *
- * 2a. Insert nodes with: avl_add(), or avl_find() and avl_insert()
- *
- * 2b. Visited elements with:
- * avl_first() - returns the lowest valued node
- * avl_last() - returns the highest valued node
- * AVL_NEXT() - given a node go to next higher one
- * AVL_PREV() - given a node go to previous lower one
- *
- * 2c. Find the node with the closest value either less than or greater
- * than a given value with avl_nearest().
- *
- * 2d. Remove individual nodes from the list/tree with avl_remove().
- *
- * and finally when the list is being destroyed
- *
- * 3. Use avl_destroy_nodes() to quickly process/free up any remaining nodes.
- * Note that once you use avl_destroy_nodes(), you can no longer
- * use any routine except avl_destroy_nodes() and avl_destoy().
- *
- * 4. Use avl_destroy() to destroy the AVL tree itself.
- *
- * Any locking for multiple thread access is up to the user to provide, just
- * as is needed for any linked list implementation.
- */
-
-
-/*
- * Type used for the root of the AVL tree.
- */
-typedef struct avl_tree avl_tree_t;
-
-/*
- * The data nodes in the AVL tree must have a field of this type.
- */
-typedef struct avl_node avl_node_t;
-
-/*
- * An opaque type used to locate a position in the tree where a node
- * would be inserted.
- */
-typedef uintptr_t avl_index_t;
-
-
-/*
- * Direction constants used for avl_nearest().
- */
-#define AVL_BEFORE (0)
-#define AVL_AFTER (1)
-
-
-/*
- * Prototypes
- *
- * Where not otherwise mentioned, "void *" arguments are a pointer to the
- * user data structure which must contain a field of type avl_node_t.
- *
- * Also assume the user data structures looks like:
- * stuct my_type {
- * ...
- * avl_node_t my_link;
- * ...
- * };
- */
-
-/*
- * Initialize an AVL tree. Arguments are:
- *
- * tree - the tree to be initialized
- * compar - function to compare two nodes, it must return exactly: -1, 0, or +1
- * -1 for <, 0 for ==, and +1 for >
- * size - the value of sizeof(struct my_type)
- * offset - the value of OFFSETOF(struct my_type, my_link)
- */
-extern void avl_create(avl_tree_t *tree,
- int (*compar) (const void *, const void *), size_t size, size_t offset);
-
-
-/*
- * Find a node with a matching value in the tree. Returns the matching node
- * found. If not found, it returns NULL and then if "where" is not NULL it sets
- * "where" for use with avl_insert() or avl_nearest().
- *
- * node - node that has the value being looked for
- * where - position for use with avl_nearest() or avl_insert(), may be NULL
- */
-extern void *avl_find(avl_tree_t *tree, void *node, avl_index_t *where);
-
-/*
- * Insert a node into the tree.
- *
- * node - the node to insert
- * where - position as returned from avl_find()
- */
-extern void avl_insert(avl_tree_t *tree, void *node, avl_index_t where);
-
-/*
- * Insert "new_data" in "tree" in the given "direction" either after
- * or before the data "here".
- *
- * This might be usefull for avl clients caching recently accessed
- * data to avoid doing avl_find() again for insertion.
- *
- * new_data - new data to insert
- * here - existing node in "tree"
- * direction - either AVL_AFTER or AVL_BEFORE the data "here".
- */
-extern void avl_insert_here(avl_tree_t *tree, void *new_data, void *here,
- int direction);
-
-
-/*
- * Return the first or last valued node in the tree. Will return NULL
- * if the tree is empty.
- *
- */
-extern void *avl_first(avl_tree_t *tree);
-extern void *avl_last(avl_tree_t *tree);
-
-
-/*
- * Return the next or previous valued node in the tree.
- * AVL_NEXT() will return NULL if at the last node.
- * AVL_PREV() will return NULL if at the first node.
- *
- * node - the node from which the next or previous node is found
- */
-#define AVL_NEXT(tree, node) avl_walk(tree, node, AVL_AFTER)
-#define AVL_PREV(tree, node) avl_walk(tree, node, AVL_BEFORE)
-
-
-/*
- * Find the node with the nearest value either greater or less than
- * the value from a previous avl_find(). Returns the node or NULL if
- * there isn't a matching one.
- *
- * where - position as returned from avl_find()
- * direction - either AVL_BEFORE or AVL_AFTER
- *
- * EXAMPLE get the greatest node that is less than a given value:
- *
- * avl_tree_t *tree;
- * struct my_data look_for_value = {....};
- * struct my_data *node;
- * struct my_data *less;
- * avl_index_t where;
- *
- * node = avl_find(tree, &look_for_value, &where);
- * if (node != NULL)
- * less = AVL_PREV(tree, node);
- * else
- * less = avl_nearest(tree, where, AVL_BEFORE);
- */
-extern void *avl_nearest(avl_tree_t *tree, avl_index_t where, int direction);
-
-
-/*
- * Add a single node to the tree.
- * The node must not be in the tree, and it must not
- * compare equal to any other node already in the tree.
- *
- * node - the node to add
- */
-extern void avl_add(avl_tree_t *tree, void *node);
-
-
-/*
- * Remove a single node from the tree. The node must be in the tree.
- *
- * node - the node to remove
- */
-extern void avl_remove(avl_tree_t *tree, void *node);
-
-/*
- * Reinsert a node only if its order has changed relative to its nearest
- * neighbors. To optimize performance avl_update_lt() checks only the previous
- * node and avl_update_gt() checks only the next node. Use avl_update_lt() and
- * avl_update_gt() only if you know the direction in which the order of the
- * node may change.
- */
-extern boolean_t avl_update(avl_tree_t *, void *);
-extern boolean_t avl_update_lt(avl_tree_t *, void *);
-extern boolean_t avl_update_gt(avl_tree_t *, void *);
-
-/*
- * Return the number of nodes in the tree
- */
-extern unsigned long avl_numnodes(avl_tree_t *tree);
-
-/*
- * Return B_TRUE if there are zero nodes in the tree, B_FALSE otherwise.
- */
-extern boolean_t avl_is_empty(avl_tree_t *tree);
-
-/*
- * Used to destroy any remaining nodes in a tree. The cookie argument should
- * be initialized to NULL before the first call. Returns a node that has been
- * removed from the tree and may be free()'d. Returns NULL when the tree is
- * empty.
- *
- * Once you call avl_destroy_nodes(), you can only continuing calling it and
- * finally avl_destroy(). No other AVL routines will be valid.
- *
- * cookie - a "void *" used to save state between calls to avl_destroy_nodes()
- *
- * EXAMPLE:
- * avl_tree_t *tree;
- * struct my_data *node;
- * void *cookie;
- *
- * cookie = NULL;
- * while ((node = avl_destroy_nodes(tree, &cookie)) != NULL)
- * free(node);
- * avl_destroy(tree);
- */
-extern void *avl_destroy_nodes(avl_tree_t *tree, void **cookie);
-
-
-/*
- * Final destroy of an AVL tree. Arguments are:
- *
- * tree - the empty tree to destroy
- */
-extern void avl_destroy(avl_tree_t *tree);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* FB_AVL_H */
diff --git a/usr/src/cmd/filebench/common/fb_localfs.c b/usr/src/cmd/filebench/common/fb_localfs.c
deleted file mode 100644
index 91bdfd2b73..0000000000
--- a/usr/src/cmd/filebench/common/fb_localfs.c
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#include "config.h"
-#include "filebench.h"
-#include "flowop.h"
-#include "threadflow.h" /* For aiolist definition */
-
-#ifndef HAVE_OFF64_T
-/*
- * We are probably on linux.
- * According to http://www.suse.de/~aj/linux_lfs.html, defining the
- * above, automatically changes type of off_t to off64_t. so let
- * us use only off_t as off64_t is not defined
- */
-#define off64_t off_t
-#endif /* HAVE_OFF64_T */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/resource.h>
-
-#include "filebench.h"
-#include "fsplug.h"
-
-#ifdef HAVE_AIO
-#include <aio.h>
-#endif /* HAVE_AIO */
-
-#ifdef HAVE_LIBAIO_H
-#include <libaio.h>
-#endif /* HAVE_LIBAIO_H */
-
-#ifndef HAVE_AIOCB64_T
-#define aiocb64 aiocb
-#endif /* HAVE_AIOCB64_T */
-
-/*
- * These routines implement local file access. They are placed into a
- * vector of functions that are called by all I/O operations in fileset.c
- * and flowop_library.c. This represents the default file system plug-in,
- * and may be replaced by vectors for other file system plug-ins.
- */
-
-static int fb_lfs_freemem(fb_fdesc_t *fd, off64_t size);
-static int fb_lfs_open(fb_fdesc_t *, char *, int, int);
-static int fb_lfs_pread(fb_fdesc_t *, caddr_t, fbint_t, off64_t);
-static int fb_lfs_read(fb_fdesc_t *, caddr_t, fbint_t);
-static int fb_lfs_pwrite(fb_fdesc_t *, caddr_t, fbint_t, off64_t);
-static int fb_lfs_write(fb_fdesc_t *, caddr_t, fbint_t);
-static int fb_lfs_lseek(fb_fdesc_t *, off64_t, int);
-static int fb_lfs_truncate(fb_fdesc_t *, off64_t);
-static int fb_lfs_rename(const char *, const char *);
-static int fb_lfs_close(fb_fdesc_t *);
-static int fb_lfs_link(const char *, const char *);
-static int fb_lfs_symlink(const char *, const char *);
-static int fb_lfs_unlink(char *);
-static ssize_t fb_lfs_readlink(const char *, char *, size_t);
-static int fb_lfs_mkdir(char *, int);
-static int fb_lfs_rmdir(char *);
-static DIR *fb_lfs_opendir(char *);
-static struct dirent *fb_lfs_readdir(DIR *);
-static int fb_lfs_closedir(DIR *);
-static int fb_lfs_fsync(fb_fdesc_t *);
-static int fb_lfs_stat(char *, struct stat64 *);
-static int fb_lfs_fstat(fb_fdesc_t *, struct stat64 *);
-static int fb_lfs_access(const char *, int);
-static void fb_lfs_recur_rm(char *);
-
-static fsplug_func_t fb_lfs_funcs =
-{
- "locfs",
- fb_lfs_freemem, /* flush page cache */
- fb_lfs_open, /* open */
- fb_lfs_pread, /* pread */
- fb_lfs_read, /* read */
- fb_lfs_pwrite, /* pwrite */
- fb_lfs_write, /* write */
- fb_lfs_lseek, /* lseek */
- fb_lfs_truncate, /* ftruncate */
- fb_lfs_rename, /* rename */
- fb_lfs_close, /* close */
- fb_lfs_link, /* link */
- fb_lfs_symlink, /* symlink */
- fb_lfs_unlink, /* unlink */
- fb_lfs_readlink, /* readlink */
- fb_lfs_mkdir, /* mkdir */
- fb_lfs_rmdir, /* rmdir */
- fb_lfs_opendir, /* opendir */
- fb_lfs_readdir, /* readdir */
- fb_lfs_closedir, /* closedir */
- fb_lfs_fsync, /* fsync */
- fb_lfs_stat, /* stat */
- fb_lfs_fstat, /* fstat */
- fb_lfs_access, /* access */
- fb_lfs_recur_rm /* recursive rm */
-};
-
-#ifdef HAVE_AIO
-/*
- * Local file system asynchronous IO flowops are in this module, as
- * they have a number of local file system specific features.
- */
-static int fb_lfsflow_aiowrite(threadflow_t *threadflow, flowop_t *flowop);
-static int fb_lfsflow_aiowait(threadflow_t *threadflow, flowop_t *flowop);
-
-static flowop_proto_t fb_lfsflow_funcs[] = {
- FLOW_TYPE_AIO, FLOW_ATTR_WRITE, "aiowrite", flowop_init_generic,
- fb_lfsflow_aiowrite, flowop_destruct_generic,
- FLOW_TYPE_AIO, 0, "aiowait", flowop_init_generic,
- fb_lfsflow_aiowait, flowop_destruct_generic
-};
-
-#endif /* HAVE_AIO */
-
-/*
- * Initialize this processes I/O functions vector to point to
- * the vector of local file system I/O functions
- */
-void
-fb_lfs_funcvecinit(void)
-{
- fs_functions_vec = &fb_lfs_funcs;
-}
-
-/*
- * Initialize those flowops whose implementation is file system
- * specific.
- */
-void
-fb_lfs_flowinit(void)
-{
- int nops;
-
- /*
- * re-initialize the I/O functions vector while we are at
- * it as it may have been redefined since the process was
- * created, at least if this is the master processes
- */
- fb_lfs_funcvecinit();
-
-#ifdef HAVE_AIO
- nops = sizeof (fb_lfsflow_funcs) / sizeof (flowop_proto_t);
- flowop_flow_init(fb_lfsflow_funcs, nops);
-#endif /* HAVE_AIO */
-}
-
-/*
- * Frees up memory mapped file region of supplied size. The
- * file descriptor "fd" indicates which memory mapped file.
- * If successful, returns 0. Otherwise returns -1 if "size"
- * is zero, or -1 times the number of times msync() failed.
- */
-static int
-fb_lfs_freemem(fb_fdesc_t *fd, off64_t size)
-{
- off64_t left;
- int ret = 0;
-
- for (left = size; left > 0; left -= MMAP_SIZE) {
- off64_t thismapsize;
- caddr_t addr;
-
- thismapsize = MIN(MMAP_SIZE, left);
- addr = mmap64(0, thismapsize, PROT_READ|PROT_WRITE,
- MAP_SHARED, fd->fd_num, size - left);
- ret += msync(addr, thismapsize, MS_INVALIDATE);
- (void) munmap(addr, thismapsize);
- }
- return (ret);
-}
-
-/*
- * Does a posix pread. Returns what the pread() returns.
- */
-static int
-fb_lfs_pread(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize, off64_t fileoffset)
-{
- return (pread64(fd->fd_num, iobuf, iosize, fileoffset));
-}
-
-/*
- * Does a posix read. Returns what the read() returns.
- */
-static int
-fb_lfs_read(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize)
-{
- return (read(fd->fd_num, iobuf, iosize));
-}
-
-#ifdef HAVE_AIO
-
-/*
- * Asynchronous write section. An Asynchronous IO element
- * (aiolist_t) is used to associate the asynchronous write request with
- * its subsequent completion. This element includes a aiocb64 struct
- * that is used by posix aio_xxx calls to track the asynchronous writes.
- * The flowops aiowrite and aiowait result in calls to these posix
- * aio_xxx system routines to do the actual asynchronous write IO
- * operations.
- */
-
-
-/*
- * Allocates an asynchronous I/O list (aio, of type
- * aiolist_t) element. Adds it to the flowop thread's
- * threadflow aio list. Returns a pointer to the element.
- */
-static aiolist_t *
-aio_allocate(flowop_t *flowop)
-{
- aiolist_t *aiolist;
-
- if ((aiolist = malloc(sizeof (aiolist_t))) == NULL) {
- filebench_log(LOG_ERROR, "malloc aiolist failed");
- filebench_shutdown(1);
- }
-
- /* Add to list */
- if (flowop->fo_thread->tf_aiolist == NULL) {
- flowop->fo_thread->tf_aiolist = aiolist;
- aiolist->al_next = NULL;
- } else {
- aiolist->al_next = flowop->fo_thread->tf_aiolist;
- flowop->fo_thread->tf_aiolist = aiolist;
- }
- return (aiolist);
-}
-
-/*
- * Searches for the aiolist element that has a matching
- * completion block, aiocb. If none found returns FILEBENCH_ERROR. If
- * found, removes the aiolist element from flowop thread's
- * list and returns FILEBENCH_OK.
- */
-static int
-aio_deallocate(flowop_t *flowop, struct aiocb64 *aiocb)
-{
- aiolist_t *aiolist = flowop->fo_thread->tf_aiolist;
- aiolist_t *previous = NULL;
- aiolist_t *match = NULL;
-
- if (aiocb == NULL) {
- filebench_log(LOG_ERROR, "null aiocb deallocate");
- return (FILEBENCH_OK);
- }
-
- while (aiolist) {
- if (aiocb == &(aiolist->al_aiocb)) {
- match = aiolist;
- break;
- }
- previous = aiolist;
- aiolist = aiolist->al_next;
- }
-
- if (match == NULL)
- return (FILEBENCH_ERROR);
-
- /* Remove from the list */
- if (previous)
- previous->al_next = match->al_next;
- else
- flowop->fo_thread->tf_aiolist = match->al_next;
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate posix aiowrite(). Determines which file to use,
- * either one file of a fileset, or the file associated
- * with a fileobj, allocates and fills an aiolist_t element
- * for the write, and issues the asynchronous write. This
- * operation is only valid for random IO, and returns an
- * error if the flowop is set for sequential IO. Returns
- * FILEBENCH_OK on success, FILEBENCH_NORSC if iosetup can't
- * obtain a file to open, and FILEBENCH_ERROR on any
- * encountered error.
- */
-static int
-fb_lfsflow_aiowrite(threadflow_t *threadflow, flowop_t *flowop)
-{
- caddr_t iobuf;
- fbint_t wss;
- fbint_t iosize;
- fb_fdesc_t *fdesc;
- int ret;
-
- iosize = avd_get_int(flowop->fo_iosize);
-
- if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf,
- &fdesc, iosize)) != FILEBENCH_OK)
- return (ret);
-
- if (avd_get_bool(flowop->fo_random)) {
- uint64_t fileoffset;
- struct aiocb64 *aiocb;
- aiolist_t *aiolist;
-
- if (filebench_randomno64(&fileoffset,
- wss, iosize, NULL) == -1) {
- filebench_log(LOG_ERROR,
- "file size smaller than IO size for thread %s",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- aiolist = aio_allocate(flowop);
- aiolist->al_type = AL_WRITE;
- aiocb = &aiolist->al_aiocb;
-
- aiocb->aio_fildes = fdesc->fd_num;
- aiocb->aio_buf = iobuf;
- aiocb->aio_nbytes = (size_t)iosize;
- aiocb->aio_offset = (off64_t)fileoffset;
- aiocb->aio_reqprio = 0;
-
- filebench_log(LOG_DEBUG_IMPL,
- "aio fd=%d, bytes=%llu, offset=%llu",
- fdesc->fd_num, (u_longlong_t)iosize,
- (u_longlong_t)fileoffset);
-
- flowop_beginop(threadflow, flowop);
- if (aio_write64(aiocb) < 0) {
- filebench_log(LOG_ERROR, "aiowrite failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
- flowop_endop(threadflow, flowop, iosize);
- } else {
- return (FILEBENCH_ERROR);
- }
-
- return (FILEBENCH_OK);
-}
-
-
-
-#define MAXREAP 4096
-
-/*
- * Emulate posix aiowait(). Waits for the completion of half the
- * outstanding asynchronous IOs, or a single IO, which ever is
- * larger. The routine will return after a sufficient number of
- * completed calls issued by any thread in the procflow have
- * completed, or a 1 second timout elapses. All completed
- * IO operations are deleted from the thread's aiolist.
- */
-static int
-fb_lfsflow_aiowait(threadflow_t *threadflow, flowop_t *flowop)
-{
- struct aiocb64 **worklist;
- aiolist_t *aio = flowop->fo_thread->tf_aiolist;
- int uncompleted = 0;
-
- worklist = calloc(MAXREAP, sizeof (struct aiocb64 *));
-
- /* Count the list of pending aios */
- while (aio) {
- uncompleted++;
- aio = aio->al_next;
- }
-
- do {
- uint_t ncompleted = 0;
- uint_t todo;
- struct timespec timeout;
- int inprogress;
- int i;
-
- /* Wait for half of the outstanding requests */
- timeout.tv_sec = 1;
- timeout.tv_nsec = 0;
-
- if (uncompleted > MAXREAP)
- todo = MAXREAP;
- else
- todo = uncompleted / 2;
-
- if (todo == 0)
- todo = 1;
-
- flowop_beginop(threadflow, flowop);
-
-#if (defined(HAVE_AIOWAITN) && defined(USE_PROCESS_MODEL))
- if (((aio_waitn64((struct aiocb64 **)worklist,
- MAXREAP, &todo, &timeout)) == -1) &&
- errno && (errno != ETIME)) {
- filebench_log(LOG_ERROR,
- "aiowait failed: %s, outstanding = %d, "
- "ncompleted = %d ",
- strerror(errno), uncompleted, todo);
- }
-
- ncompleted = todo;
- /* Take the completed I/Os from the list */
- inprogress = 0;
- for (i = 0; i < ncompleted; i++) {
- if ((aio_return64(worklist[i]) == -1) &&
- (errno == EINPROGRESS)) {
- inprogress++;
- continue;
- }
- if (aio_deallocate(flowop, worklist[i])
- == FILEBENCH_ERROR) {
- filebench_log(LOG_ERROR, "Could not remove "
- "aio from list ");
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
- }
-
- uncompleted -= ncompleted;
- uncompleted += inprogress;
-
-#else
-
- for (ncompleted = 0, inprogress = 0,
- aio = flowop->fo_thread->tf_aiolist;
- ncompleted < todo, aio != NULL; aio = aio->al_next) {
- int result = aio_error64(&aio->al_aiocb);
-
- if (result == EINPROGRESS) {
- inprogress++;
- continue;
- }
-
- if ((aio_return64(&aio->al_aiocb) == -1) || result) {
- filebench_log(LOG_ERROR, "aio failed: %s",
- strerror(result));
- continue;
- }
-
- ncompleted++;
-
- if (aio_deallocate(flowop, &aio->al_aiocb) < 0) {
- filebench_log(LOG_ERROR, "Could not remove "
- "aio from list ");
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
- }
-
- uncompleted -= ncompleted;
-
-#endif
- filebench_log(LOG_DEBUG_SCRIPT,
- "aio2 completed %d ios, uncompleted = %d, inprogress = %d",
- ncompleted, uncompleted, inprogress);
-
- } while (uncompleted > MAXREAP);
-
- flowop_endop(threadflow, flowop, 0);
-
- free(worklist);
-
- return (FILEBENCH_OK);
-}
-
-#endif /* HAVE_AIO */
-
-/*
- * Does an open64 of a file. Inserts the file descriptor number returned
- * by open() into the supplied filebench fd. Returns FILEBENCH_OK on
- * successs, and FILEBENCH_ERROR on failure.
- */
-
-static int
-fb_lfs_open(fb_fdesc_t *fd, char *path, int flags, int perms)
-{
- if ((fd->fd_num = open64(path, flags, perms)) < 0)
- return (FILEBENCH_ERROR);
- else
- return (FILEBENCH_OK);
-}
-
-/*
- * Does an unlink (delete) of a file.
- */
-static int
-fb_lfs_unlink(char *path)
-{
- return (unlink(path));
-}
-
-/*
- * Does a readlink of a symbolic link.
- */
-static ssize_t
-fb_lfs_readlink(const char *path, char *buf, size_t buf_size)
-{
- return (readlink(path, buf, buf_size));
-}
-
-/*
- * Does fsync of a file. Returns with fsync return info.
- */
-static int
-fb_lfs_fsync(fb_fdesc_t *fd)
-{
- return (fsync(fd->fd_num));
-}
-
-/*
- * Do a posix lseek of a file. Return what lseek() returns.
- */
-static int
-fb_lfs_lseek(fb_fdesc_t *fd, off64_t offset, int whence)
-{
- return (lseek64(fd->fd_num, offset, whence));
-}
-
-/*
- * Do a posix rename of a file. Return what rename() returns.
- */
-static int
-fb_lfs_rename(const char *old, const char *new)
-{
- return (rename(old, new));
-}
-
-
-/*
- * Do a posix close of a file. Return what close() returns.
- */
-static int
-fb_lfs_close(fb_fdesc_t *fd)
-{
- return (close(fd->fd_num));
-}
-
-/*
- * Use mkdir to create a directory.
- */
-static int
-fb_lfs_mkdir(char *path, int perm)
-{
- return (mkdir(path, perm));
-}
-
-/*
- * Use rmdir to delete a directory. Returns what rmdir() returns.
- */
-static int
-fb_lfs_rmdir(char *path)
-{
- return (rmdir(path));
-}
-
-/*
- * does a recursive rm to remove an entire directory tree (i.e. a fileset).
- * Supplied with the path to the root of the tree.
- */
-static void
-fb_lfs_recur_rm(char *path)
-{
- char cmd[MAXPATHLEN];
-
- (void) snprintf(cmd, sizeof (cmd), "rm -rf %s", path);
- (void) system(cmd);
-}
-
-/*
- * Does a posix opendir(), Returns a directory handle on success,
- * NULL on failure.
- */
-static DIR *
-fb_lfs_opendir(char *path)
-{
- return (opendir(path));
-}
-
-/*
- * Does a readdir() call. Returns a pointer to a table of directory
- * information on success, NULL on failure.
- */
-static struct dirent *
-fb_lfs_readdir(DIR *dirp)
-{
- return (readdir(dirp));
-}
-
-/*
- * Does a closedir() call.
- */
-static int
-fb_lfs_closedir(DIR *dirp)
-{
- return (closedir(dirp));
-}
-
-/*
- * Does an fstat of a file.
- */
-static int
-fb_lfs_fstat(fb_fdesc_t *fd, struct stat64 *statbufp)
-{
- return (fstat64(fd->fd_num, statbufp));
-}
-
-/*
- * Does a stat of a file.
- */
-static int
-fb_lfs_stat(char *path, struct stat64 *statbufp)
-{
- return (stat64(path, statbufp));
-}
-
-/*
- * Do a pwrite64 to a file.
- */
-static int
-fb_lfs_pwrite(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize, off64_t offset)
-{
- return (pwrite64(fd->fd_num, iobuf, iosize, offset));
-}
-
-/*
- * Do a write to a file.
- */
-static int
-fb_lfs_write(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize)
-{
- return (write(fd->fd_num, iobuf, iosize));
-}
-
-/*
- * Does a truncate operation and returns the result
- */
-static int
-fb_lfs_truncate(fb_fdesc_t *fd, off64_t fse_size)
-{
-#ifdef HAVE_FTRUNCATE64
- return (ftruncate64(fd->fd_num, fse_size));
-#else
- return (ftruncate(fd->fd_num, (off_t)fse_size));
-#endif
-}
-
-/*
- * Does a link operation and returns the result
- */
-static int
-fb_lfs_link(const char *existing, const char *new)
-{
- return (link(existing, new));
-}
-
-/*
- * Does a symlink operation and returns the result
- */
-static int
-fb_lfs_symlink(const char *existing, const char *new)
-{
- return (symlink(existing, new));
-}
-
-/*
- * Does an access() check on a file.
- */
-static int
-fb_lfs_access(const char *path, int amode)
-{
- return (access(path, amode));
-}
diff --git a/usr/src/cmd/filebench/common/fb_random.c b/usr/src/cmd/filebench/common/fb_random.c
deleted file mode 100644
index 39872dc8ee..0000000000
--- a/usr/src/cmd/filebench/common/fb_random.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <math.h>
-#include "filebench.h"
-#include "ipc.h"
-#include "gamma_dist.h"
-
-static int urandomfd;
-
-/*
- * Reads a 64 bit random number from the urandom "file".
- * Shuts down the run if the read fails. Otherwise returns
- * the random number after rounding it off by "round".
- * Returns 0 on success, -1 on failure.
- */
-int
-filebench_randomno64(uint64_t *randp, uint64_t max,
- uint64_t round, avd_t avd)
-{
- uint64_t random;
-
- /* check for round value too large */
- if (max <= round) {
- *randp = 0;
-
- /* if it just fits, its ok, otherwise error */
- if (max == round)
- return (0);
- else
- return (-1);
- }
-
- if (avd) {
-
- /* get it from the variable */
- random = avd_get_int(avd);
-
- } else {
-
- /* get it from urandom */
- if (read(urandomfd, &random,
- sizeof (uint64_t)) != sizeof (uint64_t)) {
- filebench_log(LOG_ERROR,
- "read /dev/urandom failed: %s", strerror(errno));
- filebench_shutdown(1);
- }
- }
-
- /* clip with max and optionally round */
- max -= round;
- random = random / (FILEBENCH_RANDMAX64 / max);
- if (round) {
- random = random / round;
- random *= round;
- }
- if (random > max)
- random = max;
-
- *randp = random;
- return (0);
-}
-
-
-/*
- * Reads a 32 bit random number from the urandom "file".
- * Shuts down the run if the read fails. Otherwise returns
- * the random number after rounding it off by "round".
- * Returns 0 on success, -1 on failure.
- */
-int
-filebench_randomno32(uint32_t *randp, uint32_t max,
- uint32_t round, avd_t avd)
-{
- uint32_t random;
-
- /* check for round value too large */
- if (max <= round) {
- *randp = 0;
-
- /* if it just fits, its ok, otherwise error */
- if (max == round)
- return (0);
- else
- return (-1);
- }
-
- if (avd) {
-
- /* get it from the variable */
- random = (uint32_t)avd_get_int(avd);
-
- } else {
-
- /* get it from urandom */
- if (read(urandomfd, &random,
- sizeof (uint32_t)) != sizeof (uint32_t)) {
- filebench_log(LOG_ERROR,
- "read /dev/urandom failed: %s", strerror(errno));
- filebench_shutdown(1);
- }
- }
-
- /* clip with max and optionally round */
- max -= round;
- random = random / (FILEBENCH_RANDMAX32 / max);
- if (round) {
- random = random / round;
- random *= round;
- }
- if (random > max)
- random = max;
-
- *randp = random;
- return (0);
-}
-
-/*
- * fetch a source random number from the pseudo random number generator:
- * erand48()
- */
-static double
-rand_src_rand48(unsigned short *xi)
-{
- return (erand48(xi));
-}
-
-/*
- * fetch a source random number from the hardware random number device:
- * urandomfd. Convert it to a floating point probability.
- */
-/* ARGSUSED */
-static double
-rand_src_urandom(unsigned short *xi)
-{
- fbint_t randnum;
-
- if (read(urandomfd, &randnum,
- sizeof (fbint_t)) != sizeof (fbint_t)) {
- filebench_log(LOG_ERROR,
- "read /dev/urandom failed: %s", strerror(errno));
- filebench_shutdown(1);
- return (0.0);
- }
-
- /* convert to 0-1 probability */
- return ((double)randnum / (double)(FILEBENCH_RANDMAX64));
-}
-
-/*
- * fetch a uniformly distributed random number from the supplied
- * random object.
- */
-static double
-rand_uniform_get(randdist_t *rndp)
-{
- double dprob, dmin, dres, dround;
-
- dmin = (double)rndp->rnd_vint_min;
- dround = (double)rndp->rnd_vint_round;
-
- dprob = (*rndp->rnd_src)(rndp->rnd_xi);
-
- dres = (dprob * (2.0 * (rndp->rnd_dbl_mean - dmin))) + dmin;
-
- if (dround == 0.0)
- return (dres);
- else
- return (round(dres / dround) * dround);
-}
-
-/*
- * fetch a gamma distributed random number from the supplied
- * random object.
- */
-static double
-rand_gamma_get(randdist_t *rndp)
-{
- double dmult, dres, dmin, dround;
-
- dmin = (double)rndp->rnd_vint_min;
- dround = (double)rndp->rnd_vint_round;
-
- dmult = (rndp->rnd_dbl_mean - dmin) / rndp->rnd_dbl_gamma;
-
- dres = gamma_dist_knuth_src(rndp->rnd_dbl_gamma,
- dmult, rndp->rnd_src, rndp->rnd_xi) + dmin;
-
- if (dround == 0.0)
- return (dres);
- else
- return (round(dres / dround) * dround);
-}
-
-/*
- * fetch a table driven random number from the supplied
- * random object.
- */
-static double
-rand_table_get(randdist_t *rndp)
-{
- double dprob, dprcnt, dtabres, dsclres, dmin, dround;
- int idx;
-
- dmin = (double)rndp->rnd_vint_min;
- dround = (double)rndp->rnd_vint_round;
-
- dprob = (*rndp->rnd_src)(rndp->rnd_xi);
-
- dprcnt = (dprob * (double)(PF_TAB_SIZE));
- idx = (int)dprcnt;
-
- dtabres = (rndp->rnd_rft[idx].rf_base +
- (rndp->rnd_rft[idx].rf_range * (dprcnt - (double)idx)));
-
- dsclres = (dtabres * (rndp->rnd_dbl_mean - dmin)) + dmin;
-
- if (dround == 0.0)
- return (dsclres);
- else
- return (round(dsclres / dround) * dround);
-}
-
-/*
- * Set the random seed in the supplied random object.
- */
-static void
-rand_seed_set(randdist_t *rndp)
-{
- union {
- uint64_t ll;
- uint16_t w[4];
- } temp1;
- int idx;
-
- temp1.ll = (uint64_t)avd_get_int(rndp->rnd_seed);
-
- for (idx = 0; idx < 3; idx++) {
-
-#ifdef _BIG_ENDIAN
- rndp->rnd_xi[idx] = temp1.w[3-idx];
-#else
- rndp->rnd_xi[idx] = temp1.w[idx];
-#endif
- }
-}
-
-/*
- * Define a random entity which will contain the parameters of a random
- * distribution.
- */
-randdist_t *
-randdist_alloc(void)
-{
- randdist_t *rndp;
-
- if ((rndp = (randdist_t *)ipc_malloc(FILEBENCH_RANDDIST)) == NULL) {
- filebench_log(LOG_ERROR, "Out of memory for random dist");
- return (NULL);
- }
-
- /* place on global list */
- rndp->rnd_next = filebench_shm->shm_rand_list;
- filebench_shm->shm_rand_list = rndp;
-
- return (rndp);
-}
-
-/*
- * Initializes a random distribution entity, converting avd_t
- * parameters to doubles, and converting the list of probability density
- * function table entries, if supplied, into a probablilty function table
- */
-static void
-randdist_init_one(randdist_t *rndp)
-{
- probtabent_t *rdte_hdp, *ptep;
- double tablemean, tablemin;
- int pteidx;
-
- /* convert parameters to doubles */
- rndp->rnd_dbl_gamma = (double)avd_get_int(rndp->rnd_gamma) / 1000.0;
- if (rndp->rnd_mean != NULL)
- rndp->rnd_dbl_mean = (double)avd_get_int(rndp->rnd_mean);
- else
- rndp->rnd_dbl_mean = rndp->rnd_dbl_gamma;
-
- /* de-reference min and round amounts for later use */
- rndp->rnd_vint_min = avd_get_int(rndp->rnd_min);
- rndp->rnd_vint_round = avd_get_int(rndp->rnd_round);
-
- filebench_log(LOG_DEBUG_IMPL,
- "init random var %s: Mean = %6.0llf, Gamma = %6.3llf, Min = %llu",
- rndp->rnd_var->var_name, rndp->rnd_dbl_mean, rndp->rnd_dbl_gamma,
- (u_longlong_t)rndp->rnd_vint_min);
-
- /* initialize distribution to apply */
- switch (rndp->rnd_type & RAND_TYPE_MASK) {
- case RAND_TYPE_UNIFORM:
- rndp->rnd_get = rand_uniform_get;
- break;
-
- case RAND_TYPE_GAMMA:
- rndp->rnd_get = rand_gamma_get;
- break;
-
- case RAND_TYPE_TABLE:
- rndp->rnd_get = rand_table_get;
- break;
-
- default:
- filebench_log(LOG_DEBUG_IMPL, "Random Type not Specified");
- filebench_shutdown(1);
- return;
- }
-
- /* initialize source of random numbers */
- if (rndp->rnd_type & RAND_SRC_GENERATOR) {
- rndp->rnd_src = rand_src_rand48;
- rand_seed_set(rndp);
- } else {
- rndp->rnd_src = rand_src_urandom;
- }
-
- /* any random distribution table to convert? */
- if ((rdte_hdp = rndp->rnd_probtabs) == NULL)
- return;
-
- /* determine random distribution max and mins and initialize table */
- pteidx = 0;
- tablemean = 0.0;
- for (ptep = rdte_hdp; ptep; ptep = ptep->pte_next) {
- double dmin, dmax;
- int entcnt;
-
- dmax = (double)avd_get_int(ptep->pte_segmax);
- dmin = (double)avd_get_int(ptep->pte_segmin);
-
- /* initialize table minimum on first pass */
- if (pteidx == 0)
- tablemin = dmin;
-
- /* update table minimum */
- if (tablemin > dmin)
- tablemin = dmin;
-
- entcnt = (int)avd_get_int(ptep->pte_percent);
- tablemean += (((dmin + dmax)/2.0) * (double)entcnt);
-
- /* populate the lookup table */
-
- for (; entcnt > 0; entcnt--) {
- rndp->rnd_rft[pteidx].rf_base = dmin;
- rndp->rnd_rft[pteidx].rf_range = dmax - dmin;
- pteidx++;
- }
- }
-
- /* check to see if probability equals 100% */
- if (pteidx != PF_TAB_SIZE)
- filebench_log(LOG_ERROR,
- "Prob table only totals %d%%", pteidx);
-
- /* If table is not supplied with a mean value, set it to table mean */
- if (rndp->rnd_dbl_mean == 0.0)
- rndp->rnd_dbl_mean = (double)tablemean / (double)PF_TAB_SIZE;
-
- /* now normalize the entries for a min value of 0, mean of 1 */
- tablemean = (tablemean / 100.0) - tablemin;
-
- /* special case if really a constant value */
- if (tablemean == 0.0) {
- for (pteidx = 0; pteidx < PF_TAB_SIZE; pteidx++) {
- rndp->rnd_rft[pteidx].rf_base = 0.0;
- rndp->rnd_rft[pteidx].rf_range = 0.0;
- }
- return;
- }
-
- for (pteidx = 0; pteidx < PF_TAB_SIZE; pteidx++) {
-
- rndp->rnd_rft[pteidx].rf_base =
- ((rndp->rnd_rft[pteidx].rf_base - tablemin) / tablemean);
- rndp->rnd_rft[pteidx].rf_range =
- (rndp->rnd_rft[pteidx].rf_range / tablemean);
- }
-}
-
-/*
- * initialize all the random distribution entities
- */
-void
-randdist_init(void)
-{
- randdist_t *rndp;
-
- for (rndp = filebench_shm->shm_rand_list; rndp; rndp = rndp->rnd_next)
- randdist_init_one(rndp);
-}
-
-/*
- * Initialize the urandom random number source
- */
-void
-fb_random_init(void)
-{
- /* open the "urandom" random number device file */
- if ((urandomfd = open("/dev/urandom", O_RDONLY)) < 0) {
- filebench_log(LOG_ERROR, "open /dev/urandom failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
-}
diff --git a/usr/src/cmd/filebench/common/fb_random.h b/usr/src/cmd/filebench/common/fb_random.h
deleted file mode 100644
index 027b299d26..0000000000
--- a/usr/src/cmd/filebench/common/fb_random.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_RANDOM_H
-#define _FB_RANDOM_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "config.h"
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * probability table entry, used while parsing the supplied
- * probability table
- */
-typedef struct probtabent {
- struct probtabent *pte_next;
- avd_t pte_percent;
- avd_t pte_segmin;
- avd_t pte_segmax;
-} probtabent_t;
-
-/*
- * The supplied probability table is converted into a probability funtion
- * lookup table at initialization time. This is the definition for each
- * entry in the table.
- */
-typedef struct randfunc {
- double rf_base;
- double rf_range;
-} randfunc_t;
-
-/* Number of entries in the probability function table */
-#define PF_TAB_SIZE 100
-
-/*
- * Random Distribution definition object. Includes a pointer to the
- * appropriate function to access the distribution defined by the object,
- * as well as a function pointer to the specified source of random
- * numbers.
- */
-typedef struct randdist {
- double (*rnd_get)(struct randdist *);
- double (*rnd_src)(unsigned short *);
- struct randdist *rnd_next;
- struct var *rnd_var;
- avd_t rnd_seed;
- avd_t rnd_mean;
- avd_t rnd_gamma;
- avd_t rnd_min;
- avd_t rnd_round;
- double rnd_dbl_mean;
- double rnd_dbl_gamma;
- fbint_t rnd_vint_min;
- fbint_t rnd_vint_round;
- probtabent_t *rnd_probtabs;
- randfunc_t rnd_rft[PF_TAB_SIZE];
- uint16_t rnd_xi[3];
- uint16_t rnd_type;
-} randdist_t;
-
-#define RAND_TYPE_UNIFORM 0x1
-#define RAND_TYPE_GAMMA 0x2
-#define RAND_TYPE_TABLE 0x3
-#define RAND_TYPE_MASK 0x0fff
-#define RAND_SRC_URANDOM 0x0000
-#define RAND_SRC_GENERATOR 0x1000
-
-#define RAND_PARAM_TYPE 1
-#define RAND_PARAM_SRC 2
-#define RAND_PARAM_SEED 3
-#define RAND_PARAM_MIN 4
-#define RAND_PARAM_MEAN 5
-#define RAND_PARAM_GAMMA 6
-#define RAND_PARAM_ROUND 7
-
-randdist_t *randdist_alloc(void);
-void randdist_init(void);
-int filebench_randomno32(uint32_t *, uint32_t, uint32_t, avd_t);
-int filebench_randomno64(uint64_t *, uint64_t, uint64_t, avd_t);
-void fb_random_init(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_RANDOM_H */
diff --git a/usr/src/cmd/filebench/common/filebench.h b/usr/src/cmd/filebench/common/filebench.h
deleted file mode 100644
index 9564bc7c9c..0000000000
--- a/usr/src/cmd/filebench/common/filebench.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#ifndef _FB_FILEBENCH_H
-#define _FB_FILEBENCH_H
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#ifndef HAVE_BOOLEAN_T
-typedef enum { B_FALSE, B_TRUE } boolean_t;
-#endif
-
-#ifndef HAVE_U_LONGLONG_T
-typedef unsigned long long u_longlong_t;
-#endif
-
-#ifndef HAVE_UINT_T
-typedef unsigned int uint_t;
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#include "procflow.h"
-#include "misc.h"
-#include "ipc.h"
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-
-#ifdef __STDC__
-#include <stdarg.h>
-#define __V(x) x
-#ifndef __P
-#define __P(x) x
-#endif
-#else
-#include <varargs.h>
-#define __V(x) (va_alist) va_dcl
-#define __P(x) ()
-#define const
-#endif
-
-#include <sys/times.h>
-
-#ifdef HAVE_SYS_INT_LIMITS_H
-#include <sys/int_limits.h>
-#endif /* HAVE_SYS_INT_LIMITS_H */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern pid_t my_pid; /* this process' process id */
-extern procflow_t *my_procflow; /* if slave process, procflow pointer */
-extern int errno;
-extern char *execname;
-extern char *fbbasepath;
-extern int noproc;
-
-void filebench_init();
-void filebench_log __V((int level, const char *fmt, ...));
-void filebench_shutdown(int error);
-void filebench_plugin_funcvecinit(void);
-
-#ifndef HAVE_UINT64_MAX
-#define UINT64_MAX (((off64_t)1UL<<63UL) - 1UL)
-#endif
-
-#define FILEBENCH_RANDMAX64 UINT64_MAX
-#define FILEBENCH_RANDMAX32 UINT32_MAX
-
-#if defined(_LP64) || (__WORDSIZE == 64)
-#define filebench_randomno filebench_randomno64
-#define FILEBENCH_RANDMAX FILEBENCH_RANDMAX64
-#else
-#define filebench_randomno filebench_randomno32
-#define FILEBENCH_RANDMAX FILEBENCH_RANDMAX32
-#endif
-
-#define KB (1024LL)
-#define MB (KB * KB)
-#define GB (KB * MB)
-
-#define MMAP_SIZE (1024UL * 1024UL * 1024UL)
-
-#ifndef MIN
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#endif
-
-#define FILEBENCH_VERSION "1.4.8"
-#define FILEBENCHDIR "/usr/benchmarks/filebench"
-#define FILEBENCH_PROMPT "filebench> "
-#define MAX_LINE_LEN 1024
-#define MAX_CMD_HIST 128
-#define SHUTDOWN_WAIT_SECONDS 3 /* time to wait for proc / thrd to quit */
-
-#define FILEBENCH_DONE 1
-#define FILEBENCH_OK 0
-#define FILEBENCH_ERROR -1
-#define FILEBENCH_NORSC -2
-
-/* For MacOSX */
-#ifndef HAVE_OFF64_T
-#define mmap64 mmap
-#define off64_t off_t
-#define open64 open
-#define stat64 stat
-#define pread64 pread
-#define pwrite64 pwrite
-#define lseek64 lseek
-#define fstat64 fstat
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_FILEBENCH_H */
diff --git a/usr/src/cmd/filebench/common/fileset.c b/usr/src/cmd/filebench/common/fileset.c
deleted file mode 100644
index 38a075be42..0000000000
--- a/usr/src/cmd/filebench/common/fileset.c
+++ /dev/null
@@ -1,1980 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#include <fcntl.h>
-#include <pthread.h>
-#include <errno.h>
-#include <math.h>
-#include <libgen.h>
-#include <sys/mman.h>
-#include <sys/shm.h>
-
-#include "filebench.h"
-#include "fileset.h"
-#include "gamma_dist.h"
-#include "utils.h"
-#include "fsplug.h"
-
-/*
- * File sets, of type fileset_t, are entities which contain
- * information about collections of files and subdirectories in Filebench.
- * The fileset, once populated, consists of a tree of fileset entries of
- * type filesetentry_t which specify files and directories. The fileset
- * is rooted in a directory specified by fileset_path, and once the populated
- * fileset has been created, has a tree of directories and files
- * corresponding to the fileset's filesetentry tree.
- *
- * Fileset entities are allocated by fileset_define() which is called from
- * parser_gram.y: parser_fileset_define(). The filesetentry tree corrseponding
- * to the eventual directory and file tree to be instantiated on the storage
- * medium is built by fileset_populate(), which is This routine is called
- * from fileset_createset(), which is in turn called by fileset_createset().
- * After calling fileset_populate(), fileset_createset() will call
- * fileset_create() to pre-allocate designated files and directories.
- *
- * Fileset_createset() is called from parser_gram.y: parser_create_fileset()
- * when a "create fileset" or "run" command is encountered. When the
- * "create fileset" command is used, it is generally paired with
- * a "create processes" command, and must appear first, in order to
- * instantiate all the files in the fileset before trying to use them.
- */
-
-static int fileset_checkraw(fileset_t *fileset);
-
-/* maximum parallel allocation control */
-#define MAX_PARALLOC_THREADS 32
-
-/*
- * returns pointer to file or fileset
- * string, as appropriate
- */
-static char *
-fileset_entity_name(fileset_t *fileset)
-{
- if (fileset->fs_attrs & FILESET_IS_FILE)
- return ("file");
- else
- return ("fileset");
-}
-
-/*
- * Removes the last file or directory name from a pathname.
- * Basically removes characters from the end of the path by
- * setting them to \0 until a forward slash '/' is
- * encountered. It also removes the forward slash.
- */
-static char *
-trunc_dirname(char *dir)
-{
- char *s = dir + strlen(dir);
-
- while (s != dir) {
- int c = *s;
-
- *s = 0;
- if (c == '/')
- break;
- s--;
- }
- return (dir);
-}
-
-/*
- * Prints a list of allowed options and how to specify them.
- */
-void
-fileset_usage(void)
-{
- (void) fprintf(stderr,
- "define [file name=<name> | fileset name=<name>],path=<pathname>,"
- ",entries=<number>\n");
- (void) fprintf(stderr,
- " [,filesize=[size]]\n");
- (void) fprintf(stderr,
- " [,dirwidth=[width]]\n");
- (void) fprintf(stderr,
- " [,dirdepthrv=$random_variable_name]\n");
- (void) fprintf(stderr,
- " [,dirgamma=[100-10000]] "
- "(Gamma * 1000)\n");
- (void) fprintf(stderr,
- " [,sizegamma=[100-10000]] (Gamma * 1000)\n");
- (void) fprintf(stderr,
- " [,prealloc=[percent]]\n");
- (void) fprintf(stderr, " [,paralloc]\n");
- (void) fprintf(stderr, " [,reuse]\n");
- (void) fprintf(stderr, "\n");
-}
-
-/*
- * Creates a path string from the filesetentry_t "*entry"
- * and all of its parent's path names. The resulting path
- * is a concatination of all the individual parent paths.
- * Allocates memory for the path string and returns a
- * pointer to it.
- */
-char *
-fileset_resolvepath(filesetentry_t *entry)
-{
- filesetentry_t *fsep = entry;
- char path[MAXPATHLEN];
- char pathtmp[MAXPATHLEN];
- char *s;
-
- path[0] = '\0';
- while (fsep->fse_parent) {
- (void) strcpy(pathtmp, "/");
- (void) fb_strlcat(pathtmp, fsep->fse_path, MAXPATHLEN);
- (void) fb_strlcat(pathtmp, path, MAXPATHLEN);
- (void) fb_strlcpy(path, pathtmp, MAXPATHLEN);
- fsep = fsep->fse_parent;
- }
-
- s = malloc(strlen(path) + 1);
- (void) fb_strlcpy(s, path, MAXPATHLEN);
- return (s);
-}
-
-/*
- * Creates multiple nested directories as required by the
- * supplied path. Starts at the end of the path, creating
- * a list of directories to mkdir, up to the root of the
- * path, then mkdirs them one at a time from the root on down.
- */
-static int
-fileset_mkdir(char *path, int mode)
-{
- char *p;
- char *dirs[65536];
- int i = 0;
-
- if ((p = strdup(path)) == NULL)
- goto null_str;
-
- /*
- * Fill an array of subdirectory path names until either we
- * reach the root or encounter an already existing subdirectory
- */
- /* CONSTCOND */
- while (1) {
- struct stat64 sb;
-
- if (stat64(p, &sb) == 0)
- break;
- if (strlen(p) < 3)
- break;
- if ((dirs[i] = strdup(p)) == NULL) {
- free(p);
- goto null_str;
- }
-
- (void) trunc_dirname(p);
- i++;
- }
-
- /* Make the directories, from closest to root downwards. */
- for (--i; i >= 0; i--) {
- (void) FB_MKDIR(dirs[i], mode);
- free(dirs[i]);
- }
-
- free(p);
- return (FILEBENCH_OK);
-
-null_str:
- /* clean up */
- for (--i; i >= 0; i--)
- free(dirs[i]);
-
- filebench_log(LOG_ERROR,
- "Failed to create directory path %s: Out of memory", path);
- return (FILEBENCH_ERROR);
-}
-
-/*
- * creates the subdirectory tree for a fileset.
- */
-static int
-fileset_create_subdirs(fileset_t *fileset, char *filesetpath)
-{
- filesetentry_t *direntry;
- char full_path[MAXPATHLEN];
- char *part_path;
-
- /* walk the subdirectory list, enstanciating subdirs */
- direntry = fileset->fs_dirlist;
- while (direntry) {
- (void) fb_strlcpy(full_path, filesetpath, MAXPATHLEN);
- part_path = fileset_resolvepath(direntry);
- (void) fb_strlcat(full_path, part_path, MAXPATHLEN);
- free(part_path);
-
- /* now create this portion of the subdirectory tree */
- if (fileset_mkdir(full_path, 0755) == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
-
- direntry = direntry->fse_nextoftype;
- }
- return (FILEBENCH_OK);
-}
-
-/*
- * move filesetentry between exist tree and non-exist tree, source_tree
- * to destination tree.
- */
-static void
-fileset_move_entry(avl_tree_t *src_tree, avl_tree_t *dst_tree,
- filesetentry_t *entry)
-{
- avl_remove(src_tree, entry);
- avl_add(dst_tree, entry);
-}
-
-/*
- * given a fileset entry, determines if the associated leaf directory
- * needs to be made or not, and if so does the mkdir.
- */
-static int
-fileset_alloc_leafdir(filesetentry_t *entry)
-{
- fileset_t *fileset;
- char path[MAXPATHLEN];
- struct stat64 sb;
- char *pathtmp;
-
- fileset = entry->fse_fileset;
- (void) fb_strlcpy(path, avd_get_str(fileset->fs_path), MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, avd_get_str(fileset->fs_name), MAXPATHLEN);
- pathtmp = fileset_resolvepath(entry);
- (void) fb_strlcat(path, pathtmp, MAXPATHLEN);
- free(pathtmp);
-
- filebench_log(LOG_DEBUG_IMPL, "Populated %s", entry->fse_path);
-
- /* see if not reusing and this directory does not exist */
- if (!((entry->fse_flags & FSE_REUSING) && (stat64(path, &sb) == 0))) {
-
- /* No file or not reusing, so create */
- if (FB_MKDIR(path, 0755) < 0) {
- filebench_log(LOG_ERROR,
- "Failed to pre-allocate leaf directory %s: %s",
- path, strerror(errno));
- fileset_unbusy(entry, TRUE, FALSE, 0);
- return (FILEBENCH_ERROR);
- }
- }
-
- /* unbusy the allocated entry */
- fileset_unbusy(entry, TRUE, TRUE, 0);
- return (FILEBENCH_OK);
-}
-
-/*
- * given a fileset entry, determines if the associated file
- * needs to be allocated or not, and if so does the allocation.
- */
-static int
-fileset_alloc_file(filesetentry_t *entry)
-{
- fileset_t *fileset;
- char path[MAXPATHLEN];
- char *buf;
- struct stat64 sb;
- char *pathtmp;
- off64_t seek;
- fb_fdesc_t fdesc;
- int trust_tree;
-
- fileset = entry->fse_fileset;
- (void) fb_strlcpy(path, avd_get_str(fileset->fs_path), MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, avd_get_str(fileset->fs_name), MAXPATHLEN);
- pathtmp = fileset_resolvepath(entry);
- (void) fb_strlcat(path, pathtmp, MAXPATHLEN);
- free(pathtmp);
-
- filebench_log(LOG_DEBUG_IMPL, "Populated %s", entry->fse_path);
-
- /* see if reusing and this file exists */
- trust_tree = avd_get_bool(fileset->fs_trust_tree);
- if ((entry->fse_flags & FSE_REUSING) && (trust_tree ||
- (FB_STAT(path, &sb) == 0))) {
- if (FB_OPEN(&fdesc, path, O_RDWR, 0) == FILEBENCH_ERROR) {
- filebench_log(LOG_INFO,
- "Attempted but failed to Re-use file %s",
- path);
- fileset_unbusy(entry, TRUE, FALSE, 0);
- return (FILEBENCH_ERROR);
- }
-
- if (trust_tree || (sb.st_size == (off64_t)entry->fse_size)) {
- filebench_log(LOG_DEBUG_IMPL,
- "Re-using file %s", path);
-
- if (!avd_get_bool(fileset->fs_cached))
- (void) FB_FREEMEM(&fdesc, entry->fse_size);
-
- (void) FB_CLOSE(&fdesc);
-
- /* unbusy the allocated entry */
- fileset_unbusy(entry, TRUE, TRUE, 0);
- return (FILEBENCH_OK);
-
- } else if (sb.st_size > (off64_t)entry->fse_size) {
- /* reuse, but too large */
- filebench_log(LOG_DEBUG_IMPL,
- "Truncating & re-using file %s", path);
-
- (void) FB_FTRUNC(&fdesc, (off64_t)entry->fse_size);
-
- if (!avd_get_bool(fileset->fs_cached))
- (void) FB_FREEMEM(&fdesc, entry->fse_size);
-
- (void) FB_CLOSE(&fdesc);
-
- /* unbusy the allocated entry */
- fileset_unbusy(entry, TRUE, TRUE, 0);
- return (FILEBENCH_OK);
- }
- } else {
-
- /* No file or not reusing, so create */
- if (FB_OPEN(&fdesc, path, O_RDWR | O_CREAT, 0644) ==
- FILEBENCH_ERROR) {
- filebench_log(LOG_ERROR,
- "Failed to pre-allocate file %s: %s",
- path, strerror(errno));
-
- /* unbusy the unallocated entry */
- fileset_unbusy(entry, TRUE, FALSE, 0);
- return (FILEBENCH_ERROR);
- }
- }
-
- if ((buf = (char *)malloc(FILE_ALLOC_BLOCK)) == NULL) {
- /* unbusy the unallocated entry */
- fileset_unbusy(entry, TRUE, FALSE, 0);
- return (FILEBENCH_ERROR);
- }
-
- for (seek = 0; seek < entry->fse_size; ) {
- off64_t wsize;
- int ret = 0;
-
- /*
- * Write FILE_ALLOC_BLOCK's worth,
- * except on last write
- */
- wsize = MIN(entry->fse_size - seek, FILE_ALLOC_BLOCK);
-
- ret = FB_WRITE(&fdesc, buf, wsize);
- if (ret != wsize) {
- filebench_log(LOG_ERROR,
- "Failed to pre-allocate file %s: %s",
- path, strerror(errno));
- (void) FB_CLOSE(&fdesc);
- free(buf);
- fileset_unbusy(entry, TRUE, FALSE, 0);
- return (FILEBENCH_ERROR);
- }
- seek += wsize;
- }
-
- if (!avd_get_bool(fileset->fs_cached))
- (void) FB_FREEMEM(&fdesc, entry->fse_size);
-
- (void) FB_CLOSE(&fdesc);
-
- free(buf);
-
- /* unbusy the allocated entry */
- fileset_unbusy(entry, TRUE, TRUE, 0);
-
- filebench_log(LOG_DEBUG_IMPL,
- "Pre-allocated file %s size %llu",
- path, (u_longlong_t)entry->fse_size);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * given a fileset entry, determines if the associated file
- * needs to be allocated or not, and if so does the allocation.
- * Sets shm_fsparalloc_count to -1 on error.
- */
-static void *
-fileset_alloc_thread(filesetentry_t *entry)
-{
- if (fileset_alloc_file(entry) == FILEBENCH_ERROR) {
- (void) pthread_mutex_lock(&filebench_shm->shm_fsparalloc_lock);
- filebench_shm->shm_fsparalloc_count = -1;
- } else {
- (void) pthread_mutex_lock(&filebench_shm->shm_fsparalloc_lock);
- filebench_shm->shm_fsparalloc_count--;
- }
-
- (void) pthread_cond_signal(&filebench_shm->shm_fsparalloc_cv);
- (void) pthread_mutex_unlock(&filebench_shm->shm_fsparalloc_lock);
-
- pthread_exit(NULL);
- return (NULL);
-}
-
-
-/*
- * First creates the parent directories of the file using
- * fileset_mkdir(). Then Optionally sets the O_DSYNC flag
- * and opens the file with open64(). It unlocks the fileset
- * entry lock, sets the DIRECTIO_ON or DIRECTIO_OFF flags
- * as requested, and returns the file descriptor integer
- * for the opened file in the supplied filebench file descriptor.
- * Returns FILEBENCH_ERROR on error, and FILEBENCH_OK on success.
- */
-int
-fileset_openfile(fb_fdesc_t *fdesc, fileset_t *fileset,
- filesetentry_t *entry, int flag, int filemode, int attrs)
-{
- char path[MAXPATHLEN];
- char dir[MAXPATHLEN];
- char *pathtmp;
- struct stat64 sb;
- int open_attrs = 0;
-
- (void) fb_strlcpy(path, avd_get_str(fileset->fs_path), MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, avd_get_str(fileset->fs_name), MAXPATHLEN);
- pathtmp = fileset_resolvepath(entry);
- (void) fb_strlcat(path, pathtmp, MAXPATHLEN);
- (void) fb_strlcpy(dir, path, MAXPATHLEN);
- free(pathtmp);
- (void) trunc_dirname(dir);
-
- /* If we are going to create a file, create the parent dirs */
- if ((flag & O_CREAT) && (stat64(dir, &sb) != 0)) {
- if (fileset_mkdir(dir, 0755) == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
- }
-
- if (attrs & FLOW_ATTR_DSYNC) {
-#ifdef sun
- open_attrs |= O_DSYNC;
-#else
- open_attrs |= O_FSYNC;
-#endif
- }
-
- if (FB_OPEN(fdesc, path, flag | open_attrs, filemode)
- == FILEBENCH_ERROR) {
- filebench_log(LOG_ERROR,
- "Failed to open file %d, %s, with status %x: %s",
- entry->fse_index, path, entry->fse_flags, strerror(errno));
-
- fileset_unbusy(entry, FALSE, FALSE, 0);
- return (FILEBENCH_ERROR);
- }
-
- if (flag & O_CREAT)
- fileset_unbusy(entry, TRUE, TRUE, 1);
- else
- fileset_unbusy(entry, FALSE, FALSE, 1);
-
-#ifdef sun
- if (attrs & FLOW_ATTR_DIRECTIO)
- (void) directio(fdesc->fd_num, DIRECTIO_ON);
- else
- (void) directio(fdesc->fd_num, DIRECTIO_OFF);
-#endif
-
- return (FILEBENCH_OK);
-}
-
-/*
- * removes all filesetentries from their respective btrees, and puts them
- * on the free list. The supplied argument indicates which free list to
- * use.
- */
-static void
-fileset_pickreset(fileset_t *fileset, int entry_type)
-{
- filesetentry_t *entry;
-
- switch (entry_type & FILESET_PICKMASK) {
- case FILESET_PICKFILE:
- entry = (filesetentry_t *)avl_first(&fileset->fs_noex_files);
-
- /* make sure non-existing files are marked free */
- while (entry) {
- entry->fse_flags |= FSE_FREE;
- entry->fse_open_cnt = 0;
- fileset_move_entry(&fileset->fs_noex_files,
- &fileset->fs_free_files, entry);
- entry = AVL_NEXT(&fileset->fs_noex_files, entry);
- }
-
- /* free up any existing files */
- entry = (filesetentry_t *)avl_first(&fileset->fs_exist_files);
-
- while (entry) {
- entry->fse_flags |= FSE_FREE;
- entry->fse_open_cnt = 0;
- fileset_move_entry(&fileset->fs_exist_files,
- &fileset->fs_free_files, entry);
-
- entry = AVL_NEXT(&fileset->fs_exist_files, entry);
- }
-
- break;
-
- case FILESET_PICKDIR:
- /* nothing to reset, as all (sub)dirs always exist */
- break;
-
- case FILESET_PICKLEAFDIR:
- entry = (filesetentry_t *)
- avl_first(&fileset->fs_noex_leaf_dirs);
-
- /* make sure non-existing leaf dirs are marked free */
- while (entry) {
- entry->fse_flags |= FSE_FREE;
- entry->fse_open_cnt = 0;
- fileset_move_entry(&fileset->fs_noex_leaf_dirs,
- &fileset->fs_free_leaf_dirs, entry);
- entry = AVL_NEXT(&fileset->fs_noex_leaf_dirs, entry);
- }
-
- /* free up any existing leaf dirs */
- entry = (filesetentry_t *)
- avl_first(&fileset->fs_exist_leaf_dirs);
-
- while (entry) {
- entry->fse_flags |= FSE_FREE;
- entry->fse_open_cnt = 0;
- fileset_move_entry(&fileset->fs_exist_leaf_dirs,
- &fileset->fs_free_leaf_dirs, entry);
-
- entry = AVL_NEXT(&fileset->fs_exist_leaf_dirs, entry);
- }
-
- break;
- }
-}
-
-/*
- * find a filesetentry from the fileset using the supplied index
- */
-static filesetentry_t *
-fileset_find_entry(avl_tree_t *atp, uint_t index)
-{
- avl_index_t found_loc;
- filesetentry_t desired_fse, *found_fse;
-
- /* find the file with the desired index, if it is in the tree */
- desired_fse.fse_index = index;
- found_fse = avl_find(atp, (void *)(&desired_fse), &found_loc);
- if (found_fse != NULL)
- return (found_fse);
-
- /* if requested node not found, find next higher node */
- found_fse = avl_nearest(atp, found_loc, AVL_AFTER);
- if (found_fse != NULL)
- return (found_fse);
-
- /* might have hit the end, return lowest available index node */
- found_fse = avl_first(atp);
- return (found_fse);
-}
-
-/*
- * Selects a fileset entry from a fileset. If the
- * FILESET_PICKLEAFDIR flag is set it will pick a leaf directory entry,
- * if the FILESET_PICKDIR flag is set it will pick a non leaf directory
- * entry, otherwise a file entry. The FILESET_PICKUNIQUE
- * flag will take an entry off of one of the free (unused)
- * lists (file or directory), otherwise the entry will be
- * picked off of one of the rotor lists (file or directory).
- * The FILESET_PICKEXISTS will insure that only extant
- * (FSE_EXISTS) state files are selected, while
- * FILESET_PICKNOEXIST insures that only non extant
- * (not FSE_EXISTS) state files are selected.
- * Note that the selected fileset entry (file) is returned
- * with its FSE_BUSY flag (in fse_flags) set.
- */
-filesetentry_t *
-fileset_pick(fileset_t *fileset, int flags, int tid, int index)
-{
- filesetentry_t *entry = NULL;
- filesetentry_t *start_point;
- avl_tree_t *atp;
- fbint_t max_entries;
-
- (void) ipc_mutex_lock(&fileset->fs_pick_lock);
-
- /* see if we have to wait for available files or directories */
- switch (flags & FILESET_PICKMASK) {
- case FILESET_PICKFILE:
- if (fileset->fs_filelist == NULL)
- goto empty;
-
- while (fileset->fs_idle_files == 0) {
- (void) pthread_cond_wait(&fileset->fs_idle_files_cv,
- &fileset->fs_pick_lock);
- }
-
- max_entries = fileset->fs_constentries;
- if (flags & FILESET_PICKUNIQUE) {
- atp = &fileset->fs_free_files;
- } else if (flags & FILESET_PICKNOEXIST) {
- atp = &fileset->fs_noex_files;
- } else {
- atp = &fileset->fs_exist_files;
- }
- break;
-
- case FILESET_PICKDIR:
- if (fileset->fs_dirlist == NULL)
- goto empty;
-
- while (fileset->fs_idle_dirs == 0) {
- (void) pthread_cond_wait(&fileset->fs_idle_dirs_cv,
- &fileset->fs_pick_lock);
- }
-
- max_entries = 1;
- atp = &fileset->fs_dirs;
- break;
-
- case FILESET_PICKLEAFDIR:
- if (fileset->fs_leafdirlist == NULL)
- goto empty;
-
- while (fileset->fs_idle_leafdirs == 0) {
- (void) pthread_cond_wait(&fileset->fs_idle_leafdirs_cv,
- &fileset->fs_pick_lock);
- }
-
- max_entries = fileset->fs_constleafdirs;
- if (flags & FILESET_PICKUNIQUE) {
- atp = &fileset->fs_free_leaf_dirs;
- } else if (flags & FILESET_PICKNOEXIST) {
- atp = &fileset->fs_noex_leaf_dirs;
- } else {
- atp = &fileset->fs_exist_leaf_dirs;
- }
- break;
- }
-
- /* see if asking for impossible */
- if (avl_is_empty(atp))
- goto empty;
-
- if (flags & FILESET_PICKUNIQUE) {
- uint64_t index64;
-
- /*
- * pick at random from free list in order to
- * distribute initially allocated files more
- * randomly on storage media. Use uniform
- * random number generator to select index
- * if it is not supplied with pick call.
- */
- if (index) {
- index64 = index;
- } else {
- if (filebench_randomno64(&index64, max_entries, 1,
- NULL) == FILEBENCH_ERROR)
- return (NULL);
- }
-
- entry = fileset_find_entry(atp, (int)index64);
-
- if (entry == NULL)
- goto empty;
-
- } else if (flags & FILESET_PICKBYINDEX) {
- /* pick by supplied index */
- entry = fileset_find_entry(atp, index);
-
- } else {
- /* pick in rotation */
- switch (flags & FILESET_PICKMASK) {
- case FILESET_PICKFILE:
- if (flags & FILESET_PICKNOEXIST) {
- entry = fileset_find_entry(atp,
- fileset->fs_file_nerotor);
- fileset->fs_file_nerotor =
- entry->fse_index + 1;
- } else {
- entry = fileset_find_entry(atp,
- fileset->fs_file_exrotor[tid]);
- fileset->fs_file_exrotor[tid] =
- entry->fse_index + 1;
- }
- break;
-
- case FILESET_PICKDIR:
- entry = fileset_find_entry(atp, fileset->fs_dirrotor);
- fileset->fs_dirrotor = entry->fse_index + 1;
- break;
-
- case FILESET_PICKLEAFDIR:
- if (flags & FILESET_PICKNOEXIST) {
- entry = fileset_find_entry(atp,
- fileset->fs_leafdir_nerotor);
- fileset->fs_leafdir_nerotor =
- entry->fse_index + 1;
- } else {
- entry = fileset_find_entry(atp,
- fileset->fs_leafdir_exrotor);
- fileset->fs_leafdir_exrotor =
- entry->fse_index + 1;
- }
- break;
- }
- }
-
- if (entry == NULL)
- goto empty;
-
- /* see if entry in use */
- start_point = entry;
- while (entry->fse_flags & FSE_BUSY) {
-
- /* it is, so try next */
- entry = AVL_NEXT(atp, entry);
- if (entry == NULL)
- entry = avl_first(atp);
-
- /* see if we have wrapped around */
- if ((entry == NULL) || (entry == start_point)) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "All %d files are busy", avl_numnodes(atp));
- goto empty;
- }
-
- }
-
- /* update file or directory idle counts */
- switch (flags & FILESET_PICKMASK) {
- case FILESET_PICKFILE:
- fileset->fs_idle_files--;
- break;
- case FILESET_PICKDIR:
- fileset->fs_idle_dirs--;
- break;
- case FILESET_PICKLEAFDIR:
- fileset->fs_idle_leafdirs--;
- break;
- }
-
- /* Indicate that file or directory is now busy */
- entry->fse_flags |= FSE_BUSY;
-
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
- filebench_log(LOG_DEBUG_SCRIPT, "Picked file %s", entry->fse_path);
- return (entry);
-
-empty:
- filebench_log(LOG_DEBUG_SCRIPT, "No file found");
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
- return (NULL);
-}
-
-/*
- * Removes a filesetentry from the "FSE_BUSY" state, signaling any threads
- * that are waiting for a NOT BUSY filesetentry. Also sets whether it is
- * existant or not, or leaves that designation alone.
- */
-void
-fileset_unbusy(filesetentry_t *entry, int update_exist,
- int new_exist_val, int open_cnt_incr)
-{
- fileset_t *fileset = NULL;
-
- if (entry)
- fileset = entry->fse_fileset;
-
- if (fileset == NULL) {
- filebench_log(LOG_ERROR, "fileset_unbusy: NO FILESET!");
- return;
- }
-
- (void) ipc_mutex_lock(&fileset->fs_pick_lock);
-
- /* modify FSE_EXIST flag and actual dirs/files count, if requested */
- if (update_exist) {
- if (new_exist_val == TRUE) {
- if (entry->fse_flags & FSE_FREE) {
-
- /* asked to set and it was free */
- entry->fse_flags |= FSE_EXISTS;
- entry->fse_flags &= (~FSE_FREE);
- switch (entry->fse_flags & FSE_TYPE_MASK) {
- case FSE_TYPE_FILE:
- fileset_move_entry(
- &fileset->fs_free_files,
- &fileset->fs_exist_files, entry);
- break;
-
- case FSE_TYPE_DIR:
- break;
-
- case FSE_TYPE_LEAFDIR:
- fileset_move_entry(
- &fileset->fs_free_leaf_dirs,
- &fileset->fs_exist_leaf_dirs,
- entry);
- break;
- }
-
- } else if (!(entry->fse_flags & FSE_EXISTS)) {
-
- /* asked to set, and it was clear */
- entry->fse_flags |= FSE_EXISTS;
- switch (entry->fse_flags & FSE_TYPE_MASK) {
- case FSE_TYPE_FILE:
- fileset_move_entry(
- &fileset->fs_noex_files,
- &fileset->fs_exist_files, entry);
- break;
- case FSE_TYPE_DIR:
- break;
- case FSE_TYPE_LEAFDIR:
- fileset_move_entry(
- &fileset->fs_noex_leaf_dirs,
- &fileset->fs_exist_leaf_dirs,
- entry);
- break;
- }
- }
- } else {
- if (entry->fse_flags & FSE_FREE) {
- /* asked to clear, and it was free */
- entry->fse_flags &= (~(FSE_FREE | FSE_EXISTS));
- switch (entry->fse_flags & FSE_TYPE_MASK) {
- case FSE_TYPE_FILE:
- fileset_move_entry(
- &fileset->fs_free_files,
- &fileset->fs_noex_files, entry);
- break;
-
- case FSE_TYPE_DIR:
- break;
-
- case FSE_TYPE_LEAFDIR:
- fileset_move_entry(
- &fileset->fs_free_leaf_dirs,
- &fileset->fs_noex_leaf_dirs,
- entry);
- break;
- }
- } else if (entry->fse_flags & FSE_EXISTS) {
-
- /* asked to clear, and it was set */
- entry->fse_flags &= (~FSE_EXISTS);
- switch (entry->fse_flags & FSE_TYPE_MASK) {
- case FSE_TYPE_FILE:
- fileset_move_entry(
- &fileset->fs_exist_files,
- &fileset->fs_noex_files, entry);
- break;
- case FSE_TYPE_DIR:
- break;
- case FSE_TYPE_LEAFDIR:
- fileset_move_entry(
- &fileset->fs_exist_leaf_dirs,
- &fileset->fs_noex_leaf_dirs,
- entry);
- break;
- }
- }
- }
- }
-
- /* update open count */
- entry->fse_open_cnt += open_cnt_incr;
-
- /* increment idle count, clear FSE_BUSY and signal IF it was busy */
- if (entry->fse_flags & FSE_BUSY) {
-
- /* unbusy it */
- entry->fse_flags &= (~FSE_BUSY);
-
- /* release any threads waiting for unbusy */
- if (entry->fse_flags & FSE_THRD_WAITNG) {
- entry->fse_flags &= (~FSE_THRD_WAITNG);
- (void) pthread_cond_broadcast(
- &fileset->fs_thrd_wait_cv);
- }
-
- /* increment idle count and signal waiting threads */
- switch (entry->fse_flags & FSE_TYPE_MASK) {
- case FSE_TYPE_FILE:
- fileset->fs_idle_files++;
- if (fileset->fs_idle_files == 1) {
- (void) pthread_cond_signal(
- &fileset->fs_idle_files_cv);
- }
- break;
-
- case FSE_TYPE_DIR:
- fileset->fs_idle_dirs++;
- if (fileset->fs_idle_dirs == 1) {
- (void) pthread_cond_signal(
- &fileset->fs_idle_dirs_cv);
- }
- break;
-
- case FSE_TYPE_LEAFDIR:
- fileset->fs_idle_leafdirs++;
- if (fileset->fs_idle_leafdirs == 1) {
- (void) pthread_cond_signal(
- &fileset->fs_idle_leafdirs_cv);
- }
- break;
- }
- }
-
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
-}
-
-/*
- * Given a fileset "fileset", create the associated files as
- * specified in the attributes of the fileset. The fileset is
- * rooted in a directory whose pathname is in fileset_path. If the
- * directory exists, meaning that there is already a fileset,
- * and the fileset_reuse attribute is false, then remove it and all
- * its contained files and subdirectories. Next, the routine
- * creates a root directory for the fileset. All the file type
- * filesetentries are cycled through creating as needed
- * their containing subdirectory trees in the filesystem and
- * creating actual files for fileset_preallocpercent of them. The
- * created files are filled with fse_size bytes of unitialized
- * data. The routine returns FILEBENCH_ERROR on errors,
- * FILEBENCH_OK on success.
- */
-static int
-fileset_create(fileset_t *fileset)
-{
- filesetentry_t *entry;
- char path[MAXPATHLEN];
- struct stat64 sb;
- hrtime_t start = gethrtime();
- char *fileset_path;
- char *fileset_name;
- int randno;
- int preallocated = 0;
- int reusing;
-
- if ((fileset_path = avd_get_str(fileset->fs_path)) == NULL) {
- filebench_log(LOG_ERROR, "%s path not set",
- fileset_entity_name(fileset));
- return (FILEBENCH_ERROR);
- }
-
- if ((fileset_name = avd_get_str(fileset->fs_name)) == NULL) {
- filebench_log(LOG_ERROR, "%s name not set",
- fileset_entity_name(fileset));
- return (FILEBENCH_ERROR);
- }
-
-#ifdef HAVE_RAW_SUPPORT
- /* treat raw device as special case */
- if (fileset->fs_attrs & FILESET_IS_RAW_DEV)
- return (FILEBENCH_OK);
-#endif /* HAVE_RAW_SUPPORT */
-
- /* XXX Add check to see if there is enough space */
-
- /* set up path to fileset */
- (void) fb_strlcpy(path, fileset_path, MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, fileset_name, MAXPATHLEN);
-
- /* if reusing and trusting to exist, just blindly reuse */
- if (avd_get_bool(fileset->fs_trust_tree)) {
- reusing = 1;
-
- /* if exists and resusing, then don't create new */
- } else if (((stat64(path, &sb) == 0)&& (strlen(path) > 3) &&
- (strlen(avd_get_str(fileset->fs_path)) > 2)) &&
- avd_get_bool(fileset->fs_reuse)) {
- reusing = 1;
- } else {
- reusing = 0;
- }
-
- if (!reusing) {
- /* Remove existing */
- FB_RECUR_RM(path);
- filebench_log(LOG_VERBOSE,
- "Removed any existing %s %s in %llu seconds",
- fileset_entity_name(fileset), fileset_name,
- (u_longlong_t)(((gethrtime() - start) /
- 1000000000) + 1));
- } else {
- /* we are re-using */
- filebench_log(LOG_VERBOSE, "Re-using %s %s.",
- fileset_entity_name(fileset), fileset_name);
- }
-
- /* make the filesets directory tree unless in reuse mode */
- if (!reusing && (avd_get_bool(fileset->fs_prealloc))) {
- filebench_log(LOG_VERBOSE,
- "making tree for filset %s", path);
-
- (void) FB_MKDIR(path, 0755);
-
- if (fileset_create_subdirs(fileset, path) == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
- }
-
- start = gethrtime();
-
- filebench_log(LOG_VERBOSE, "Creating %s %s...",
- fileset_entity_name(fileset), fileset_name);
-
- randno = ((RAND_MAX * (100
- - avd_get_int(fileset->fs_preallocpercent))) / 100);
-
- /* alloc any files, as required */
- fileset_pickreset(fileset, FILESET_PICKFILE);
- while (entry = fileset_pick(fileset,
- FILESET_PICKFREE | FILESET_PICKFILE, 0, 0)) {
- pthread_t tid;
- int newrand;
-
- newrand = rand();
-
- if (newrand < randno) {
- /* unbusy the unallocated entry */
- fileset_unbusy(entry, TRUE, FALSE, 0);
- continue;
- }
-
- preallocated++;
-
- if (reusing)
- entry->fse_flags |= FSE_REUSING;
- else
- entry->fse_flags &= (~FSE_REUSING);
-
- /* fire off allocation threads for each file if paralloc set */
- if (avd_get_bool(fileset->fs_paralloc)) {
-
- /* limit total number of simultaneous allocations */
- (void) pthread_mutex_lock(
- &filebench_shm->shm_fsparalloc_lock);
- while (filebench_shm->shm_fsparalloc_count
- >= MAX_PARALLOC_THREADS) {
- (void) pthread_cond_wait(
- &filebench_shm->shm_fsparalloc_cv,
- &filebench_shm->shm_fsparalloc_lock);
- }
-
- /* quit if any allocation thread reports an error */
- if (filebench_shm->shm_fsparalloc_count < 0) {
- (void) pthread_mutex_unlock(
- &filebench_shm->shm_fsparalloc_lock);
- return (FILEBENCH_ERROR);
- }
-
- filebench_shm->shm_fsparalloc_count++;
- (void) pthread_mutex_unlock(
- &filebench_shm->shm_fsparalloc_lock);
-
- /*
- * Fire off a detached allocation thread per file.
- * The thread will self destruct when it finishes
- * writing pre-allocation data to the file.
- */
- if (pthread_create(&tid, NULL,
- (void *(*)(void*))fileset_alloc_thread,
- entry) == 0) {
- /*
- * A thread was created; detach it so it can
- * fully quit when finished.
- */
- (void) pthread_detach(tid);
- } else {
- filebench_log(LOG_ERROR,
- "File prealloc thread create failed");
- filebench_shutdown(1);
- }
-
- } else {
- if (fileset_alloc_file(entry) == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
- }
- }
-
- /* alloc any leaf directories, as required */
- fileset_pickreset(fileset, FILESET_PICKLEAFDIR);
- while (entry = fileset_pick(fileset,
- FILESET_PICKFREE | FILESET_PICKLEAFDIR, 0, 0)) {
-
- if (rand() < randno) {
- /* unbusy the unallocated entry */
- fileset_unbusy(entry, TRUE, FALSE, 0);
- continue;
- }
-
- preallocated++;
-
- if (reusing)
- entry->fse_flags |= FSE_REUSING;
- else
- entry->fse_flags &= (~FSE_REUSING);
-
- if (fileset_alloc_leafdir(entry) == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
- }
-
-exit:
- filebench_log(LOG_VERBOSE,
- "Preallocated %d of %llu of %s %s in %llu seconds",
- preallocated,
- (u_longlong_t)fileset->fs_constentries,
- fileset_entity_name(fileset), fileset_name,
- (u_longlong_t)(((gethrtime() - start) / 1000000000) + 1));
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Removes all files and directories associated with a fileset
- * from the storage subsystem.
- */
-static void
-fileset_delete_storage(fileset_t *fileset)
-{
- char path[MAXPATHLEN];
- char *fileset_path;
- char *fileset_name;
-
- if ((fileset_path = avd_get_str(fileset->fs_path)) == NULL)
- return;
-
- if ((fileset_name = avd_get_str(fileset->fs_name)) == NULL)
- return;
-
-#ifdef HAVE_RAW_SUPPORT
- /* treat raw device as special case */
- if (fileset->fs_attrs & FILESET_IS_RAW_DEV)
- return;
-#endif /* HAVE_RAW_SUPPORT */
-
- /* set up path to file */
- (void) fb_strlcpy(path, fileset_path, MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, fileset_name, MAXPATHLEN);
-
- /* now delete any files and directories on the disk */
- FB_RECUR_RM(path);
-}
-
-/*
- * Removes the fileset entity and all of its filesetentry entities.
- */
-static void
-fileset_delete_fileset(fileset_t *fileset)
-{
- filesetentry_t *entry, *next_entry;
-
- /* run down the file list, removing and freeing each filesetentry */
- for (entry = fileset->fs_filelist; entry; entry = next_entry) {
-
- /* free the entry */
- next_entry = entry->fse_next;
-
- /* return it to the pool */
- switch (entry->fse_flags & FSE_TYPE_MASK) {
- case FSE_TYPE_FILE:
- case FSE_TYPE_LEAFDIR:
- case FSE_TYPE_DIR:
- ipc_free(FILEBENCH_FILESETENTRY, (void *)entry);
- break;
- default:
- filebench_log(LOG_ERROR,
- "Unallocated filesetentry found on list");
- break;
- }
- }
-
- ipc_free(FILEBENCH_FILESET, (void *)fileset);
-}
-
-void
-fileset_delete_all_filesets(void)
-{
- fileset_t *fileset, *next_fileset;
-
- for (fileset = filebench_shm->shm_filesetlist;
- fileset; fileset = next_fileset) {
- next_fileset = fileset->fs_next;
- fileset_delete_storage(fileset);
- fileset_delete_fileset(fileset);
- }
-
- filebench_shm->shm_filesetlist = NULL;
-}
-/*
- * Adds an entry to the fileset's file list. Single threaded so
- * no locking needed.
- */
-static void
-fileset_insfilelist(fileset_t *fileset, filesetentry_t *entry)
-{
- entry->fse_flags = FSE_TYPE_FILE | FSE_FREE;
- avl_add(&fileset->fs_free_files, entry);
-
- if (fileset->fs_filelist == NULL) {
- fileset->fs_filelist = entry;
- entry->fse_nextoftype = NULL;
- } else {
- entry->fse_nextoftype = fileset->fs_filelist;
- fileset->fs_filelist = entry;
- }
-}
-
-/*
- * Adds an entry to the fileset's directory list. Single
- * threaded so no locking needed.
- */
-static void
-fileset_insdirlist(fileset_t *fileset, filesetentry_t *entry)
-{
- entry->fse_flags = FSE_TYPE_DIR | FSE_EXISTS;
- avl_add(&fileset->fs_dirs, entry);
-
- if (fileset->fs_dirlist == NULL) {
- fileset->fs_dirlist = entry;
- entry->fse_nextoftype = NULL;
- } else {
- entry->fse_nextoftype = fileset->fs_dirlist;
- fileset->fs_dirlist = entry;
- }
-}
-
-/*
- * Adds an entry to the fileset's leaf directory list. Single
- * threaded so no locking needed.
- */
-static void
-fileset_insleafdirlist(fileset_t *fileset, filesetentry_t *entry)
-{
- entry->fse_flags = FSE_TYPE_LEAFDIR | FSE_FREE;
- avl_add(&fileset->fs_free_leaf_dirs, entry);
-
- if (fileset->fs_leafdirlist == NULL) {
- fileset->fs_leafdirlist = entry;
- entry->fse_nextoftype = NULL;
- } else {
- entry->fse_nextoftype = fileset->fs_leafdirlist;
- fileset->fs_leafdirlist = entry;
- }
-}
-
-/*
- * Compares two fileset entries to determine their relative order
- */
-static int
-fileset_entry_compare(const void *node_1, const void *node_2)
-{
- if (((filesetentry_t *)node_1)->fse_index <
- ((filesetentry_t *)node_2)->fse_index)
- return (-1);
-
- if (((filesetentry_t *)node_1)->fse_index ==
- ((filesetentry_t *)node_2)->fse_index)
- return (0);
-
- return (1);
-}
-
-/*
- * Obtains a filesetentry entity for a file to be placed in a
- * (sub)directory of a fileset. The size of the file may be
- * specified by fileset_meansize, or calculated from a gamma
- * distribution of parameter fileset_sizegamma and of mean size
- * fileset_meansize. The filesetentry entity is placed on the file
- * list in the specified parent filesetentry entity, which may
- * be a directory filesetentry, or the root filesetentry in the
- * fileset. It is also placed on the fileset's list of all
- * contained files. Returns FILEBENCH_OK if successful or FILEBENCH_ERROR
- * if ipc memory for the path string cannot be allocated.
- */
-static int
-fileset_populate_file(fileset_t *fileset, filesetentry_t *parent, int serial)
-{
- char tmpname[16];
- filesetentry_t *entry;
- double drand;
- uint_t index;
-
- if ((entry = (filesetentry_t *)ipc_malloc(FILEBENCH_FILESETENTRY))
- == NULL) {
- filebench_log(LOG_ERROR,
- "fileset_populate_file: Can't malloc filesetentry");
- return (FILEBENCH_ERROR);
- }
-
- /* Another currently idle file */
- (void) ipc_mutex_lock(&fileset->fs_pick_lock);
- index = fileset->fs_idle_files++;
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
-
- entry->fse_index = index;
- entry->fse_parent = parent;
- entry->fse_fileset = fileset;
- fileset_insfilelist(fileset, entry);
-
- (void) snprintf(tmpname, sizeof (tmpname), "%08d", serial);
- if ((entry->fse_path = (char *)ipc_pathalloc(tmpname)) == NULL) {
- filebench_log(LOG_ERROR,
- "fileset_populate_file: Can't alloc path string");
- return (FILEBENCH_ERROR);
- }
-
- /* see if random variable was supplied for file size */
- if (fileset->fs_meansize == -1) {
- entry->fse_size = (off64_t)avd_get_int(fileset->fs_size);
- } else {
- double gamma;
-
- gamma = avd_get_int(fileset->fs_sizegamma) / 1000.0;
- if (gamma > 0) {
- drand = gamma_dist_knuth(gamma,
- fileset->fs_meansize / gamma);
- entry->fse_size = (off64_t)drand;
- } else {
- entry->fse_size = (off64_t)fileset->fs_meansize;
- }
- }
-
- fileset->fs_bytes += entry->fse_size;
-
- fileset->fs_realfiles++;
- return (FILEBENCH_OK);
-}
-
-/*
- * Obtaines a filesetentry entity for a leaf directory to be placed in a
- * (sub)directory of a fileset. The leaf directory will always be empty so
- * it can be created and deleted (mkdir, rmdir) at will. The filesetentry
- * entity is placed on the leaf directory list in the specified parent
- * filesetentry entity, which may be a (sub) directory filesetentry, or
- * the root filesetentry in the fileset. It is also placed on the fileset's
- * list of all contained leaf directories. Returns FILEBENCH_OK if successful
- * or FILEBENCH_ERROR if ipc memory cannot be allocated.
- */
-static int
-fileset_populate_leafdir(fileset_t *fileset, filesetentry_t *parent, int serial)
-{
- char tmpname[16];
- filesetentry_t *entry;
- uint_t index;
-
- if ((entry = (filesetentry_t *)ipc_malloc(FILEBENCH_FILESETENTRY))
- == NULL) {
- filebench_log(LOG_ERROR,
- "fileset_populate_file: Can't malloc filesetentry");
- return (FILEBENCH_ERROR);
- }
-
- /* Another currently idle leaf directory */
- (void) ipc_mutex_lock(&fileset->fs_pick_lock);
- index = fileset->fs_idle_leafdirs++;
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
-
- entry->fse_index = index;
- entry->fse_parent = parent;
- entry->fse_fileset = fileset;
- fileset_insleafdirlist(fileset, entry);
-
- (void) snprintf(tmpname, sizeof (tmpname), "%08d", serial);
- if ((entry->fse_path = (char *)ipc_pathalloc(tmpname)) == NULL) {
- filebench_log(LOG_ERROR,
- "fileset_populate_file: Can't alloc path string");
- return (FILEBENCH_ERROR);
- }
-
- fileset->fs_realleafdirs++;
- return (FILEBENCH_OK);
-}
-
-/*
- * Creates a directory node in a fileset, by obtaining a
- * filesetentry entity for the node and initializing it
- * according to parameters of the fileset. It determines a
- * directory tree depth and directory width, optionally using
- * a gamma distribution. If its calculated depth is less then
- * its actual depth in the directory tree, it becomes a leaf
- * node and files itself with "width" number of file type
- * filesetentries, otherwise it files itself with "width"
- * number of directory type filesetentries, using recursive
- * calls to fileset_populate_subdir. The end result of the
- * initial call to this routine is a tree of directories of
- * random width and varying depth with sufficient leaf
- * directories to contain all required files.
- * Returns FILEBENCH_OK on success. Returns FILEBENCH_ERROR if ipc path
- * string memory cannot be allocated and returns the error code (currently
- * also FILEBENCH_ERROR) from calls to fileset_populate_file or recursive
- * calls to fileset_populate_subdir.
- */
-static int
-fileset_populate_subdir(fileset_t *fileset, filesetentry_t *parent,
- int serial, double depth)
-{
- double randepth, drand, ranwidth;
- int isleaf = 0;
- char tmpname[16];
- filesetentry_t *entry;
- int i;
- uint_t index;
-
- depth += 1;
-
- /* Create dir node */
- if ((entry = (filesetentry_t *)ipc_malloc(FILEBENCH_FILESETENTRY))
- == NULL) {
- filebench_log(LOG_ERROR,
- "fileset_populate_subdir: Can't malloc filesetentry");
- return (FILEBENCH_ERROR);
- }
-
- /* another idle directory */
- (void) ipc_mutex_lock(&fileset->fs_pick_lock);
- index = fileset->fs_idle_dirs++;
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
-
- (void) snprintf(tmpname, sizeof (tmpname), "%08d", serial);
- if ((entry->fse_path = (char *)ipc_pathalloc(tmpname)) == NULL) {
- filebench_log(LOG_ERROR,
- "fileset_populate_subdir: Can't alloc path string");
- return (FILEBENCH_ERROR);
- }
-
- entry->fse_index = index;
- entry->fse_parent = parent;
- entry->fse_fileset = fileset;
- fileset_insdirlist(fileset, entry);
-
- if (fileset->fs_dirdepthrv) {
- randepth = (int)avd_get_int(fileset->fs_dirdepthrv);
- } else {
- double gamma;
-
- gamma = avd_get_int(fileset->fs_dirgamma) / 1000.0;
- if (gamma > 0) {
- drand = gamma_dist_knuth(gamma,
- fileset->fs_meandepth / gamma);
- randepth = (int)drand;
- } else {
- randepth = (int)fileset->fs_meandepth;
- }
- }
-
- if (fileset->fs_meanwidth == -1) {
- ranwidth = avd_get_dbl(fileset->fs_dirwidth);
- } else {
- double gamma;
-
- gamma = avd_get_int(fileset->fs_sizegamma) / 1000.0;
- if (gamma > 0) {
- drand = gamma_dist_knuth(gamma,
- fileset->fs_meanwidth / gamma);
- ranwidth = drand;
- } else {
- ranwidth = fileset->fs_meanwidth;
- }
- }
-
- if (randepth == 0)
- randepth = 1;
- if (ranwidth == 0)
- ranwidth = 1;
- if (depth >= randepth)
- isleaf = 1;
-
- /*
- * Create directory of random width filled with files according
- * to distribution, or if root directory, continue until #files required
- */
- for (i = 1; ((parent == NULL) || (i < ranwidth + 1)) &&
- (fileset->fs_realfiles < fileset->fs_constentries);
- i++) {
- int ret = 0;
-
- if (parent && isleaf)
- ret = fileset_populate_file(fileset, entry, i);
- else
- ret = fileset_populate_subdir(fileset, entry, i, depth);
-
- if (ret != 0)
- return (ret);
- }
-
- /*
- * Create directory of random width filled with leaf directories
- * according to distribution, or if root directory, continue until
- * the number of leaf directories required has been generated.
- */
- for (i = 1; ((parent == NULL) || (i < ranwidth + 1)) &&
- (fileset->fs_realleafdirs < fileset->fs_constleafdirs);
- i++) {
- int ret = 0;
-
- if (parent && isleaf)
- ret = fileset_populate_leafdir(fileset, entry, i);
- else
- ret = fileset_populate_subdir(fileset, entry, i, depth);
-
- if (ret != 0)
- return (ret);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Populates a fileset with files and subdirectory entries. Uses
- * the supplied fileset_dirwidth and fileset_entries (number of files) to
- * calculate the required fileset_meandepth (of subdirectories) and
- * initialize the fileset_meanwidth and fileset_meansize variables. Then
- * calls fileset_populate_subdir() to do the recursive
- * subdirectory entry creation and leaf file entry creation. All
- * of the above is skipped if the fileset has already been
- * populated. Returns 0 on success, or an error code from the
- * call to fileset_populate_subdir if that call fails.
- */
-static int
-fileset_populate(fileset_t *fileset)
-{
- fbint_t entries = avd_get_int(fileset->fs_entries);
- fbint_t leafdirs = avd_get_int(fileset->fs_leafdirs);
- int meandirwidth;
- int ret;
-
- /* Skip if already populated */
- if (fileset->fs_bytes > 0)
- goto exists;
-
-#ifdef HAVE_RAW_SUPPORT
- /* check for raw device */
- if (fileset->fs_attrs & FILESET_IS_RAW_DEV)
- return (FILEBENCH_OK);
-#endif /* HAVE_RAW_SUPPORT */
-
- /*
- * save value of entries and leaf dirs obtained for later
- * in case it was random
- */
- fileset->fs_constentries = entries;
- fileset->fs_constleafdirs = leafdirs;
-
- /* initialize idle files and directories condition variables */
- (void) pthread_cond_init(&fileset->fs_idle_files_cv, ipc_condattr());
- (void) pthread_cond_init(&fileset->fs_idle_dirs_cv, ipc_condattr());
- (void) pthread_cond_init(&fileset->fs_idle_leafdirs_cv, ipc_condattr());
-
- /* no files or dirs idle (or busy) yet */
- fileset->fs_idle_files = 0;
- fileset->fs_idle_dirs = 0;
- fileset->fs_idle_leafdirs = 0;
-
- /* initialize locks and other condition variables */
- (void) pthread_mutex_init(&fileset->fs_pick_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&fileset->fs_histo_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_cond_init(&fileset->fs_thrd_wait_cv, ipc_condattr());
-
- /* Initialize avl btrees */
- avl_create(&(fileset->fs_free_files), fileset_entry_compare,
- sizeof (filesetentry_t), FSE_OFFSETOF(fse_link));
- avl_create(&(fileset->fs_noex_files), fileset_entry_compare,
- sizeof (filesetentry_t), FSE_OFFSETOF(fse_link));
- avl_create(&(fileset->fs_exist_files), fileset_entry_compare,
- sizeof (filesetentry_t), FSE_OFFSETOF(fse_link));
- avl_create(&(fileset->fs_free_leaf_dirs), fileset_entry_compare,
- sizeof (filesetentry_t), FSE_OFFSETOF(fse_link));
- avl_create(&(fileset->fs_noex_leaf_dirs), fileset_entry_compare,
- sizeof (filesetentry_t), FSE_OFFSETOF(fse_link));
- avl_create(&(fileset->fs_exist_leaf_dirs), fileset_entry_compare,
- sizeof (filesetentry_t), FSE_OFFSETOF(fse_link));
- avl_create(&(fileset->fs_dirs), fileset_entry_compare,
- sizeof (filesetentry_t), FSE_OFFSETOF(fse_link));
-
- /* is dirwidth a random variable? */
- if (AVD_IS_RANDOM(fileset->fs_dirwidth)) {
- meandirwidth =
- (int)fileset->fs_dirwidth->avd_val.randptr->rnd_dbl_mean;
- fileset->fs_meanwidth = -1;
- } else {
- meandirwidth = (int)avd_get_int(fileset->fs_dirwidth);
- fileset->fs_meanwidth = (double)meandirwidth;
- }
-
- /*
- * Input params are:
- * # of files
- * ave # of files per dir
- * max size of dir
- * # ave size of file
- * max size of file
- */
- fileset->fs_meandepth = log(entries+leafdirs) / log(meandirwidth);
-
- /* Has a random variable been supplied for dirdepth? */
- if (fileset->fs_dirdepthrv) {
- /* yes, so set the random variable's mean value to meandepth */
- fileset->fs_dirdepthrv->avd_val.randptr->rnd_dbl_mean =
- fileset->fs_meandepth;
- }
-
- /* test for random size variable */
- if (AVD_IS_RANDOM(fileset->fs_size))
- fileset->fs_meansize = -1;
- else
- fileset->fs_meansize = avd_get_int(fileset->fs_size);
-
- if ((ret = fileset_populate_subdir(fileset, NULL, 1, 0)) != 0)
- return (ret);
-
-
-exists:
- if (fileset->fs_attrs & FILESET_IS_FILE) {
- filebench_log(LOG_VERBOSE, "File %s: mbytes=%llu",
- avd_get_str(fileset->fs_name),
- (u_longlong_t)(fileset->fs_bytes / 1024UL / 1024UL));
- } else {
- filebench_log(LOG_VERBOSE, "Fileset %s: %d files, %d leafdirs "
- "avg dir = %d, avg depth = %.1lf, mbytes=%llu",
- avd_get_str(fileset->fs_name), entries, leafdirs,
- meandirwidth,
- fileset->fs_meandepth,
- (u_longlong_t)(fileset->fs_bytes / 1024UL / 1024UL));
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Allocates a fileset instance, initializes fileset_dirgamma and
- * fileset_sizegamma default values, and sets the fileset name to the
- * supplied name string. Puts the allocated fileset on the
- * master fileset list and returns a pointer to it.
- *
- * This routine implements the 'define fileset' calls found in a .f
- * workload, such as in the following example:
- * define fileset name=drew4ever, entries=$nfiles
- */
-fileset_t *
-fileset_define(avd_t name)
-{
- fileset_t *fileset;
-
- if (name == NULL)
- return (NULL);
-
- if ((fileset = (fileset_t *)ipc_malloc(FILEBENCH_FILESET)) == NULL) {
- filebench_log(LOG_ERROR,
- "fileset_define: Can't malloc fileset");
- return (NULL);
- }
-
- filebench_log(LOG_DEBUG_IMPL,
- "Defining file %s", avd_get_str(name));
-
- (void) ipc_mutex_lock(&filebench_shm->shm_fileset_lock);
-
- fileset->fs_dirgamma = avd_int_alloc(1500);
- fileset->fs_sizegamma = avd_int_alloc(1500);
- fileset->fs_histo_id = -1;
-
- /* Add fileset to global list */
- if (filebench_shm->shm_filesetlist == NULL) {
- filebench_shm->shm_filesetlist = fileset;
- fileset->fs_next = NULL;
- } else {
- fileset->fs_next = filebench_shm->shm_filesetlist;
- filebench_shm->shm_filesetlist = fileset;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_fileset_lock);
-
- fileset->fs_name = name;
-
- return (fileset);
-}
-
-/*
- * If supplied with a pointer to a fileset and the fileset's
- * fileset_prealloc flag is set, calls fileset_populate() to populate
- * the fileset with filesetentries, then calls fileset_create()
- * to make actual directories and files for the filesetentries.
- * Otherwise, it applies fileset_populate() and fileset_create()
- * to all the filesets on the master fileset list. It always
- * returns zero (0) if one fileset is populated / created,
- * otherwise it returns the sum of returned values from
- * fileset_create() and fileset_populate(), which
- * will be a negative one (-1) times the number of
- * fileset_create() calls which failed.
- */
-int
-fileset_createset(fileset_t *fileset)
-{
- fileset_t *list;
- int ret = 0;
-
- /* set up for possible parallel allocate */
- filebench_shm->shm_fsparalloc_count = 0;
- (void) pthread_cond_init(
- &filebench_shm->shm_fsparalloc_cv,
- ipc_condattr());
-
- if (fileset && avd_get_bool(fileset->fs_prealloc)) {
-
- /* check for raw files */
- if (fileset_checkraw(fileset)) {
- filebench_log(LOG_INFO,
- "file %s/%s is a RAW device",
- avd_get_str(fileset->fs_path),
- avd_get_str(fileset->fs_name));
- return (FILEBENCH_OK);
- }
-
- filebench_log(LOG_INFO,
- "creating/pre-allocating %s %s",
- fileset_entity_name(fileset),
- avd_get_str(fileset->fs_name));
-
- if ((ret = fileset_populate(fileset)) != FILEBENCH_OK)
- return (ret);
-
- if ((ret = fileset_create(fileset)) != FILEBENCH_OK)
- return (ret);
- } else {
-
- filebench_log(LOG_INFO,
- "Creating/pre-allocating files and filesets");
-
- list = filebench_shm->shm_filesetlist;
- while (list) {
- /* check for raw files */
- if (fileset_checkraw(list)) {
- filebench_log(LOG_INFO,
- "file %s/%s is a RAW device",
- avd_get_str(list->fs_path),
- avd_get_str(list->fs_name));
- list = list->fs_next;
- continue;
- }
-
- if ((ret = fileset_populate(list)) != FILEBENCH_OK)
- return (ret);
-
- if ((ret = fileset_create(list)) != FILEBENCH_OK)
- return (ret);
-
- list = list->fs_next;
- }
- }
-
- /* wait for allocation threads to finish */
- filebench_log(LOG_INFO,
- "waiting for fileset pre-allocation to finish");
-
- (void) pthread_mutex_lock(&filebench_shm->shm_fsparalloc_lock);
- while (filebench_shm->shm_fsparalloc_count > 0)
- (void) pthread_cond_wait(
- &filebench_shm->shm_fsparalloc_cv,
- &filebench_shm->shm_fsparalloc_lock);
- (void) pthread_mutex_unlock(&filebench_shm->shm_fsparalloc_lock);
-
- if (filebench_shm->shm_fsparalloc_count < 0)
- return (FILEBENCH_ERROR);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Searches through the master fileset list for the named fileset.
- * If found, returns pointer to same, otherwise returns NULL.
- */
-fileset_t *
-fileset_find(char *name)
-{
- fileset_t *fileset = filebench_shm->shm_filesetlist;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_fileset_lock);
-
- while (fileset) {
- if (strcmp(name, avd_get_str(fileset->fs_name)) == 0) {
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_fileset_lock);
- return (fileset);
- }
- fileset = fileset->fs_next;
- }
- (void) ipc_mutex_unlock(&filebench_shm->shm_fileset_lock);
-
- return (NULL);
-}
-
-/*
- * Iterates over all the file sets in the filesetlist,
- * executing the supplied command "*cmd()" on them. Also
- * indicates to the executed command if it is the first
- * time the command has been executed since the current
- * call to fileset_iter.
- */
-int
-fileset_iter(int (*cmd)(fileset_t *fileset, int first))
-{
- fileset_t *fileset = filebench_shm->shm_filesetlist;
- int count = 0;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_fileset_lock);
-
- while (fileset) {
- if (cmd(fileset, count == 0) == FILEBENCH_ERROR) {
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_fileset_lock);
- return (FILEBENCH_ERROR);
- }
- fileset = fileset->fs_next;
- count++;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_fileset_lock);
- return (FILEBENCH_OK);
-}
-
-/*
- * Prints information to the filebench log about the file
- * object. Also prints a header on the first call.
- */
-int
-fileset_print(fileset_t *fileset, int first)
-{
- int pathlength;
- char *fileset_path;
- char *fileset_name;
- static char pad[] = " "; /* 30 spaces */
-
- if ((fileset_path = avd_get_str(fileset->fs_path)) == NULL) {
- filebench_log(LOG_ERROR, "%s path not set",
- fileset_entity_name(fileset));
- return (FILEBENCH_ERROR);
- }
-
- if ((fileset_name = avd_get_str(fileset->fs_name)) == NULL) {
- filebench_log(LOG_ERROR, "%s name not set",
- fileset_entity_name(fileset));
- return (FILEBENCH_ERROR);
- }
-
- pathlength = strlen(fileset_path) + strlen(fileset_name);
-
- if (pathlength > 29)
- pathlength = 29;
-
- if (first) {
- filebench_log(LOG_INFO, "File or Fileset name%20s%12s%10s",
- "file size",
- "dir width",
- "entries");
- }
-
- if (fileset->fs_attrs & FILESET_IS_FILE) {
- if (fileset->fs_attrs & FILESET_IS_RAW_DEV) {
- filebench_log(LOG_INFO,
- "%s/%s%s (Raw Device)",
- fileset_path, fileset_name, &pad[pathlength]);
- } else {
- filebench_log(LOG_INFO,
- "%s/%s%s%9llu (Single File)",
- fileset_path, fileset_name, &pad[pathlength],
- (u_longlong_t)avd_get_int(fileset->fs_size));
- }
- } else {
- filebench_log(LOG_INFO, "%s/%s%s%9llu%12llu%10llu",
- fileset_path, fileset_name,
- &pad[pathlength],
- (u_longlong_t)avd_get_int(fileset->fs_size),
- (u_longlong_t)avd_get_int(fileset->fs_dirwidth),
- (u_longlong_t)fileset->fs_constentries);
- }
- return (FILEBENCH_OK);
-}
-
-/*
- * checks to see if the path/name pair points to a raw device. If
- * so it sets the raw device flag (FILESET_IS_RAW_DEV) and returns 1.
- * If RAW is not defined, or it is not a raw device, it clears the
- * raw device flag and returns 0.
- */
-int
-fileset_checkraw(fileset_t *fileset)
-{
- char path[MAXPATHLEN];
- struct stat64 sb;
- char *pathname;
- char *setname;
-
- fileset->fs_attrs &= (~FILESET_IS_RAW_DEV);
-
-#ifdef HAVE_RAW_SUPPORT
- /* check for raw device */
- if ((pathname = avd_get_str(fileset->fs_path)) == NULL)
- return (FILEBENCH_OK);
-
- if ((setname = avd_get_str(fileset->fs_name)) == NULL)
- return (FILEBENCH_OK);
-
- (void) fb_strlcpy(path, pathname, MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, setname, MAXPATHLEN);
- if ((stat64(path, &sb) == 0) &&
- ((sb.st_mode & S_IFMT) == S_IFBLK) && sb.st_rdev) {
- fileset->fs_attrs |= FILESET_IS_RAW_DEV;
- if (!(fileset->fs_attrs & FILESET_IS_FILE)) {
- filebench_log(LOG_ERROR,
- "WARNING Fileset %s/%s Cannot be RAW device",
- avd_get_str(fileset->fs_path),
- avd_get_str(fileset->fs_name));
- filebench_shutdown(1);
- }
-
- return (1);
- }
-#endif /* HAVE_RAW_SUPPORT */
-
- return (FILEBENCH_OK);
-}
diff --git a/usr/src/cmd/filebench/common/fileset.h b/usr/src/cmd/filebench/common/fileset.h
deleted file mode 100644
index 95e697cbd8..0000000000
--- a/usr/src/cmd/filebench/common/fileset.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_FILESET_H
-#define _FB_FILESET_H
-
-#include "filebench.h"
-#include "config.h"
-
-#ifndef HAVE_OFF64_T
-/*
- * We are probably on linux.
- * According to http://www.suse.de/~aj/linux_lfs.html, defining the
- * above, automatically changes type of off_t to off64_t. so let
- * us use only off_t as off64_t is not defined
- */
-#define off64_t off_t
-#endif /* HAVE_OFF64_T */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/resource.h>
-#include <pthread.h>
-
-#include "vars.h"
-#include "fb_avl.h"
-
-#define FILE_ALLOC_BLOCK (off64_t)(1024 * 1024)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define FSE_MAXTID 16384
-
-#define FSE_MAXPATHLEN 16
-#define FSE_TYPE_FILE 0x00
-#define FSE_TYPE_DIR 0x01
-#define FSE_TYPE_LEAFDIR 0x02
-#define FSE_TYPE_MASK 0x03
-#define FSE_FREE 0x04
-#define FSE_EXISTS 0x08
-#define FSE_BUSY 0x10
-#define FSE_REUSING 0x20
-#define FSE_THRD_WAITNG 0x40
-
-typedef struct filesetentry {
- struct filesetentry *fse_next; /* master list of entries */
- struct filesetentry *fse_parent; /* link to directory */
- avl_node_t fse_link; /* links in avl btree, prot. */
- /* by fs_pick_lock */
- uint_t fse_index; /* file order number */
- struct filesetentry *fse_nextoftype; /* List of specific fse */
- struct fileset *fse_fileset; /* Parent fileset */
- char *fse_path;
- int fse_depth;
- off64_t fse_size;
- int fse_open_cnt; /* protected by fs_pick_lock */
- int fse_flags; /* protected by fs_pick_lock */
-} filesetentry_t;
-
-#define FSE_OFFSETOF(f) ((size_t)(&(((filesetentry_t *)0)->f)))
-
-/* type of fileset entry to obtain */
-#define FILESET_PICKFILE 0x00 /* Pick a file from the set */
-#define FILESET_PICKDIR 0x01 /* Pick a directory */
-#define FILESET_PICKLEAFDIR 0x02 /* Pick a leaf directory */
-#define FILESET_PICKMASK 0x03 /* Pick type mask */
-/* other pick flags */
-#define FILESET_PICKUNIQUE 0x04 /* Pick a unique file or leafdir from the */
- /* fileset until empty */
-#define FILESET_PICKEXISTS 0x10 /* Pick an existing file */
-#define FILESET_PICKNOEXIST 0x20 /* Pick a file that doesn't exist */
-#define FILESET_PICKBYINDEX 0x40 /* use supplied index number to select file */
-#define FILESET_PICKFREE FILESET_PICKUNIQUE
-
-/* fileset attributes */
-#define FILESET_IS_RAW_DEV 0x01 /* fileset is a raw device */
-#define FILESET_IS_FILE 0x02 /* Fileset is emulating a single file */
-
-typedef struct fileset {
- struct fileset *fs_next; /* Next in list */
- avd_t fs_name; /* Name */
- avd_t fs_path; /* Pathname prefix in fileset */
- avd_t fs_entries; /* Number of entries attr */
- /* (possibly random) */
- fbint_t fs_constentries; /* Constant version of enties attr */
- avd_t fs_leafdirs; /* Number of leaf directories attr */
- /* (possibly random) */
- fbint_t fs_constleafdirs; /* Constant version of leafdirs */
- /* attr */
- avd_t fs_preallocpercent; /* Prealloc size */
- int fs_attrs; /* Attributes */
- avd_t fs_dirwidth; /* Explicit or mean for distribution */
- avd_t fs_dirdepthrv; /* random variable for dir depth */
- avd_t fs_size; /* Explicit or mean for distribution */
- avd_t fs_dirgamma; /* Dirdepth Gamma distribution */
- /* (* 1000) defaults to 1500, set */
- /* to 0 for explicit depth */
- avd_t fs_sizegamma; /* Filesize and dirwidth Gamma */
- /* distribution (* 1000), default */
- /* is 1500, set to 0 for explicit */
- avd_t fs_create; /* Attr */
- avd_t fs_prealloc; /* Attr */
- avd_t fs_paralloc; /* Attr */
- avd_t fs_cached; /* Attr */
- avd_t fs_reuse; /* Attr */
- avd_t fs_readonly; /* Attr */
- avd_t fs_trust_tree; /* Attr */
- double fs_meandepth; /* Computed mean depth */
- double fs_meanwidth; /* Specified mean dir width */
- double fs_meansize; /* Specified mean file size */
- int fs_realfiles; /* Actual files */
- int fs_realleafdirs; /* Actual explicit leaf directories */
- off64_t fs_bytes; /* Total space consumed by files */
-
- int64_t fs_idle_files; /* number of files NOT busy */
- pthread_cond_t fs_idle_files_cv; /* idle files condition variable */
-
- int64_t fs_idle_dirs; /* number of dirs NOT busy */
- pthread_cond_t fs_idle_dirs_cv; /* idle dirs condition variable */
-
- int64_t fs_idle_leafdirs; /* number of dirs NOT busy */
- pthread_cond_t fs_idle_leafdirs_cv; /* idle dirs condition variable */
-
- pthread_mutex_t fs_pick_lock; /* per fileset "pick" function lock */
- pthread_cond_t fs_thrd_wait_cv; /* per fileset file busy wait cv */
- avl_tree_t fs_free_files; /* btree of free files */
- avl_tree_t fs_exist_files; /* btree of files on device */
- avl_tree_t fs_noex_files; /* btree of files NOT on device */
- avl_tree_t fs_dirs; /* btree of internal dirs */
- avl_tree_t fs_free_leaf_dirs; /* btree of free leaf dirs */
- avl_tree_t fs_exist_leaf_dirs; /* btree of leaf dirs on device */
- avl_tree_t fs_noex_leaf_dirs; /* btree of leaf dirs NOT */
- /* currently on device */
- filesetentry_t *fs_filelist; /* List of files */
- uint_t fs_file_exrotor[FSE_MAXTID]; /* next file to */
- /* select */
- uint_t fs_file_nerotor; /* next non existent file */
- /* to select for createfile */
- filesetentry_t *fs_dirlist; /* List of directories */
- uint_t fs_dirrotor; /* index of next directory to select */
- filesetentry_t *fs_leafdirlist; /* List of leaf directories */
- uint_t fs_leafdir_exrotor; /* Ptr to next existing leaf */
- /* directory to select */
- uint_t fs_leafdir_nerotor; /* Ptr to next non-existing */
- int *fs_filehistop; /* Ptr to access histogram */
- int fs_histo_id; /* shared memory id for filehisto */
- pthread_mutex_t fs_histo_lock; /* lock for incr of histo */
-} fileset_t;
-
-int fileset_createset(fileset_t *);
-void fileset_delete_all_filesets(void);
-int fileset_openfile(fb_fdesc_t *fd, fileset_t *fileset,
- filesetentry_t *entry, int flag, int mode, int attrs);
-fileset_t *fileset_define(avd_t);
-fileset_t *fileset_find(char *name);
-filesetentry_t *fileset_pick(fileset_t *fileset, int flags, int tid,
- int index);
-char *fileset_resolvepath(filesetentry_t *entry);
-void fileset_usage(void);
-int fileset_iter(int (*cmd)(fileset_t *fileset, int first));
-int fileset_print(fileset_t *fileset, int first);
-void fileset_unbusy(filesetentry_t *entry, int update_exist,
- int new_exist_val, int open_cnt_incr);
-int fileset_dump_histo(fileset_t *fileset, int first);
-void fileset_attach_all_histos(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_FILESET_H */
diff --git a/usr/src/cmd/filebench/common/flowop.c b/usr/src/cmd/filebench/common/flowop.c
deleted file mode 100644
index 4a527e2a44..0000000000
--- a/usr/src/cmd/filebench/common/flowop.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include "config.h"
-
-#ifdef HAVE_LWPS
-#include <sys/lwp.h>
-#endif
-#include <fcntl.h>
-#include "filebench.h"
-#include "flowop.h"
-#include "stats.h"
-
-#ifdef LINUX_PORT
-#include <sys/types.h>
-#include <linux/unistd.h>
-#endif
-
-static flowop_t *flowop_define_common(threadflow_t *threadflow, char *name,
- flowop_t *inherit, flowop_t **flowoplist_hdp, int instance, int type);
-static int flowop_composite(threadflow_t *threadflow, flowop_t *flowop);
-static int flowop_composite_init(flowop_t *flowop);
-static void flowop_composite_destruct(flowop_t *flowop);
-
-/*
- * A collection of flowop support functions. The actual code that
- * implements the various flowops is in flowop_library.c.
- *
- * Routines for defining, creating, initializing and destroying
- * flowops, cyclically invoking the flowops on each threadflow's flowop
- * list, collecting statistics about flowop execution, and other
- * housekeeping duties are included in this file.
- *
- * User Defined Composite Flowops
- * The ability to define new flowops as lists of built-in or previously
- * defined flowops has been added to Filebench. In a sense they are like
- * in-line subroutines, which can have default attributes set at definition
- * time and passed arguments at invocation time. Like other flowops (and
- * unlike conventional subroutines) you can invoke them with an iteration
- * count (the "iter" attribute), and they will loop through their associated
- * list of flowops for "iter" number of times each time they are encountered
- * in the thread or outer composite flowop which invokes them.
- *
- * Composite flowops are created with a "define" command, are given a name,
- * optional default attributes, and local variable definitions on the
- * "define" command line, followed by a brace enclosed list of flowops
- * to execute. The enclosed flowops may include attributes that reference
- * the local variables, as well as constants and global variables.
- *
- * Composite flowops are used pretty much like regular flowops, but you can
- * also set local variables to constants or global variables ($local_var =
- * [$var | $random_var | string | boolean | integer | double]) as part of
- * the invocation. Thus each invocation can pass customized values to its
- * inner flowops, greatly increasing their generality.
- *
- * All flowops are placed on a global, singly linked list, with fo_next
- * being the link pointer for this list. The are also placed on a private
- * list for the thread or composite flowop they are part of. The tf_thrd_fops
- * pointer in the thread will point to the list of top level flowops in the
- * thread, which are linked together by fo_exec_next. If any of these flowops
- * are composite flowops, they will have a list of second level flowops rooted
- * at the composite flowop's fo_comp_fops pointer. So, there is one big list
- * of all flowops, and an n-arry tree of threads, composite flowops, and
- * flowops, with composite flowops being the branch nodes in the tree.
- *
- * To illustrate, if we have three first level flowops, the first of which is
- * a composite flowop consisting of two other flowops, we get:
- *
- * Thread->tf_thrd_fops -> flowop->fo_exec_next -> flowop->fo_exec_next
- * flowop->fo_comp_fops |
- * | V
- * | flowop->fo_exec_next
- * |
- * V
- * flowop->fo_exec_next -> flowop->fo_exec_next
- *
- * And all five flowops (plus others from any other threads) are on a global
- * list linked with fo_next.
- */
-
-/*
- * Prints the name and instance number of each flowop in
- * the supplied list to the filebench log.
- */
-int
-flowop_printlist(flowop_t *list)
-{
- flowop_t *flowop = list;
-
- while (flowop) {
- filebench_log(LOG_DEBUG_IMPL, "flowop-list %s-%d",
- flowop->fo_name, flowop->fo_instance);
- flowop = flowop->fo_exec_next;
- }
- return (0);
-}
-
-/*
- * Prints the name and instance number of all flowops on
- * the master flowop list to the console and the filebench log.
- */
-void
-flowop_printall(void)
-{
- flowop_t *flowop = filebench_shm->shm_flowoplist;
-
- while (flowop) {
- filebench_log(LOG_VERBOSE, "flowop-list %s-%d",
- flowop->fo_name, flowop->fo_instance);
- flowop = flowop->fo_next;
- }
-}
-
-#define TIMESPEC_TO_HRTIME(s, e) (((e.tv_sec - s.tv_sec) * 1000000000LL) + \
- (e.tv_nsec - s.tv_nsec))
-/*
- * Puts current high resolution time in start time entry
- * for threadflow and may also calculate running filebench
- * overhead statistics.
- */
-void
-flowop_beginop(threadflow_t *threadflow, flowop_t *flowop)
-{
-#ifdef HAVE_PROCFS
- if ((filebench_shm->shm_mmode & FILEBENCH_MODE_NOUSAGE) == 0) {
- if ((noproc == 0) && (threadflow->tf_lwpusagefd == 0)) {
- char procname[128];
-
- (void) snprintf(procname, sizeof (procname),
- "/proc/%d/lwp/%d/lwpusage", my_pid, _lwp_self());
- threadflow->tf_lwpusagefd = open(procname, O_RDONLY);
- }
-
- (void) pread(threadflow->tf_lwpusagefd,
- &threadflow->tf_susage,
- sizeof (struct prusage), 0);
-
- /* Compute overhead time in this thread around op */
- if (threadflow->tf_eusage.pr_stime.tv_nsec) {
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_OHEAD] +=
- TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_utime,
- threadflow->tf_susage.pr_utime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_ttime,
- threadflow->tf_susage.pr_ttime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_stime,
- threadflow->tf_susage.pr_stime);
- }
- }
-#endif
-
- /* Start of op for this thread */
- threadflow->tf_stime = gethrtime();
-}
-
-flowstat_t controlstats;
-pthread_mutex_t controlstats_lock;
-static int controlstats_zeroed = 0;
-
-/*
- * Updates flowop's latency statistics, using saved start
- * time and current high resolution time. Updates flowop's
- * io count and transferred bytes statistics. Also updates
- * threadflow's and flowop's cumulative read or write byte
- * and io count statistics.
- */
-void
-flowop_endop(threadflow_t *threadflow, flowop_t *flowop, int64_t bytes)
-{
- hrtime_t t;
-
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] +=
- (gethrtime() - threadflow->tf_stime);
-#ifdef HAVE_PROCFS
- if ((filebench_shm->shm_mmode & FILEBENCH_MODE_NOUSAGE) == 0) {
- if ((pread(threadflow->tf_lwpusagefd, &threadflow->tf_eusage,
- sizeof (struct prusage), 0)) != sizeof (struct prusage))
- filebench_log(LOG_ERROR, "cannot read /proc");
-
- t =
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_utime,
- threadflow->tf_eusage.pr_utime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_ttime,
- threadflow->tf_eusage.pr_ttime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_stime,
- threadflow->tf_eusage.pr_stime);
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] += t;
-
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_WAIT] +=
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_tftime,
- threadflow->tf_eusage.pr_tftime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_dftime,
- threadflow->tf_eusage.pr_dftime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_kftime,
- threadflow->tf_eusage.pr_kftime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_kftime,
- threadflow->tf_eusage.pr_kftime) +
- TIMESPEC_TO_HRTIME(threadflow->tf_susage.pr_slptime,
- threadflow->tf_eusage.pr_slptime);
- }
-#endif
-
- flowop->fo_stats.fs_count++;
- flowop->fo_stats.fs_bytes += bytes;
- (void) ipc_mutex_lock(&controlstats_lock);
- if ((flowop->fo_type & FLOW_TYPE_IO) ||
- (flowop->fo_type & FLOW_TYPE_AIO)) {
- controlstats.fs_count++;
- controlstats.fs_bytes += bytes;
- }
- if (flowop->fo_attrs & FLOW_ATTR_READ) {
- threadflow->tf_stats.fs_rbytes += bytes;
- threadflow->tf_stats.fs_rcount++;
- flowop->fo_stats.fs_rcount++;
- controlstats.fs_rbytes += bytes;
- controlstats.fs_rcount++;
- } else if (flowop->fo_attrs & FLOW_ATTR_WRITE) {
- threadflow->tf_stats.fs_wbytes += bytes;
- threadflow->tf_stats.fs_wcount++;
- flowop->fo_stats.fs_wcount++;
- controlstats.fs_wbytes += bytes;
- controlstats.fs_wcount++;
- }
- (void) ipc_mutex_unlock(&controlstats_lock);
-}
-
-/*
- * Calls the flowop's initialization function, pointed to by
- * flowop->fo_init.
- */
-static int
-flowop_initflow(flowop_t *flowop)
-{
- /*
- * save static copies of two items, in case they are supplied
- * from random variables
- */
- if (!AVD_IS_STRING(flowop->fo_value))
- flowop->fo_constvalue = avd_get_int(flowop->fo_value);
-
- flowop->fo_constwss = avd_get_int(flowop->fo_wss);
-
- if ((*flowop->fo_init)(flowop) < 0) {
- filebench_log(LOG_ERROR, "flowop %s-%d init failed",
- flowop->fo_name, flowop->fo_instance);
- return (-1);
- }
- return (0);
-}
-
-static int
-flowop_create_runtime_flowops(threadflow_t *threadflow, flowop_t **ops_list_ptr)
-{
- flowop_t *flowop = *ops_list_ptr;
-
- while (flowop) {
- flowop_t *newflowop;
-
- if (flowop == *ops_list_ptr)
- *ops_list_ptr = NULL;
-
- newflowop = flowop_define_common(threadflow, flowop->fo_name,
- flowop, ops_list_ptr, 1, 0);
- if (newflowop == NULL)
- return (FILEBENCH_ERROR);
-
- /* check for fo_filename attribute, and resolve if present */
- if (flowop->fo_filename) {
- char *name;
-
- name = avd_get_str(flowop->fo_filename);
- newflowop->fo_fileset = fileset_find(name);
-
- if (newflowop->fo_fileset == NULL) {
- filebench_log(LOG_ERROR,
- "flowop %s: file %s not found",
- newflowop->fo_name, name);
- filebench_shutdown(1);
- }
- }
-
- if (flowop_initflow(newflowop) < 0) {
- filebench_log(LOG_ERROR, "Flowop init of %s failed",
- newflowop->fo_name);
- }
-
- flowop = flowop->fo_exec_next;
- }
- return (FILEBENCH_OK);
-}
-
-/*
- * Calls the flowop's destruct function, pointed to by
- * flowop->fo_destruct.
- */
-static void
-flowop_destructflow(flowop_t *flowop)
-{
- (*flowop->fo_destruct)(flowop);
-}
-
-/*
- * call the destruct funtions of all the threadflow's flowops,
- * if it is still flagged as "running".
- */
-void
-flowop_destruct_all_flows(threadflow_t *threadflow)
-{
- flowop_t *flowop;
-
- /* wait a moment to give other threads a chance to stop too */
- (void) sleep(1);
-
- (void) ipc_mutex_lock(&threadflow->tf_lock);
-
- /* prepare to call destruct flow routines, if necessary */
- if (threadflow->tf_running == 0) {
-
- /* allready destroyed */
- (void) ipc_mutex_unlock(&threadflow->tf_lock);
- return;
- }
-
- flowop = threadflow->tf_thrd_fops;
- threadflow->tf_running = 0;
- (void) ipc_mutex_unlock(&threadflow->tf_lock);
-
- while (flowop) {
- flowop_destructflow(flowop);
- flowop = flowop->fo_exec_next;
- }
-}
-
-/*
- * The final initialization and main execution loop for the
- * worker threads. Sets threadflow and flowop start times,
- * waits for all process to start, then creates the runtime
- * flowops from those defined by the F language workload
- * script. It does some more initialization, then enters a
- * loop to repeatedly execute the flowops on the flowop list
- * until an abort condition is detected, at which time it exits.
- * This is the starting routine for the new worker thread
- * created by threadflow_createthread(), and is not currently
- * called from anywhere else.
- */
-void
-flowop_start(threadflow_t *threadflow)
-{
- flowop_t *flowop;
- size_t memsize;
- int ret = FILEBENCH_OK;
-
-#ifdef HAVE_PROCFS
- if (noproc == 0) {
- char procname[128];
- long ctl[2] = {PCSET, PR_MSACCT};
- int pfd;
-
- (void) snprintf(procname, sizeof (procname),
- "/proc/%d/lwp/%d/lwpctl", my_pid, _lwp_self());
- pfd = open(procname, O_WRONLY);
- (void) pwrite(pfd, &ctl, sizeof (ctl), 0);
- (void) close(pfd);
- }
-#endif
-
- (void) ipc_mutex_lock(&controlstats_lock);
- if (!controlstats_zeroed) {
- (void) memset(&controlstats, 0, sizeof (controlstats));
- controlstats_zeroed = 1;
- }
- (void) ipc_mutex_unlock(&controlstats_lock);
-
- flowop = threadflow->tf_thrd_fops;
- threadflow->tf_stats.fs_stime = gethrtime();
- flowop->fo_stats.fs_stime = gethrtime();
-
- /* Hold the flowop find lock as reader to prevent lookups */
- (void) pthread_rwlock_rdlock(&filebench_shm->shm_flowop_find_lock);
-
- /*
- * Block until all processes have started, acting like
- * a barrier. The original filebench process initially
- * holds the run_lock as a reader, preventing any of the
- * threads from obtaining the writer lock, and hence
- * passing this point. Once all processes and threads
- * have been created, the original process unlocks
- * run_lock, allowing each waiting thread to lock
- * and then immediately unlock it, then begin running.
- */
- (void) pthread_rwlock_wrlock(&filebench_shm->shm_run_lock);
- (void) pthread_rwlock_unlock(&filebench_shm->shm_run_lock);
-
- /* Create the runtime flowops from those defined by the script */
- (void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
- if (flowop_create_runtime_flowops(threadflow, &threadflow->tf_thrd_fops)
- != FILEBENCH_OK) {
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
- filebench_shutdown(1);
- return;
- }
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
-
- /* Release the find lock as reader to allow lookups */
- (void) pthread_rwlock_unlock(&filebench_shm->shm_flowop_find_lock);
-
- /* Set to the start of the new flowop list */
- flowop = threadflow->tf_thrd_fops;
-
- threadflow->tf_abort = 0;
- threadflow->tf_running = 1;
-
- memsize = (size_t)threadflow->tf_constmemsize;
-
- /* If we are going to use ISM, allocate later */
- if (threadflow->tf_attrs & THREADFLOW_USEISM) {
- threadflow->tf_mem =
- ipc_ismmalloc(memsize);
- } else {
- threadflow->tf_mem =
- malloc(memsize);
- }
-
- (void) memset(threadflow->tf_mem, 0, memsize);
- filebench_log(LOG_DEBUG_SCRIPT, "Thread allocated %d bytes", memsize);
-
-#ifdef HAVE_LWPS
- filebench_log(LOG_DEBUG_SCRIPT, "Thread %zx (%d) started",
- threadflow,
- _lwp_self());
-#endif
-
- /* Main filebench worker loop */
- while (ret == FILEBENCH_OK) {
- int i, count;
-
- /* Abort if asked */
- if (threadflow->tf_abort || filebench_shm->shm_f_abort)
- break;
-
- /* Be quiet while stats are gathered */
- if (filebench_shm->shm_bequiet) {
- (void) sleep(1);
- continue;
- }
-
- /* Take it easy until everyone is ready to go */
- if (!filebench_shm->shm_procs_running) {
- (void) sleep(1);
- continue;
- }
-
- if (flowop == NULL) {
- filebench_log(LOG_ERROR, "flowop_read null flowop");
- return;
- }
-
- if (flowop->fo_stats.fs_stime == 0)
- flowop->fo_stats.fs_stime = gethrtime();
-
- /* Execute the flowop for fo_iters times */
- count = (int)avd_get_int(flowop->fo_iters);
- for (i = 0; i < count; i++) {
-
- filebench_log(LOG_DEBUG_SCRIPT, "%s: executing flowop "
- "%s-%d", threadflow->tf_name, flowop->fo_name,
- flowop->fo_instance);
-
- ret = (*flowop->fo_func)(threadflow, flowop);
-
- /*
- * Return value FILEBENCH_ERROR means "flowop
- * failed, stop the filebench run"
- */
- if (ret == FILEBENCH_ERROR) {
- filebench_log(LOG_ERROR,
- "%s-%d: flowop %s-%d failed",
- threadflow->tf_name,
- threadflow->tf_instance,
- flowop->fo_name,
- flowop->fo_instance);
- (void) ipc_mutex_lock(&threadflow->tf_lock);
- threadflow->tf_abort = 1;
- filebench_shm->shm_f_abort =
- FILEBENCH_ABORT_ERROR;
- (void) ipc_mutex_unlock(&threadflow->tf_lock);
- break;
- }
-
- /*
- * Return value of FILEBENCH_NORSC means "stop
- * the filebench run" if in "end on no work mode",
- * otherwise it indicates an error
- */
- if (ret == FILEBENCH_NORSC) {
- (void) ipc_mutex_lock(&threadflow->tf_lock);
- threadflow->tf_abort = FILEBENCH_DONE;
- if (filebench_shm->shm_rmode ==
- FILEBENCH_MODE_Q1STDONE) {
- filebench_shm->shm_f_abort =
- FILEBENCH_ABORT_RSRC;
- } else if (filebench_shm->shm_rmode !=
- FILEBENCH_MODE_QALLDONE) {
- filebench_log(LOG_ERROR1,
- "WARNING! Run stopped early:\n "
- " flowop %s-%d could "
- "not obtain a file. Please\n "
- " reduce runtime, "
- "increase fileset entries "
- "($nfiles), or switch modes.",
- flowop->fo_name,
- flowop->fo_instance);
- filebench_shm->shm_f_abort =
- FILEBENCH_ABORT_ERROR;
- }
- (void) ipc_mutex_unlock(&threadflow->tf_lock);
- break;
- }
-
- /*
- * Return value of FILEBENCH_DONE means "stop
- * the filebench run without error"
- */
- if (ret == FILEBENCH_DONE) {
- (void) ipc_mutex_lock(&threadflow->tf_lock);
- threadflow->tf_abort = FILEBENCH_DONE;
- filebench_shm->shm_f_abort =
- FILEBENCH_ABORT_DONE;
- (void) ipc_mutex_unlock(&threadflow->tf_lock);
- break;
- }
-
- /*
- * If we get here and the return is something other
- * than FILEBENCH_OK, it means a spurious code
- * was returned, so treat as major error. This
- * probably indicates a bug in the flowop.
- */
- if (ret != FILEBENCH_OK) {
- filebench_log(LOG_ERROR,
- "Flowop %s unexpected return value = %d\n",
- flowop->fo_name, ret);
- filebench_shm->shm_f_abort =
- FILEBENCH_ABORT_ERROR;
- break;
- }
- }
-
- /* advance to next flowop */
- flowop = flowop->fo_exec_next;
-
- /* but if at end of list, start over from the beginning */
- if (flowop == NULL) {
- flowop = threadflow->tf_thrd_fops;
- threadflow->tf_stats.fs_count++;
- }
- }
-
-#ifdef HAVE_LWPS
- filebench_log(LOG_DEBUG_SCRIPT, "Thread %d exiting",
- _lwp_self());
-#endif
-
- /* Tell flowops to destroy locally acquired state */
- flowop_destruct_all_flows(threadflow);
-
- pthread_exit(&threadflow->tf_abort);
-}
-
-void flowoplib_flowinit(void);
-void fb_lfs_flowinit(void);
-
-void
-flowop_init(void)
-{
- (void) pthread_mutex_init(&controlstats_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- flowoplib_flowinit();
-}
-
-static int plugin_flowinit_done = FALSE;
-
-/*
- * Initialize any "plug-in" flowops. Called when the first "create fileset"
- * command is encountered.
- */
-void
-flowop_plugin_flowinit(void)
-{
- if (plugin_flowinit_done)
- return;
-
- plugin_flowinit_done = TRUE;
-
- switch (filebench_shm->shm_filesys_type) {
- case LOCAL_FS_PLUG:
- fb_lfs_flowinit();
- break;
-
- case NFS3_PLUG:
- case NFS4_PLUG:
- case CIFS_PLUG:
- break;
- }
-}
-
-
-/*
- * Delete the designated flowop from the thread's flowop list.
- */
-static void
-flowop_delete(flowop_t **flowoplist, flowop_t *flowop)
-{
- flowop_t *entry = *flowoplist;
- int found = 0;
-
- filebench_log(LOG_DEBUG_IMPL, "Deleting flowop (%s-%d)",
- flowop->fo_name,
- flowop->fo_instance);
-
- /* Delete from thread's flowop list */
- if (flowop == *flowoplist) {
- /* First on list */
- *flowoplist = flowop->fo_exec_next;
- filebench_log(LOG_DEBUG_IMPL,
- "Delete0 flowop: (%s-%d)",
- flowop->fo_name,
- flowop->fo_instance);
- } else {
- while (entry->fo_exec_next) {
- filebench_log(LOG_DEBUG_IMPL,
- "Delete0 flowop: (%s-%d) == (%s-%d)",
- entry->fo_exec_next->fo_name,
- entry->fo_exec_next->fo_instance,
- flowop->fo_name,
- flowop->fo_instance);
-
- if (flowop == entry->fo_exec_next) {
- /* Delete */
- filebench_log(LOG_DEBUG_IMPL,
- "Deleted0 flowop: (%s-%d)",
- entry->fo_exec_next->fo_name,
- entry->fo_exec_next->fo_instance);
- entry->fo_exec_next =
- entry->fo_exec_next->fo_exec_next;
- break;
- }
- entry = entry->fo_exec_next;
- }
- }
-
-#ifdef HAVE_PROCFS
- /* Close /proc stats */
- if (flowop->fo_thread)
- (void) close(flowop->fo_thread->tf_lwpusagefd);
-#endif
-
- /* Delete from global list */
- entry = filebench_shm->shm_flowoplist;
-
- if (flowop == filebench_shm->shm_flowoplist) {
- /* First on list */
- filebench_shm->shm_flowoplist = flowop->fo_next;
- found = 1;
- } else {
- while (entry->fo_next) {
- filebench_log(LOG_DEBUG_IMPL,
- "Delete flowop: (%s-%d) == (%s-%d)",
- entry->fo_next->fo_name,
- entry->fo_next->fo_instance,
- flowop->fo_name,
- flowop->fo_instance);
-
- if (flowop == entry->fo_next) {
- /* Delete */
- entry->fo_next = entry->fo_next->fo_next;
- found = 1;
- break;
- }
-
- entry = entry->fo_next;
- }
- }
- if (found) {
- filebench_log(LOG_DEBUG_IMPL,
- "Deleted flowop: (%s-%d)",
- flowop->fo_name,
- flowop->fo_instance);
- ipc_free(FILEBENCH_FLOWOP, (char *)flowop);
- } else {
- filebench_log(LOG_DEBUG_IMPL, "Flowop %s-%d not found!",
- flowop->fo_name,
- flowop->fo_instance);
- }
-}
-
-/*
- * Deletes all the flowops from a flowop list.
- */
-void
-flowop_delete_all(flowop_t **flowoplist)
-{
- flowop_t *flowop = *flowoplist;
- flowop_t *next_flowop;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
-
- while (flowop) {
- filebench_log(LOG_DEBUG_IMPL, "Deleting flowop (%s-%d)",
- flowop->fo_name, flowop->fo_instance);
-
- if (flowop->fo_instance &&
- (flowop->fo_instance == FLOW_MASTER)) {
- flowop = flowop->fo_exec_next;
- continue;
- }
- next_flowop = flowop->fo_exec_next;
- flowop_delete(flowoplist, flowop);
- flowop = next_flowop;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
-}
-
-/*
- * Allocates a flowop entity and initializes it with inherited
- * contents from the "inherit" flowop, if it is supplied, or
- * with zeros otherwise. In either case the fo_next and fo_exec_next
- * pointers are set to NULL, and fo_thread is set to point to
- * the owning threadflow. The initialized flowop is placed at
- * the head of the global flowop list, and also placed on the
- * tail of the supplied local flowop list, which will either
- * be a threadflow's tf_thrd_fops list or a composite flowop's
- * fo_comp_fops list. The routine locks the flowop's fo_lock and
- * leaves it held on return. If successful, it returns a pointer
- * to the allocated and initialized flowop, otherwise it returns NULL.
- *
- * filebench_shm->shm_flowop_lock must be held by caller.
- */
-static flowop_t *
-flowop_define_common(threadflow_t *threadflow, char *name, flowop_t *inherit,
- flowop_t **flowoplist_hdp, int instance, int type)
-{
- flowop_t *flowop;
-
- if (name == NULL)
- return (NULL);
-
- if ((flowop = (flowop_t *)ipc_malloc(FILEBENCH_FLOWOP)) == NULL) {
- filebench_log(LOG_ERROR,
- "flowop_define: Can't malloc flowop");
- return (NULL);
- }
-
- filebench_log(LOG_DEBUG_IMPL, "defining flowops %s-%d, addr %zx",
- name, instance, flowop);
-
- if (flowop == NULL)
- return (NULL);
-
- if (inherit) {
- (void) memcpy(flowop, inherit, sizeof (flowop_t));
- (void) pthread_mutex_init(&flowop->fo_lock,
- ipc_mutexattr(IPC_MUTEX_PRI_ROB));
- (void) ipc_mutex_lock(&flowop->fo_lock);
- flowop->fo_next = NULL;
- flowop->fo_exec_next = NULL;
- filebench_log(LOG_DEBUG_IMPL,
- "flowop %s-%d calling init", name, instance);
- } else {
- (void) memset(flowop, 0, sizeof (flowop_t));
- flowop->fo_iters = avd_int_alloc(1);
- flowop->fo_type = type;
- (void) pthread_mutex_init(&flowop->fo_lock,
- ipc_mutexattr(IPC_MUTEX_PRI_ROB));
- (void) ipc_mutex_lock(&flowop->fo_lock);
- }
-
- /* Create backpointer to thread */
- flowop->fo_thread = threadflow;
-
- /* Add flowop to global list */
- if (filebench_shm->shm_flowoplist == NULL) {
- filebench_shm->shm_flowoplist = flowop;
- flowop->fo_next = NULL;
- } else {
- flowop->fo_next = filebench_shm->shm_flowoplist;
- filebench_shm->shm_flowoplist = flowop;
- }
-
- (void) strcpy(flowop->fo_name, name);
- flowop->fo_instance = instance;
-
- if (flowoplist_hdp == NULL)
- return (flowop);
-
- /* Add flowop to thread op list */
- if (*flowoplist_hdp == NULL) {
- *flowoplist_hdp = flowop;
- flowop->fo_exec_next = NULL;
- } else {
- flowop_t *flowend;
-
- /* Find the end of the thread list */
- flowend = *flowoplist_hdp;
- while (flowend->fo_exec_next != NULL)
- flowend = flowend->fo_exec_next;
- flowend->fo_exec_next = flowop;
- flowop->fo_exec_next = NULL;
- }
-
- return (flowop);
-}
-
-/*
- * Calls flowop_define_common() to allocate and initialize a
- * flowop, and holds the shared flowop_lock during the call.
- * It releases the created flowop's fo_lock when done.
- */
-flowop_t *
-flowop_define(threadflow_t *threadflow, char *name, flowop_t *inherit,
- flowop_t **flowoplist_hdp, int instance, int type)
-{
- flowop_t *flowop;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
- flowop = flowop_define_common(threadflow, name,
- inherit, flowoplist_hdp, instance, type);
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
-
- if (flowop == NULL)
- return (NULL);
-
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- return (flowop);
-}
-
-/*
- * Calls flowop_define_common() to allocate and initialize a
- * composite flowop, and holds the shared flowop_lock during the call.
- * It releases the created flowop's fo_lock when done.
- */
-flowop_t *
-flowop_new_composite_define(char *name)
-{
- flowop_t *flowop;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
- flowop = flowop_define_common(NULL, name,
- NULL, NULL, 0, FLOW_TYPE_COMPOSITE);
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
-
- if (flowop == NULL)
- return (NULL);
-
- flowop->fo_func = flowop_composite;
- flowop->fo_init = flowop_composite_init;
- flowop->fo_destruct = flowop_composite_destruct;
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- return (flowop);
-}
-
-/*
- * Attempts to take a write lock on the flowop_find_lock that is
- * defined in interprocess shared memory. Since each call to
- * flowop_start() holds a read lock on flowop_find_lock, this
- * routine effectively blocks until all instances of
- * flowop_start() have finished. The flowop_find() routine calls
- * this routine so that flowops won't be searched for until all
- * flowops have been created by flowop_start.
- */
-static void
-flowop_find_barrier(void)
-{
- /* Block on wrlock to ensure find waits for all creates */
- (void) pthread_rwlock_wrlock(&filebench_shm->shm_flowop_find_lock);
- (void) pthread_rwlock_unlock(&filebench_shm->shm_flowop_find_lock);
-}
-
-/*
- * Returns a list of flowops named "name" from the master
- * flowop list.
- */
-flowop_t *
-flowop_find(char *name)
-{
- flowop_t *flowop;
- flowop_t *result = NULL;
-
- flowop_find_barrier();
-
- (void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
-
- flowop = filebench_shm->shm_flowoplist;
-
- while (flowop) {
- if (strcmp(name, flowop->fo_name) == 0) {
-
- /* Add flowop to result list */
- if (result == NULL) {
- result = flowop;
- flowop->fo_resultnext = NULL;
- } else {
- flowop->fo_resultnext = result;
- result = flowop;
- }
- }
- flowop = flowop->fo_next;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
-
-
- return (result);
-}
-
-/*
- * Returns a pointer to the specified instance of flowop
- * "name" from the global list.
- */
-flowop_t *
-flowop_find_one(char *name, int instance)
-{
- flowop_t *test_flowop;
-
- flowop_find_barrier();
-
- (void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
-
- test_flowop = filebench_shm->shm_flowoplist;
-
- while (test_flowop) {
- if ((strcmp(name, test_flowop->fo_name) == 0) &&
- (instance == test_flowop->fo_instance))
- break;
-
- test_flowop = test_flowop->fo_next;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
-
- return (test_flowop);
-}
-
-/*
- * recursively searches through lists of flowops on a given thread
- * and those on any included composite flowops for the named flowop.
- * either returns with a pointer to the named flowop or NULL if it
- * cannot be found.
- */
-static flowop_t *
-flowop_recurse_search(char *path, char *name, flowop_t *list)
-{
- flowop_t *test_flowop;
- char fullname[MAXPATHLEN];
-
- test_flowop = list;
-
- /*
- * when searching a list of inner flowops, "path" is the fullname
- * of the containing composite flowop. Use it to form the
- * full name of the inner flowop to search for.
- */
- if (path) {
- if ((strlen(path) + strlen(name) + 1) > MAXPATHLEN) {
- filebench_log(LOG_ERROR,
- "composite flowop path name %s.%s too long",
- path, name);
- return (NULL);
- }
-
- /* create composite_name.name for recursive search */
- (void) strcpy(fullname, path);
- (void) strcat(fullname, ".");
- (void) strcat(fullname, name);
- } else {
- (void) strcpy(fullname, name);
- }
-
- /*
- * loop through all flowops on the supplied tf_thrd_fops (flowop)
- * list or fo_comp_fops (inner flowop) list.
- */
- while (test_flowop) {
- if (strcmp(fullname, test_flowop->fo_name) == 0)
- return (test_flowop);
-
- if (test_flowop->fo_type == FLOW_TYPE_COMPOSITE) {
- flowop_t *found_flowop;
-
- found_flowop = flowop_recurse_search(
- test_flowop->fo_name, name,
- test_flowop->fo_comp_fops);
-
- if (found_flowop)
- return (found_flowop);
- }
- test_flowop = test_flowop->fo_exec_next;
- }
-
- /* not found here or on any child lists */
- return (NULL);
-}
-
-/*
- * Returns a pointer to flowop named "name" from the supplied tf_thrd_fops
- * list of flowops. Returns the named flowop if found, or NULL.
- */
-flowop_t *
-flowop_find_from_list(char *name, flowop_t *list)
-{
- flowop_t *found_flowop;
-
- flowop_find_barrier();
-
- (void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
-
- found_flowop = flowop_recurse_search(NULL, name, list);
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
-
- return (found_flowop);
-}
-
-/*
- * Composite flowop method. Does one pass through its list of
- * inner flowops per iteration.
- */
-static int
-flowop_composite(threadflow_t *threadflow, flowop_t *flowop)
-{
- flowop_t *inner_flowop;
-
- /* get the first flowop in the list */
- inner_flowop = flowop->fo_comp_fops;
-
- /* make a pass through the list of sub flowops */
- while (inner_flowop) {
- int i, count;
-
- /* Abort if asked */
- if (threadflow->tf_abort || filebench_shm->shm_f_abort)
- return (FILEBENCH_DONE);
-
- if (inner_flowop->fo_stats.fs_stime == 0)
- inner_flowop->fo_stats.fs_stime = gethrtime();
-
- /* Execute the flowop for fo_iters times */
- count = (int)avd_get_int(inner_flowop->fo_iters);
- for (i = 0; i < count; i++) {
-
- filebench_log(LOG_DEBUG_SCRIPT, "%s: executing flowop "
- "%s-%d", threadflow->tf_name,
- inner_flowop->fo_name,
- inner_flowop->fo_instance);
-
- switch ((*inner_flowop->fo_func)(threadflow,
- inner_flowop)) {
-
- /* all done */
- case FILEBENCH_DONE:
- return (FILEBENCH_DONE);
-
- /* quit if inner flowop limit reached */
- case FILEBENCH_NORSC:
- return (FILEBENCH_NORSC);
-
- /* quit on inner flowop error */
- case FILEBENCH_ERROR:
- filebench_log(LOG_ERROR,
- "inner flowop %s failed",
- inner_flowop->fo_name);
- return (FILEBENCH_ERROR);
-
- /* otherwise keep going */
- default:
- break;
- }
-
- }
-
- /* advance to next flowop */
- inner_flowop = inner_flowop->fo_exec_next;
- }
-
- /* finished with this pass */
- return (FILEBENCH_OK);
-}
-
-/*
- * Composite flowop initialization. Creates runtime inner flowops
- * from prototype inner flowops.
- */
-static int
-flowop_composite_init(flowop_t *flowop)
-{
- int err;
-
- err = flowop_create_runtime_flowops(flowop->fo_thread,
- &flowop->fo_comp_fops);
- if (err != FILEBENCH_OK)
- return (err);
-
- (void) ipc_mutex_unlock(&flowop->fo_lock);
- return (0);
-}
-
-/*
- * clean up inner flowops
- */
-static void
-flowop_composite_destruct(flowop_t *flowop)
-{
- flowop_t *inner_flowop = flowop->fo_comp_fops;
-
- while (inner_flowop) {
- filebench_log(LOG_DEBUG_IMPL, "Deleting inner flowop (%s-%d)",
- inner_flowop->fo_name, inner_flowop->fo_instance);
-
- if (inner_flowop->fo_instance &&
- (inner_flowop->fo_instance == FLOW_MASTER)) {
- inner_flowop = inner_flowop->fo_exec_next;
- continue;
- }
- flowop_delete(&flowop->fo_comp_fops, inner_flowop);
- inner_flowop = inner_flowop->fo_exec_next;
- }
-}
-
-/*
- * Support routines for libraries of flowops
- */
-
-int
-flowop_init_generic(flowop_t *flowop)
-{
- (void) ipc_mutex_unlock(&flowop->fo_lock);
- return (FILEBENCH_OK);
-}
-
-void
-flowop_destruct_generic(flowop_t *flowop)
-{
- char *buf;
-
- /* release any local resources held by the flowop */
- (void) ipc_mutex_lock(&flowop->fo_lock);
- buf = flowop->fo_buf;
- flowop->fo_buf = NULL;
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- if (buf)
- free(buf);
-}
-
-
-/*
- * Loops through the supplied list of flowops and creates and initializes
- * a flowop for each one by calling flowop_define. As a side effect of
- * calling flowop define, the created flowops are placed on the
- * master flowop list. All created flowops are set to instance "0".
- */
-void
-flowop_flow_init(flowop_proto_t *list, int nops)
-{
- int i;
-
- for (i = 0; i < nops; i++) {
- flowop_t *flowop;
- flowop_proto_t *fl;
-
- fl = &(list[i]);
-
- if ((flowop = flowop_define(NULL,
- fl->fl_name, NULL, NULL, 0, fl->fl_type)) == 0) {
- filebench_log(LOG_ERROR,
- "failed to create flowop %s\n",
- fl->fl_name);
- filebench_shutdown(1);
- }
-
- flowop->fo_func = fl->fl_func;
- flowop->fo_init = fl->fl_init;
- flowop->fo_destruct = fl->fl_destruct;
- flowop->fo_attrs = fl->fl_attrs;
- }
-}
diff --git a/usr/src/cmd/filebench/common/flowop.h b/usr/src/cmd/filebench/common/flowop.h
deleted file mode 100644
index d08367e7b1..0000000000
--- a/usr/src/cmd/filebench/common/flowop.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_FLOWOP_H
-#define _FB_FLOWOP_H
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/resource.h>
-#include <pthread.h>
-#ifndef HAVE_SYSV_SEM
-#include <semaphore.h>
-#endif
-#include "stats.h"
-#include "threadflow.h"
-#include "vars.h"
-#include "fileset.h"
-#include "filebench.h"
-#include "fsplug.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct flowop {
- char fo_name[128]; /* Name */
- int fo_instance; /* Instance number */
- struct flowop *fo_next; /* Next in global list */
- struct flowop *fo_exec_next; /* Next in thread's or compfo's list */
- struct flowop *fo_resultnext; /* List of flowops in result */
- struct flowop *fo_comp_fops; /* List of flowops in composite fo */
- var_t *fo_lvar_list; /* List of composite local vars */
- struct threadflow *fo_thread; /* Backpointer to thread */
- int (*fo_func)(); /* Method */
- int (*fo_init)(); /* Init Method */
- void (*fo_destruct)(); /* Destructor Method */
- int fo_type; /* Type */
- int fo_attrs; /* Flow op attribute */
- avd_t fo_filename; /* file/fileset name */
- fileset_t *fo_fileset; /* Fileset for op */
- int fo_fd; /* File descriptor */
- int fo_fdnumber; /* User specified file descriptor */
- int fo_srcfdnumber; /* User specified src file descriptor */
- fbint_t fo_constvalue; /* constant version of fo_value */
- fbint_t fo_constwss; /* constant version of fo_wss */
- avd_t fo_iosize; /* Size of operation */
- avd_t fo_wss; /* Flow op working set size */
- char fo_targetname[128]; /* Target, for wakeup etc... */
- struct flowop *fo_targets; /* List of targets matching name */
- struct flowop *fo_targetnext; /* List of targets matching name */
- avd_t fo_iters; /* Number of iterations of op */
- avd_t fo_value; /* Attr */
- avd_t fo_sequential; /* Attr */
- avd_t fo_random; /* Attr */
- avd_t fo_stride; /* Attr */
- avd_t fo_backwards; /* Attr */
- avd_t fo_dsync; /* Attr */
- avd_t fo_blocking; /* Attr */
- avd_t fo_directio; /* Attr */
- avd_t fo_rotatefd; /* Attr */
- avd_t fo_fileindex; /* Attr */
- flowstat_t fo_stats; /* Flow statistics */
- pthread_cond_t fo_cv; /* Block/wakeup cv */
- pthread_mutex_t fo_lock; /* Mutex around flowop */
- void *fo_private; /* Flowop private scratch pad area */
- char *fo_buf; /* Per-flowop buffer */
- uint64_t fo_buf_size; /* current size of buffer */
-#ifdef HAVE_SYSV_SEM
- int fo_semid_lw; /* sem id */
- int fo_semid_hw; /* sem id for highwater block */
-#else
- sem_t fo_sem; /* sem_t for posix semaphores */
-#endif /* HAVE_SYSV_SEM */
- avd_t fo_highwater; /* value of highwater paramter */
- void *fo_idp; /* id, for sems etc */
- hrtime_t fo_timestamp; /* for ratecontrol, etc... */
- int fo_initted; /* Set to one if initialized */
- int64_t fo_tputbucket; /* Throughput bucket, for limiter */
- uint64_t fo_tputlast; /* Throughput count, for delta's */
-
-} flowop_t;
-
-/* Flow Op Attrs */
-#define FLOW_ATTR_SEQUENTIAL 0x1
-#define FLOW_ATTR_RANDOM 0x2
-#define FLOW_ATTR_STRIDE 0x4
-#define FLOW_ATTR_BACKWARDS 0x8
-#define FLOW_ATTR_DSYNC 0x10
-#define FLOW_ATTR_BLOCKING 0x20
-#define FLOW_ATTR_DIRECTIO 0x40
-#define FLOW_ATTR_READ 0x80
-#define FLOW_ATTR_WRITE 0x100
-
-/* Flowop Instance Numbers */
- /* Worker flowops have instance numbers > 0 */
-#define FLOW_DEFINITION 0 /* Prototype definition of flowop from library */
-#define FLOW_INNER_DEF -1 /* Constructed proto flowops within composite */
-#define FLOW_MASTER -2 /* Master flowop based on flowop declaration */
- /* supplied within a thread definition */
-
-/* Flowop type definitions */
-
-#define FLOW_TYPES 6
-#define FLOW_TYPE_GLOBAL 0 /* Rolled up statistics */
-#define FLOW_TYPE_IO 1 /* Op is an I/O, reflected in iops and lat */
-#define FLOW_TYPE_AIO 2 /* Op is an async I/O, reflected in iops */
-#define FLOW_TYPE_SYNC 3 /* Op is a sync event */
-#define FLOW_TYPE_COMPOSITE 4 /* Op is a composite flowop */
-#define FLOW_TYPE_OTHER 5 /* Op is a something else */
-
-typedef struct flowop_proto {
- int fl_type;
- int fl_attrs;
- char *fl_name;
- int (*fl_init)();
- int (*fl_func)();
- void (*fl_destruct)();
-} flowop_proto_t;
-
-extern flowstat_t controlstats;
-extern pthread_mutex_t controlstats_lock;
-
-void flowop_init(void);
-void flowop_plugin_flowinit(void);
-flowop_t *flowop_define(threadflow_t *, char *name, flowop_t *inherit,
- flowop_t **flowoplist_hdp, int instance, int type);
-flowop_t *flowop_find(char *name);
-flowop_t *flowop_find_one(char *name, int instance);
-flowop_t *flowop_find_from_list(char *name, flowop_t *list);
-int flowop_init_generic(flowop_t *flowop);
-void flowop_destruct_generic(flowop_t *flowop);
-void flowop_flow_init(flowop_proto_t *list, int nops);
-void flowoplib_usage(void);
-int flowoplib_iosetup(threadflow_t *threadflow, flowop_t *flowop,
- fbint_t *wssp, caddr_t *iobufp, fb_fdesc_t **filedescp, fbint_t iosize);
-void flowop_delete_all(flowop_t **threadlist);
-void flowop_endop(threadflow_t *threadflow, flowop_t *flowop, int64_t bytes);
-void flowop_beginop(threadflow_t *threadflow, flowop_t *flowop);
-void flowop_destruct_all_flows(threadflow_t *threadflow);
-flowop_t *flowop_new_composite_define(char *name);
-void flowop_printall(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_FLOWOP_H */
diff --git a/usr/src/cmd/filebench/common/flowop_library.c b/usr/src/cmd/filebench/common/flowop_library.c
deleted file mode 100644
index 6c7be68c48..0000000000
--- a/usr/src/cmd/filebench/common/flowop_library.c
+++ /dev/null
@@ -1,2712 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_ASYNCH_H
-#include <sys/asynch.h>
-#endif
-#include <stddef.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/errno.h>
-#include <sys/time.h>
-#include <inttypes.h>
-#include <fcntl.h>
-#include <math.h>
-#include <dirent.h>
-
-#ifdef HAVE_UTILITY_H
-#include <utility.h>
-#endif /* HAVE_UTILITY_H */
-
-#ifdef HAVE_SYS_ASYNC_H
-#include <sys/asynch.h>
-#endif /* HAVE_SYS_ASYNC_H */
-
-#ifndef HAVE_SYSV_SEM
-#include <semaphore.h>
-#endif /* HAVE_SYSV_SEM */
-
-#include "filebench.h"
-#include "flowop.h"
-#include "fileset.h"
-#include "fb_random.h"
-#include "utils.h"
-#include "fsplug.h"
-
-/*
- * These routines implement the flowops from the f language. Each
- * flowop has has a name such as "read", and a set of function pointers
- * to call for initialization, execution and destruction of the flowop.
- * The table flowoplib_funcs[] contains a flowoplib struct for each
- * implemented flowop. Most flowops use a generic initialization function
- * and all currently use a generic destruction function. All flowop
- * functions referenced from the table are in this file, though, of
- * course, they often call functions from other files.
- *
- * The flowop_init() routine uses the flowoplib_funcs[] table to
- * create an initial set of "instance 0" flowops, one for each type of
- * flowop, from which all other flowops are derived. These "instance 0"
- * flowops are initialized with information from the table including
- * pointers for their fo_init, fo_func and fo_destroy functions. When
- * a flowop definition is encountered in an f language script, the
- * "type" of flowop, such as "read" is used to search for the
- * "instance 0" flowop named "read", then a new flowop is allocated
- * which inherits its function pointers and other initial properties
- * from the instance 0 flowop, and is given a new name as specified
- * by the "name=" attribute.
- */
-
-static void flowoplib_destruct_noop(flowop_t *flowop);
-static int flowoplib_fdnum(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_print(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_write(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_read(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_block_init(flowop_t *flowop);
-static int flowoplib_block(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_wakeup(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_hog(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_delay(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_sempost(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_sempost_init(flowop_t *flowop);
-static int flowoplib_semblock(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_semblock_init(flowop_t *flowop);
-static void flowoplib_semblock_destruct(flowop_t *flowop);
-static int flowoplib_eventlimit(threadflow_t *, flowop_t *flowop);
-static int flowoplib_bwlimit(threadflow_t *, flowop_t *flowop);
-static int flowoplib_iopslimit(threadflow_t *, flowop_t *flowop);
-static int flowoplib_opslimit(threadflow_t *, flowop_t *flowop);
-static int flowoplib_openfile(threadflow_t *, flowop_t *flowop);
-static int flowoplib_openfile_common(threadflow_t *, flowop_t *flowop, int fd);
-static int flowoplib_createfile(threadflow_t *, flowop_t *flowop);
-static int flowoplib_closefile(threadflow_t *, flowop_t *flowop);
-static int flowoplib_makedir(threadflow_t *, flowop_t *flowop);
-static int flowoplib_removedir(threadflow_t *, flowop_t *flowop);
-static int flowoplib_listdir(threadflow_t *, flowop_t *flowop);
-static int flowoplib_fsync(threadflow_t *, flowop_t *flowop);
-static int flowoplib_readwholefile(threadflow_t *, flowop_t *flowop);
-static int flowoplib_writewholefile(threadflow_t *, flowop_t *flowop);
-static int flowoplib_appendfile(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_appendfilerand(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_deletefile(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_statfile(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_finishoncount(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_finishonbytes(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_fsyncset(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_testrandvar(threadflow_t *threadflow, flowop_t *flowop);
-static int flowoplib_testrandvar_init(flowop_t *flowop);
-static void flowoplib_testrandvar_destruct(flowop_t *flowop);
-
-static flowop_proto_t flowoplib_funcs[] = {
- FLOW_TYPE_IO, FLOW_ATTR_WRITE, "write", flowop_init_generic,
- flowoplib_write, flowop_destruct_generic,
- FLOW_TYPE_IO, FLOW_ATTR_READ, "read", flowop_init_generic,
- flowoplib_read, flowop_destruct_generic,
- FLOW_TYPE_SYNC, 0, "block", flowoplib_block_init,
- flowoplib_block, flowop_destruct_generic,
- FLOW_TYPE_SYNC, 0, "wakeup", flowop_init_generic,
- flowoplib_wakeup, flowop_destruct_generic,
- FLOW_TYPE_SYNC, 0, "semblock", flowoplib_semblock_init,
- flowoplib_semblock, flowoplib_semblock_destruct,
- FLOW_TYPE_SYNC, 0, "sempost", flowoplib_sempost_init,
- flowoplib_sempost, flowoplib_destruct_noop,
- FLOW_TYPE_OTHER, 0, "hog", flowop_init_generic,
- flowoplib_hog, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "delay", flowop_init_generic,
- flowoplib_delay, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "eventlimit", flowop_init_generic,
- flowoplib_eventlimit, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "bwlimit", flowop_init_generic,
- flowoplib_bwlimit, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "iopslimit", flowop_init_generic,
- flowoplib_iopslimit, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "opslimit", flowop_init_generic,
- flowoplib_opslimit, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "finishoncount", flowop_init_generic,
- flowoplib_finishoncount, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "finishonbytes", flowop_init_generic,
- flowoplib_finishonbytes, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "openfile", flowop_init_generic,
- flowoplib_openfile, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "createfile", flowop_init_generic,
- flowoplib_createfile, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "closefile", flowop_init_generic,
- flowoplib_closefile, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "makedir", flowop_init_generic,
- flowoplib_makedir, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "removedir", flowop_init_generic,
- flowoplib_removedir, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "listdir", flowop_init_generic,
- flowoplib_listdir, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "fsync", flowop_init_generic,
- flowoplib_fsync, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "fsyncset", flowop_init_generic,
- flowoplib_fsyncset, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "statfile", flowop_init_generic,
- flowoplib_statfile, flowop_destruct_generic,
- FLOW_TYPE_IO, FLOW_ATTR_READ, "readwholefile", flowop_init_generic,
- flowoplib_readwholefile, flowop_destruct_generic,
- FLOW_TYPE_IO, FLOW_ATTR_WRITE, "appendfile", flowop_init_generic,
- flowoplib_appendfile, flowop_destruct_generic,
- FLOW_TYPE_IO, FLOW_ATTR_WRITE, "appendfilerand", flowop_init_generic,
- flowoplib_appendfilerand, flowop_destruct_generic,
- FLOW_TYPE_IO, 0, "deletefile", flowop_init_generic,
- flowoplib_deletefile, flowop_destruct_generic,
- FLOW_TYPE_IO, FLOW_ATTR_WRITE, "writewholefile", flowop_init_generic,
- flowoplib_writewholefile, flowop_destruct_generic,
- FLOW_TYPE_OTHER, 0, "print", flowop_init_generic,
- flowoplib_print, flowop_destruct_generic,
- /* routine to calculate mean and stddev for output from a randvar */
- FLOW_TYPE_OTHER, 0, "testrandvar", flowoplib_testrandvar_init,
- flowoplib_testrandvar, flowoplib_testrandvar_destruct
-};
-
-/*
- * Loops through the list of flowops defined in this
- * module, and creates and initializes a flowop for each one
- * by calling flowop_flow_init. As a side effect of calling
- * flowop_flow_init, the created flowops are placed on the
- * master flowop list. All created flowops are set to
- * instance "0".
- */
-void
-flowoplib_flowinit()
-{
- int nops = sizeof (flowoplib_funcs) / sizeof (flowop_proto_t);
-
- flowop_flow_init(flowoplib_funcs, nops);
-}
-
-/*
- * Special total noop destruct
- */
-/* ARGSUSED */
-static void
-flowoplib_destruct_noop(flowop_t *flowop)
-{
-}
-
-/*
- * Generates a file attribute from flags in the supplied flowop.
- * Sets FLOW_ATTR_DIRECTIO and/or FLOW_ATTR_DSYNC as needed.
- */
-static int
-flowoplib_fileattrs(flowop_t *flowop)
-{
- int attrs = 0;
-
- if (avd_get_bool(flowop->fo_directio))
- attrs |= FLOW_ATTR_DIRECTIO;
-
- if (avd_get_bool(flowop->fo_dsync))
- attrs |= FLOW_ATTR_DSYNC;
-
- return (attrs);
-}
-
-/*
- * Obtain a filesetentry for a file. Result placed where filep points.
- * Supply with a flowop and a flag to indicate whether an existent or
- * non-existent file is required. Returns FILEBENCH_NORSC if all out
- * of the appropriate type of directories, FILEBENCH_ERROR if the
- * flowop does not point to a fileset, and FILEBENCH_OK otherwise.
- */
-static int
-flowoplib_pickfile(filesetentry_t **filep, flowop_t *flowop, int flags, int tid)
-{
- fileset_t *fileset;
- int fileindex;
-
- if ((fileset = flowop->fo_fileset) == NULL) {
- filebench_log(LOG_ERROR, "flowop NO fileset");
- return (FILEBENCH_ERROR);
- }
-
- if (flowop->fo_fileindex) {
- fileindex = (int)(avd_get_dbl(flowop->fo_fileindex) *
- ((double)(fileset->fs_constentries / 2)));
- fileindex = fileindex % fileset->fs_constentries;
- flags |= FILESET_PICKBYINDEX;
- } else {
- fileindex = 0;
- }
-
- if ((*filep = fileset_pick(fileset, FILESET_PICKFILE | flags,
- tid, fileindex)) == NULL) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s failed to pick file from fileset %s",
- flowop->fo_name,
- avd_get_str(fileset->fs_name));
- return (FILEBENCH_NORSC);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Obtain a filesetentry for a leaf directory. Result placed where dirp
- * points. Supply with flowop and a flag to indicate whether an existent
- * or non-existent leaf directory is required. Returns FILEBENCH_NORSC
- * if all out of the appropriate type of directories, FILEBENCH_ERROR
- * if the flowop does not point to a fileset, and FILEBENCH_OK otherwise.
- */
-static int
-flowoplib_pickleafdir(filesetentry_t **dirp, flowop_t *flowop, int flags)
-{
- fileset_t *fileset;
- int dirindex;
-
- if ((fileset = flowop->fo_fileset) == NULL) {
- filebench_log(LOG_ERROR, "flowop NO fileset");
- return (FILEBENCH_ERROR);
- }
-
- if (flowop->fo_fileindex) {
- dirindex = (int)(avd_get_dbl(flowop->fo_fileindex) *
- ((double)(fileset->fs_constleafdirs / 2)));
- dirindex = dirindex % fileset->fs_constleafdirs;
- flags |= FILESET_PICKBYINDEX;
- } else {
- dirindex = 0;
- }
-
- if ((*dirp = fileset_pick(fileset,
- FILESET_PICKLEAFDIR | flags, 0, dirindex)) == NULL) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s failed to pick directory from fileset %s",
- flowop->fo_name,
- avd_get_str(fileset->fs_name));
- return (FILEBENCH_NORSC);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Searches for a file descriptor. Tries the flowop's
- * fo_fdnumber first and returns with it if it has been
- * explicitly set (greater than 0). It next checks to
- * see if a rotating file descriptor policy is in effect,
- * and if not returns the fdnumber regardless of what
- * it is. (note that if it is 0, it just selects to the
- * default file descriptor in the threadflow's tf_fd
- * array). If the rotating fd policy is in effect, it
- * cycles from the end of the tf_fd array to one location
- * beyond the maximum needed by the number of entries in
- * the associated fileset on each invocation, then starts
- * over from the end.
- *
- * The routine returns an index into the threadflow's
- * tf_fd table where the actual file descriptor will be
- * found. Note: the calling routine must not call this
- * routine if the flowop does not have a fileset, and the
- * flowop's fo_fdnumber is zero and fo_rotatefd is
- * asserted, or an addressing fault may occur.
- */
-static int
-flowoplib_fdnum(threadflow_t *threadflow, flowop_t *flowop)
-{
- fbint_t entries;
- int fdnumber = flowop->fo_fdnumber;
-
- /* If the script sets the fd explicitly */
- if (fdnumber > 0)
- return (fdnumber);
-
- /* If the flowop defaults to persistent fd */
- if (!avd_get_bool(flowop->fo_rotatefd))
- return (fdnumber);
-
- if (flowop->fo_fileset == NULL) {
- filebench_log(LOG_ERROR, "flowop NULL file");
- return (FILEBENCH_ERROR);
- }
-
- entries = flowop->fo_fileset->fs_constentries;
-
- /* Rotate the fd on each flowop invocation */
- if (entries > (THREADFLOW_MAXFD / 2)) {
- filebench_log(LOG_ERROR, "Out of file descriptors in flowop %s"
- " (too many files : %llu",
- flowop->fo_name, (u_longlong_t)entries);
- return (FILEBENCH_ERROR);
- }
-
- /* First time around */
- if (threadflow->tf_fdrotor == 0)
- threadflow->tf_fdrotor = THREADFLOW_MAXFD;
-
- /* One fd for every file in the set */
- if (entries == (THREADFLOW_MAXFD - threadflow->tf_fdrotor))
- threadflow->tf_fdrotor = THREADFLOW_MAXFD;
-
-
- threadflow->tf_fdrotor--;
- filebench_log(LOG_DEBUG_IMPL, "selected fd = %d",
- threadflow->tf_fdrotor);
- return (threadflow->tf_fdrotor);
-}
-
-/*
- * Determines the file descriptor to use, and attempts to open
- * the file if it is not already open. Also determines the wss
- * value. Returns FILEBENCH_ERROR on errors, FILESET_NORSC if
- * if flowop_openfile_common couldn't obtain an appropriate file
- * from a the fileset, and FILEBENCH_OK otherwise.
- */
-static int
-flowoplib_filesetup(threadflow_t *threadflow, flowop_t *flowop,
- fbint_t *wssp, fb_fdesc_t **fdescp)
-{
- int fd = flowoplib_fdnum(threadflow, flowop);
-
- if (fd == -1)
- return (FILEBENCH_ERROR);
-
- /* check for conflicting fdnumber and file name */
- if ((fd > 0) && (threadflow->tf_fse[fd] != NULL)) {
- char *fd_based_name;
-
- fd_based_name =
- avd_get_str(threadflow->tf_fse[fd]->fse_fileset->fs_name);
-
- if (flowop->fo_filename != NULL) {
- char *fo_based_name;
-
- fo_based_name = avd_get_str(flowop->fo_filename);
- if (strcmp(fd_based_name, fo_based_name) != 0) {
- filebench_log(LOG_ERROR, "Name of fd refer"
- "enced fileset name (%s) CONFLICTS with"
- " flowop supplied fileset name (%s)",
- fd_based_name, fo_based_name);
- filebench_shutdown(1);
- return (FILEBENCH_ERROR);
- }
- }
- }
-
- if (threadflow->tf_fd[fd].fd_ptr == NULL) {
- int ret;
-
- if ((ret = flowoplib_openfile_common(
- threadflow, flowop, fd)) != FILEBENCH_OK)
- return (ret);
-
- if (threadflow->tf_fse[fd]) {
- filebench_log(LOG_DEBUG_IMPL, "opened file %s",
- threadflow->tf_fse[fd]->fse_path);
- } else {
- filebench_log(LOG_DEBUG_IMPL,
- "opened device %s/%s",
- avd_get_str(flowop->fo_fileset->fs_path),
- avd_get_str(flowop->fo_fileset->fs_name));
- }
- }
-
- *fdescp = &(threadflow->tf_fd[fd]);
-
- if ((*wssp = flowop->fo_constwss) == 0) {
- if (threadflow->tf_fse[fd])
- *wssp = threadflow->tf_fse[fd]->fse_size;
- else
- *wssp = avd_get_int(flowop->fo_fileset->fs_size);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Determines the io buffer or random offset into tf_mem for
- * the IO operation. Returns FILEBENCH_ERROR on errors, FILEBENCH_OK otherwise.
- */
-static int
-flowoplib_iobufsetup(threadflow_t *threadflow, flowop_t *flowop,
- caddr_t *iobufp, fbint_t iosize)
-{
- long memsize;
- size_t memoffset;
-
- if (iosize == 0) {
- filebench_log(LOG_ERROR, "zero iosize for thread %s",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- if ((memsize = threadflow->tf_constmemsize) != 0) {
-
- /* use tf_mem for I/O with random offset */
- if (filebench_randomno(&memoffset,
- memsize, iosize, NULL) == -1) {
- filebench_log(LOG_ERROR,
- "tf_memsize smaller than IO size for thread %s",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
- *iobufp = threadflow->tf_mem + memoffset;
-
- } else {
- /* use private I/O buffer */
- if ((flowop->fo_buf != NULL) &&
- (flowop->fo_buf_size < iosize)) {
- /* too small, so free up and re-allocate */
- free(flowop->fo_buf);
- flowop->fo_buf = NULL;
- }
-
- /*
- * Allocate memory for the buffer. The memory is freed
- * by flowop_destruct_generic() or by this routine if more
- * memory is needed for the buffer.
- */
- if ((flowop->fo_buf == NULL) && ((flowop->fo_buf
- = (char *)malloc(iosize)) == NULL))
- return (FILEBENCH_ERROR);
-
- flowop->fo_buf_size = iosize;
- *iobufp = flowop->fo_buf;
- }
- return (FILEBENCH_OK);
-}
-
-/*
- * Determines the file descriptor to use, opens it if necessary, the
- * io buffer or random offset into tf_mem for IO operation and the wss
- * value. Returns FILEBENCH_ERROR on errors, FILEBENCH_OK otherwise.
- */
-int
-flowoplib_iosetup(threadflow_t *threadflow, flowop_t *flowop,
- fbint_t *wssp, caddr_t *iobufp, fb_fdesc_t **filedescp, fbint_t iosize)
-{
- int ret;
-
- if ((ret = flowoplib_filesetup(threadflow, flowop, wssp, filedescp)) !=
- FILEBENCH_OK)
- return (ret);
-
- if ((ret = flowoplib_iobufsetup(threadflow, flowop, iobufp, iosize)) !=
- FILEBENCH_OK)
- return (ret);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate posix read / pread. If the flowop has a fileset,
- * a file descriptor number index is fetched, otherwise a
- * supplied fileobj file is used. In either case the specified
- * file will be opened if not already open. If the flowop has
- * neither a fileset or fileobj, an error is logged and FILEBENCH_ERROR
- * returned.
- *
- * The actual read is done to a random offset in the
- * threadflow's thread memory (tf_mem), with a size set by
- * fo_iosize and at either a random disk offset within the
- * working set size, or at the next sequential location. If
- * any errors are encountered, FILEBENCH_ERROR is returned,
- * if no appropriate file can be obtained from the fileset then
- * FILEBENCH_NORSC is returned, otherise FILEBENCH_OK is returned.
- */
-static int
-flowoplib_read(threadflow_t *threadflow, flowop_t *flowop)
-{
- caddr_t iobuf;
- fbint_t wss;
- fbint_t iosize;
- fb_fdesc_t *fdesc;
- int ret;
-
-
- iosize = avd_get_int(flowop->fo_iosize);
- if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf,
- &fdesc, iosize)) != FILEBENCH_OK)
- return (ret);
-
- if (avd_get_bool(flowop->fo_random)) {
- uint64_t fileoffset;
-
- if (filebench_randomno64(&fileoffset,
- wss, iosize, NULL) == -1) {
- filebench_log(LOG_ERROR,
- "file size smaller than IO size for thread %s",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- (void) flowop_beginop(threadflow, flowop);
- if ((ret = FB_PREAD(fdesc, iobuf,
- iosize, (off64_t)fileoffset)) == -1) {
- (void) flowop_endop(threadflow, flowop, 0);
- filebench_log(LOG_ERROR,
- "read file %s failed, offset %llu "
- "io buffer %zd: %s",
- avd_get_str(flowop->fo_fileset->fs_name),
- (u_longlong_t)fileoffset, iobuf, strerror(errno));
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
- (void) flowop_endop(threadflow, flowop, ret);
-
- if ((ret == 0))
- (void) FB_LSEEK(fdesc, 0, SEEK_SET);
-
- } else {
- (void) flowop_beginop(threadflow, flowop);
- if ((ret = FB_READ(fdesc, iobuf, iosize)) == -1) {
- (void) flowop_endop(threadflow, flowop, 0);
- filebench_log(LOG_ERROR,
- "read file %s failed, io buffer %zd: %s",
- avd_get_str(flowop->fo_fileset->fs_name),
- iobuf, strerror(errno));
- (void) flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
- (void) flowop_endop(threadflow, flowop, ret);
-
- if ((ret == 0))
- (void) FB_LSEEK(fdesc, 0, SEEK_SET);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Initializes a "flowop_block" flowop. Specifically, it
- * initializes the flowop's fo_cv and unlocks the fo_lock.
- */
-static int
-flowoplib_block_init(flowop_t *flowop)
-{
- filebench_log(LOG_DEBUG_IMPL, "flow %s-%d block init address %zx",
- flowop->fo_name, flowop->fo_instance, &flowop->fo_cv);
- (void) pthread_cond_init(&flowop->fo_cv, ipc_condattr());
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Blocks the threadflow until woken up by flowoplib_wakeup.
- * The routine blocks on the flowop's fo_cv condition variable.
- */
-static int
-flowoplib_block(threadflow_t *threadflow, flowop_t *flowop)
-{
- filebench_log(LOG_DEBUG_IMPL, "flow %s-%d blocking at address %zx",
- flowop->fo_name, flowop->fo_instance, &flowop->fo_cv);
- (void) ipc_mutex_lock(&flowop->fo_lock);
-
- flowop_beginop(threadflow, flowop);
- (void) pthread_cond_wait(&flowop->fo_cv, &flowop->fo_lock);
- flowop_endop(threadflow, flowop, 0);
-
- filebench_log(LOG_DEBUG_IMPL, "flow %s-%d unblocking",
- flowop->fo_name, flowop->fo_instance);
-
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Wakes up one or more target blocking flowops.
- * Sends broadcasts on the fo_cv condition variables of all
- * flowops on the target list, except those that are
- * FLOW_MASTER flowops. The target list consists of all
- * flowops whose name matches this flowop's "fo_targetname"
- * attribute. The target list is generated on the first
- * invocation, and the run will be shutdown if no targets
- * are found. Otherwise the routine always returns FILEBENCH_OK.
- */
-static int
-flowoplib_wakeup(threadflow_t *threadflow, flowop_t *flowop)
-{
- flowop_t *target;
-
- /* if this is the first wakeup, create the wakeup list */
- if (flowop->fo_targets == NULL) {
- flowop_t *result = flowop_find(flowop->fo_targetname);
-
- flowop->fo_targets = result;
- if (result == NULL) {
- filebench_log(LOG_ERROR,
- "wakeup: could not find op %s for thread %s",
- flowop->fo_targetname,
- threadflow->tf_name);
- filebench_shutdown(1);
- }
- while (result) {
- result->fo_targetnext =
- result->fo_resultnext;
- result = result->fo_resultnext;
- }
- }
-
- target = flowop->fo_targets;
-
- /* wakeup the targets */
- while (target) {
- if (target->fo_instance == FLOW_MASTER) {
- target = target->fo_targetnext;
- continue;
- }
- filebench_log(LOG_DEBUG_IMPL,
- "wakeup flow %s-%d at address %zx",
- target->fo_name,
- target->fo_instance,
- &target->fo_cv);
-
- flowop_beginop(threadflow, flowop);
- (void) ipc_mutex_lock(&target->fo_lock);
- (void) pthread_cond_broadcast(&target->fo_cv);
- (void) ipc_mutex_unlock(&target->fo_lock);
- flowop_endop(threadflow, flowop, 0);
-
- target = target->fo_targetnext;
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * "think time" routines. the "hog" routine consumes cpu cycles as
- * it "thinks", while the "delay" flowop simply calls sleep() to delay
- * for a given number of seconds without consuming cpu cycles.
- */
-
-
-/*
- * Consumes CPU cycles and memory bandwidth by looping for
- * flowop->fo_value times. With each loop sets memory location
- * threadflow->tf_mem to 1.
- */
-static int
-flowoplib_hog(threadflow_t *threadflow, flowop_t *flowop)
-{
- uint64_t value = avd_get_int(flowop->fo_value);
- int i;
-
- filebench_log(LOG_DEBUG_IMPL, "hog enter");
- flowop_beginop(threadflow, flowop);
- if (threadflow->tf_mem != NULL) {
- for (i = 0; i < value; i++)
- *(threadflow->tf_mem) = 1;
- }
- flowop_endop(threadflow, flowop, 0);
- filebench_log(LOG_DEBUG_IMPL, "hog exit");
- return (FILEBENCH_OK);
-}
-
-
-/*
- * Delays for fo_value seconds.
- */
-static int
-flowoplib_delay(threadflow_t *threadflow, flowop_t *flowop)
-{
- int value = avd_get_int(flowop->fo_value);
-
- flowop_beginop(threadflow, flowop);
- (void) sleep(value);
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_OK);
-}
-
-/*
- * Rate limiting routines. This is the event consuming half of the
- * event system. Each of the four following routines will limit the rate
- * to one unit of either calls, issued I/O operations, issued filebench
- * operations, or I/O bandwidth. Since there is only one event generator,
- * the events will be divided amoung multiple instances of an event
- * consumer, and further divided among different consumers if more than
- * one has been defined. There is no mechanism to enforce equal sharing
- * of events.
- */
-
-/*
- * Completes one invocation per posted event. If eventgen_q
- * has an event count greater than zero, one will be removed
- * (count decremented), otherwise the calling thread will
- * block until another event has been posted. Always returns 0
- */
-static int
-flowoplib_eventlimit(threadflow_t *threadflow, flowop_t *flowop)
-{
- /* Immediately bail if not set/enabled */
- if (!filebench_shm->shm_eventgen_enabled)
- return (FILEBENCH_OK);
-
- if (flowop->fo_initted == 0) {
- filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking",
- flowop, threadflow->tf_name, threadflow->tf_instance);
- flowop->fo_initted = 1;
- }
-
- flowop_beginop(threadflow, flowop);
- while (filebench_shm->shm_eventgen_enabled) {
- (void) ipc_mutex_lock(&filebench_shm->shm_eventgen_lock);
- if (filebench_shm->shm_eventgen_q > 0) {
- filebench_shm->shm_eventgen_q--;
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_eventgen_lock);
- break;
- }
- (void) pthread_cond_wait(&filebench_shm->shm_eventgen_cv,
- &filebench_shm->shm_eventgen_lock);
- (void) ipc_mutex_unlock(&filebench_shm->shm_eventgen_lock);
- }
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_OK);
-}
-
-static int
-flowoplib_event_find_target(threadflow_t *threadflow, flowop_t *flowop)
-{
- if (flowop->fo_targetname[0] != '\0') {
-
- /* Try to use statistics from specific flowop */
- flowop->fo_targets =
- flowop_find_from_list(flowop->fo_targetname,
- threadflow->tf_thrd_fops);
- if (flowop->fo_targets == NULL) {
- filebench_log(LOG_ERROR,
- "limit target: could not find flowop %s",
- flowop->fo_targetname);
- filebench_shutdown(1);
- return (FILEBENCH_ERROR);
- }
- } else {
- /* use total workload statistics */
- flowop->fo_targets = NULL;
- }
- return (FILEBENCH_OK);
-}
-
-/*
- * Blocks the calling thread if the number of issued I/O
- * operations exceeds the number of posted events, thus
- * limiting the average I/O operation rate to the rate
- * specified by eventgen_hz. Always returns FILEBENCH_OK.
- */
-static int
-flowoplib_iopslimit(threadflow_t *threadflow, flowop_t *flowop)
-{
- uint64_t iops;
- uint64_t delta;
- uint64_t events;
-
- /* Immediately bail if not set/enabled */
- if (!filebench_shm->shm_eventgen_enabled)
- return (FILEBENCH_OK);
-
- if (flowop->fo_initted == 0) {
- filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking",
- flowop, threadflow->tf_name, threadflow->tf_instance);
- flowop->fo_initted = 1;
-
- if (flowoplib_event_find_target(threadflow, flowop)
- == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
-
- if (flowop->fo_targets && ((flowop->fo_targets->fo_attrs &
- (FLOW_ATTR_READ | FLOW_ATTR_WRITE)) == 0)) {
- filebench_log(LOG_ERROR,
- "WARNING: Flowop %s does no IO",
- flowop->fo_targets->fo_name);
- filebench_shutdown(1);
- return (FILEBENCH_ERROR);
- }
- }
-
- if (flowop->fo_targets) {
- /*
- * Note that fs_count is already the sum of fs_rcount
- * and fs_wcount if looking at a single flowop.
- */
- iops = flowop->fo_targets->fo_stats.fs_count;
- } else {
- (void) ipc_mutex_lock(&controlstats_lock);
- iops = (controlstats.fs_rcount +
- controlstats.fs_wcount);
- (void) ipc_mutex_unlock(&controlstats_lock);
- }
-
- /* Is this the first time around */
- if (flowop->fo_tputlast == 0) {
- flowop->fo_tputlast = iops;
- return (FILEBENCH_OK);
- }
-
- delta = iops - flowop->fo_tputlast;
- flowop->fo_tputbucket -= delta;
- flowop->fo_tputlast = iops;
-
- /* No need to block if the q isn't empty */
- if (flowop->fo_tputbucket >= 0LL) {
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_OK);
- }
-
- iops = flowop->fo_tputbucket * -1;
- events = iops;
-
- flowop_beginop(threadflow, flowop);
- while (filebench_shm->shm_eventgen_enabled) {
-
- (void) ipc_mutex_lock(&filebench_shm->shm_eventgen_lock);
- if (filebench_shm->shm_eventgen_q >= events) {
- filebench_shm->shm_eventgen_q -= events;
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_eventgen_lock);
- flowop->fo_tputbucket += events;
- break;
- }
- (void) pthread_cond_wait(&filebench_shm->shm_eventgen_cv,
- &filebench_shm->shm_eventgen_lock);
- (void) ipc_mutex_unlock(&filebench_shm->shm_eventgen_lock);
- }
- flowop_endop(threadflow, flowop, 0);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Blocks the calling thread if the number of issued filebench
- * operations exceeds the number of posted events, thus limiting
- * the average filebench operation rate to the rate specified by
- * eventgen_hz. Always returns FILEBENCH_OK.
- */
-static int
-flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop)
-{
- uint64_t ops;
- uint64_t delta;
- uint64_t events;
-
- /* Immediately bail if not set/enabled */
- if (!filebench_shm->shm_eventgen_enabled)
- return (FILEBENCH_OK);
-
- if (flowop->fo_initted == 0) {
- filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking",
- flowop, threadflow->tf_name, threadflow->tf_instance);
- flowop->fo_initted = 1;
-
- if (flowoplib_event_find_target(threadflow, flowop)
- == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
- }
-
- if (flowop->fo_targets) {
- ops = flowop->fo_targets->fo_stats.fs_count;
- } else {
- (void) ipc_mutex_lock(&controlstats_lock);
- ops = controlstats.fs_count;
- (void) ipc_mutex_unlock(&controlstats_lock);
- }
-
- /* Is this the first time around */
- if (flowop->fo_tputlast == 0) {
- flowop->fo_tputlast = ops;
- return (FILEBENCH_OK);
- }
-
- delta = ops - flowop->fo_tputlast;
- flowop->fo_tputbucket -= delta;
- flowop->fo_tputlast = ops;
-
- /* No need to block if the q isn't empty */
- if (flowop->fo_tputbucket >= 0LL) {
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_OK);
- }
-
- ops = flowop->fo_tputbucket * -1;
- events = ops;
-
- flowop_beginop(threadflow, flowop);
- while (filebench_shm->shm_eventgen_enabled) {
- (void) ipc_mutex_lock(&filebench_shm->shm_eventgen_lock);
- if (filebench_shm->shm_eventgen_q >= events) {
- filebench_shm->shm_eventgen_q -= events;
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_eventgen_lock);
- flowop->fo_tputbucket += events;
- break;
- }
- (void) pthread_cond_wait(&filebench_shm->shm_eventgen_cv,
- &filebench_shm->shm_eventgen_lock);
- (void) ipc_mutex_unlock(&filebench_shm->shm_eventgen_lock);
- }
- flowop_endop(threadflow, flowop, 0);
-
- return (FILEBENCH_OK);
-}
-
-
-/*
- * Blocks the calling thread if the number of bytes of I/O
- * issued exceeds one megabyte times the number of posted
- * events, thus limiting the average I/O byte rate to one
- * megabyte times the event rate as set by eventgen_hz.
- * Always retuns FILEBENCH_OK.
- */
-static int
-flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop)
-{
- uint64_t bytes;
- uint64_t delta;
- uint64_t events;
-
- /* Immediately bail if not set/enabled */
- if (!filebench_shm->shm_eventgen_enabled)
- return (FILEBENCH_OK);
-
- if (flowop->fo_initted == 0) {
- filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking",
- flowop, threadflow->tf_name, threadflow->tf_instance);
- flowop->fo_initted = 1;
-
- if (flowoplib_event_find_target(threadflow, flowop)
- == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
-
- if ((flowop->fo_targets) &&
- ((flowop->fo_targets->fo_attrs &
- (FLOW_ATTR_READ | FLOW_ATTR_WRITE)) == 0)) {
- filebench_log(LOG_ERROR,
- "WARNING: Flowop %s does no Reads or Writes",
- flowop->fo_targets->fo_name);
- filebench_shutdown(1);
- return (FILEBENCH_ERROR);
- }
- }
-
- if (flowop->fo_targets) {
- /*
- * Note that fs_bytes is already the sum of fs_rbytes
- * and fs_wbytes if looking at a single flowop.
- */
- bytes = flowop->fo_targets->fo_stats.fs_bytes;
- } else {
- (void) ipc_mutex_lock(&controlstats_lock);
- bytes = (controlstats.fs_rbytes +
- controlstats.fs_wbytes);
- (void) ipc_mutex_unlock(&controlstats_lock);
- }
-
- /* Is this the first time around? */
- if (flowop->fo_tputlast == 0) {
- flowop->fo_tputlast = bytes;
- return (FILEBENCH_OK);
- }
-
- delta = bytes - flowop->fo_tputlast;
- flowop->fo_tputbucket -= delta;
- flowop->fo_tputlast = bytes;
-
- /* No need to block if the q isn't empty */
- if (flowop->fo_tputbucket >= 0LL) {
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_OK);
- }
-
- bytes = flowop->fo_tputbucket * -1;
- events = (bytes / MB) + 1;
-
- filebench_log(LOG_DEBUG_IMPL, "%llu bytes, %llu events",
- (u_longlong_t)bytes, (u_longlong_t)events);
-
- flowop_beginop(threadflow, flowop);
- while (filebench_shm->shm_eventgen_enabled) {
- (void) ipc_mutex_lock(&filebench_shm->shm_eventgen_lock);
- if (filebench_shm->shm_eventgen_q >= events) {
- filebench_shm->shm_eventgen_q -= events;
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_eventgen_lock);
- flowop->fo_tputbucket += (events * MB);
- break;
- }
- (void) pthread_cond_wait(&filebench_shm->shm_eventgen_cv,
- &filebench_shm->shm_eventgen_lock);
- (void) ipc_mutex_unlock(&filebench_shm->shm_eventgen_lock);
- }
- flowop_endop(threadflow, flowop, 0);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * These flowops terminate a benchmark run when either the specified
- * number of bytes of I/O (flowoplib_finishonbytes) or the specified
- * number of I/O operations (flowoplib_finishoncount) have been generated.
- */
-
-
-/*
- * Stop filebench run when specified number of I/O bytes have been
- * transferred. Compares controlstats.fs_bytes with flowop->value,
- * and if greater returns 1, stopping the run, if not, returns 0
- * to continue running.
- */
-static int
-flowoplib_finishonbytes(threadflow_t *threadflow, flowop_t *flowop)
-{
- uint64_t bytes_io; /* Bytes of I/O delivered so far */
- uint64_t byte_lim = flowop->fo_constvalue; /* Total Bytes desired */
- /* Uses constant value */
-
- if (flowop->fo_initted == 0) {
- filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking",
- flowop, threadflow->tf_name, threadflow->tf_instance);
- flowop->fo_initted = 1;
-
- if (flowoplib_event_find_target(threadflow, flowop)
- == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
-
- if ((flowop->fo_targets) &&
- ((flowop->fo_targets->fo_attrs &
- (FLOW_ATTR_READ | FLOW_ATTR_WRITE)) == 0)) {
- filebench_log(LOG_ERROR,
- "WARNING: Flowop %s does no Reads or Writes",
- flowop->fo_targets->fo_name);
- filebench_shutdown(1);
- return (FILEBENCH_ERROR);
- }
- }
-
- if (flowop->fo_targets) {
- bytes_io = flowop->fo_targets->fo_stats.fs_bytes;
- } else {
- (void) ipc_mutex_lock(&controlstats_lock);
- bytes_io = controlstats.fs_bytes;
- (void) ipc_mutex_unlock(&controlstats_lock);
- }
-
- flowop_beginop(threadflow, flowop);
- if (bytes_io > byte_lim) {
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_DONE);
- }
- flowop_endop(threadflow, flowop, 0);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Stop filebench run when specified number of I/O operations have
- * been performed. Compares controlstats.fs_count with *flowop->value,
- * and if greater returns 1, stopping the run, if not, returns FILEBENCH_OK
- * to continue running.
- */
-static int
-flowoplib_finishoncount(threadflow_t *threadflow, flowop_t *flowop)
-{
- uint64_t ops;
- uint64_t count = flowop->fo_constvalue; /* use constant value */
-
- if (flowop->fo_initted == 0) {
- filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking",
- flowop, threadflow->tf_name, threadflow->tf_instance);
- flowop->fo_initted = 1;
-
- if (flowoplib_event_find_target(threadflow, flowop)
- == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
- }
-
- if (flowop->fo_targets) {
- ops = flowop->fo_targets->fo_stats.fs_count;
- } else {
- (void) ipc_mutex_lock(&controlstats_lock);
- ops = controlstats.fs_count;
- (void) ipc_mutex_unlock(&controlstats_lock);
- }
-
- flowop_beginop(threadflow, flowop);
- if (ops >= count) {
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_DONE);
- }
- flowop_endop(threadflow, flowop, 0);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Semaphore synchronization using either System V semaphores or
- * posix semaphores. If System V semaphores are available, they will be
- * used, otherwise posix semaphores will be used.
- */
-
-
-/*
- * Initializes the filebench "block on semaphore" flowop.
- * If System V semaphores are implemented, the routine
- * initializes the System V semaphore subsystem if it hasn't
- * already been initialized, also allocates a pair of semids
- * and initializes the highwater System V semaphore.
- * If no System V semaphores, then does nothing special.
- * Returns FILEBENCH_ERROR if it cannot acquire a set of System V semphores
- * or if the initial post to the semaphore set fails. Returns FILEBENCH_OK
- * on success.
- */
-static int
-flowoplib_semblock_init(flowop_t *flowop)
-{
-
-#ifdef HAVE_SYSV_SEM
- int sys_semid;
- struct sembuf sbuf[2];
- int highwater;
-
- ipc_seminit();
-
- flowop->fo_semid_lw = ipc_semidalloc();
- flowop->fo_semid_hw = ipc_semidalloc();
-
- filebench_log(LOG_DEBUG_IMPL, "flow %s-%d semblock init semid=%x",
- flowop->fo_name, flowop->fo_instance, flowop->fo_semid_lw);
-
- sys_semid = filebench_shm->shm_sys_semid;
-
- if ((highwater = flowop->fo_semid_hw) == 0)
- highwater = flowop->fo_constvalue; /* use constant value */
-
- filebench_log(LOG_DEBUG_IMPL, "setting highwater to : %d", highwater);
-
- sbuf[0].sem_num = (short)highwater;
- sbuf[0].sem_op = avd_get_int(flowop->fo_highwater);
- sbuf[0].sem_flg = 0;
- if ((semop(sys_semid, &sbuf[0], 1) == -1) && errno) {
- filebench_log(LOG_ERROR, "semblock init post failed: %s (%d,"
- "%d)", strerror(errno), sbuf[0].sem_num, sbuf[0].sem_op);
- return (FILEBENCH_ERROR);
- }
-#else
- filebench_log(LOG_DEBUG_IMPL,
- "flow %s-%d semblock init with posix semaphore",
- flowop->fo_name, flowop->fo_instance);
-
- sem_init(&flowop->fo_sem, 1, 0);
-#endif /* HAVE_SYSV_SEM */
-
- if (!(avd_get_bool(flowop->fo_blocking)))
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Releases the semids for the System V semaphore allocated
- * to this flowop. If not using System V semaphores, then
- * it is effectively just a no-op.
- */
-static void
-flowoplib_semblock_destruct(flowop_t *flowop)
-{
-#ifdef HAVE_SYSV_SEM
- ipc_semidfree(flowop->fo_semid_lw);
- ipc_semidfree(flowop->fo_semid_hw);
-#else
- sem_destroy(&flowop->fo_sem);
-#endif /* HAVE_SYSV_SEM */
-}
-
-/*
- * Attempts to pass a System V or posix semaphore as appropriate,
- * and blocks if necessary. Returns FILEBENCH_ERROR if a set of System V
- * semphores is not available or cannot be acquired, or if the initial
- * post to the semaphore set fails. Returns FILEBENCH_OK on success.
- */
-static int
-flowoplib_semblock(threadflow_t *threadflow, flowop_t *flowop)
-{
-
-#ifdef HAVE_SYSV_SEM
- struct sembuf sbuf[2];
- int value = avd_get_int(flowop->fo_value);
- int sys_semid;
- struct timespec timeout;
-
- sys_semid = filebench_shm->shm_sys_semid;
-
- filebench_log(LOG_DEBUG_IMPL,
- "flow %s-%d sem blocking on id %x num %x value %d",
- flowop->fo_name, flowop->fo_instance, sys_semid,
- flowop->fo_semid_hw, value);
-
- /* Post, decrement the increment the hw queue */
- sbuf[0].sem_num = flowop->fo_semid_hw;
- sbuf[0].sem_op = (short)value;
- sbuf[0].sem_flg = 0;
- sbuf[1].sem_num = flowop->fo_semid_lw;
- sbuf[1].sem_op = value * -1;
- sbuf[1].sem_flg = 0;
- timeout.tv_sec = 600;
- timeout.tv_nsec = 0;
-
- if (avd_get_bool(flowop->fo_blocking))
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- flowop_beginop(threadflow, flowop);
-
-#ifdef HAVE_SEMTIMEDOP
- (void) semtimedop(sys_semid, &sbuf[0], 1, &timeout);
- (void) semtimedop(sys_semid, &sbuf[1], 1, &timeout);
-#else
- (void) semop(sys_semid, &sbuf[0], 1);
- (void) semop(sys_semid, &sbuf[1], 1);
-#endif /* HAVE_SEMTIMEDOP */
-
- if (avd_get_bool(flowop->fo_blocking))
- (void) ipc_mutex_lock(&flowop->fo_lock);
-
- flowop_endop(threadflow, flowop, 0);
-
-#else
- int value = avd_get_int(flowop->fo_value);
- int i;
-
- filebench_log(LOG_DEBUG_IMPL,
- "flow %s-%d sem blocking on posix semaphore",
- flowop->fo_name, flowop->fo_instance);
-
- /* Decrement sem by value */
- for (i = 0; i < value; i++) {
- if (sem_wait(&flowop->fo_sem) == -1) {
- filebench_log(LOG_ERROR, "semop wait failed");
- return (FILEBENCH_ERROR);
- }
- }
-
- filebench_log(LOG_DEBUG_IMPL, "flow %s-%d sem unblocking",
- flowop->fo_name, flowop->fo_instance);
-#endif /* HAVE_SYSV_SEM */
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Calls ipc_seminit(). Always returns FILEBENCH_OK.
- */
-/* ARGSUSED */
-static int
-flowoplib_sempost_init(flowop_t *flowop)
-{
-#ifdef HAVE_SYSV_SEM
- ipc_seminit();
-#endif /* HAVE_SYSV_SEM */
- return (FILEBENCH_OK);
-}
-
-/*
- * Post to a System V or posix semaphore as appropriate.
- * On the first call for a given flowop instance, this routine
- * will use the fo_targetname attribute to locate all semblock
- * flowops that are expecting posts from this flowop. All
- * target flowops on this list will have a post operation done
- * to their semaphores on each call.
- */
-static int
-flowoplib_sempost(threadflow_t *threadflow, flowop_t *flowop)
-{
- flowop_t *target;
-
- filebench_log(LOG_DEBUG_IMPL,
- "sempost flow %s-%d",
- flowop->fo_name,
- flowop->fo_instance);
-
- /* if this is the first post, create the post list */
- if (flowop->fo_targets == NULL) {
- flowop_t *result = flowop_find(flowop->fo_targetname);
-
- flowop->fo_targets = result;
-
- if (result == NULL) {
- filebench_log(LOG_ERROR,
- "sempost: could not find op %s for thread %s",
- flowop->fo_targetname,
- threadflow->tf_name);
- filebench_shutdown(1);
- }
-
- while (result) {
- result->fo_targetnext =
- result->fo_resultnext;
- result = result->fo_resultnext;
- }
- }
-
- target = flowop->fo_targets;
-
- flowop_beginop(threadflow, flowop);
- /* post to the targets */
- while (target) {
-#ifdef HAVE_SYSV_SEM
- struct sembuf sbuf[2];
- int sys_semid;
- int blocking;
-#else
- int i;
-#endif /* HAVE_SYSV_SEM */
- struct timespec timeout;
- int value = (int)avd_get_int(flowop->fo_value);
-
- if (target->fo_instance == FLOW_MASTER) {
- target = target->fo_targetnext;
- continue;
- }
-
-#ifdef HAVE_SYSV_SEM
-
- filebench_log(LOG_DEBUG_IMPL,
- "sempost flow %s-%d num %x",
- target->fo_name,
- target->fo_instance,
- target->fo_semid_lw);
-
- sys_semid = filebench_shm->shm_sys_semid;
- sbuf[0].sem_num = target->fo_semid_lw;
- sbuf[0].sem_op = (short)value;
- sbuf[0].sem_flg = 0;
- sbuf[1].sem_num = target->fo_semid_hw;
- sbuf[1].sem_op = value * -1;
- sbuf[1].sem_flg = 0;
- timeout.tv_sec = 600;
- timeout.tv_nsec = 0;
-
- if (avd_get_bool(flowop->fo_blocking))
- blocking = 1;
- else
- blocking = 0;
-
-#ifdef HAVE_SEMTIMEDOP
- if ((semtimedop(sys_semid, &sbuf[0], blocking + 1,
- &timeout) == -1) && (errno && (errno != EAGAIN))) {
-#else
- if ((semop(sys_semid, &sbuf[0], blocking + 1) == -1) &&
- (errno && (errno != EAGAIN))) {
-#endif /* HAVE_SEMTIMEDOP */
- filebench_log(LOG_ERROR, "semop post failed: %s",
- strerror(errno));
- return (FILEBENCH_ERROR);
- }
-
- filebench_log(LOG_DEBUG_IMPL,
- "flow %s-%d finished posting",
- target->fo_name, target->fo_instance);
-#else
- filebench_log(LOG_DEBUG_IMPL,
- "sempost flow %s-%d to posix semaphore",
- target->fo_name,
- target->fo_instance);
-
- /* Increment sem by value */
- for (i = 0; i < value; i++) {
- if (sem_post(&target->fo_sem) == -1) {
- filebench_log(LOG_ERROR, "semop post failed");
- return (FILEBENCH_ERROR);
- }
- }
-
- filebench_log(LOG_DEBUG_IMPL, "flow %s-%d unblocking",
- target->fo_name, target->fo_instance);
-#endif /* HAVE_SYSV_SEM */
-
- target = target->fo_targetnext;
- }
- flowop_endop(threadflow, flowop, 0);
-
- return (FILEBENCH_OK);
-}
-
-
-/*
- * Section for exercising create / open / close / delete operations
- * on files within a fileset. For proper operation, the flowop attribute
- * "fd", which sets the fo_fdnumber field in the flowop, must be used
- * so that the same file is opened and later closed. "fd" is an index
- * into a pair of arrays maintained by threadflows, one of which
- * contains the operating system assigned file descriptors and the other
- * a pointer to the filesetentry whose file the file descriptor
- * references. An openfile flowop defined without fd being set will use
- * the default (0) fd or, if specified, rotate through fd indices, but
- * createfile and closefile must use the default or a specified fd.
- * Meanwhile deletefile picks and arbitrary file to delete, regardless
- * of fd attribute.
- */
-
-/*
- * Emulates (and actually does) file open. Obtains a file descriptor
- * index, then calls flowoplib_openfile_common() to open. Returns
- * FILEBENCH_ERROR if no file descriptor is found, and returns the
- * status from flowoplib_openfile_common otherwise (FILEBENCH_ERROR,
- * FILEBENCH_NORSC, FILEBENCH_OK).
- */
-static int
-flowoplib_openfile(threadflow_t *threadflow, flowop_t *flowop)
-{
- int fd = flowoplib_fdnum(threadflow, flowop);
-
- if (fd == -1)
- return (FILEBENCH_ERROR);
-
- return (flowoplib_openfile_common(threadflow, flowop, fd));
-}
-
-/*
- * Common file opening code for filesets. Uses the supplied
- * file descriptor index to determine the tf_fd entry to use.
- * If the entry is empty (0) and the fileset exists, fileset
- * pick is called to select a fileset entry to use. The file
- * specified in the filesetentry is opened, and the returned
- * operating system file descriptor and a pointer to the
- * filesetentry are stored in tf_fd[fd] and tf_fse[fd],
- * respectively. Returns FILEBENCH_ERROR on error,
- * FILEBENCH_NORSC if no suitable filesetentry can be found,
- * and FILEBENCH_OK on success.
- */
-static int
-flowoplib_openfile_common(threadflow_t *threadflow, flowop_t *flowop, int fd)
-{
- filesetentry_t *file;
- char *fileset_name;
- int tid = 0;
- int openflag = 0;
- int err;
-
- if (flowop->fo_fileset == NULL) {
- filebench_log(LOG_ERROR, "flowop NULL file");
- return (FILEBENCH_ERROR);
- }
-
- if ((fileset_name =
- avd_get_str(flowop->fo_fileset->fs_name)) == NULL) {
- filebench_log(LOG_ERROR,
- "flowop %s: fileset has no name", flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- /*
- * set the open flag for read only or read/write, as appropriate.
- */
- if (avd_get_bool(flowop->fo_fileset->fs_readonly) == TRUE)
- openflag = O_RDONLY;
- else
- openflag = O_RDWR;
-
- /*
- * If the flowop doesn't default to persistent fd
- * then get unique thread ID for use by fileset_pick
- */
- if (avd_get_bool(flowop->fo_rotatefd))
- tid = threadflow->tf_utid;
-
- if (threadflow->tf_fd[fd].fd_ptr != NULL) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted to open without closing on fd %d",
- flowop->fo_name, fd);
- return (FILEBENCH_ERROR);
- }
-
-#ifdef HAVE_RAW_SUPPORT
- if (flowop->fo_fileset->fs_attrs & FILESET_IS_RAW_DEV) {
- int open_attrs = 0;
- char name[MAXPATHLEN];
-
- (void) fb_strlcpy(name,
- avd_get_str(flowop->fo_fileset->fs_path), MAXPATHLEN);
- (void) fb_strlcat(name, "/", MAXPATHLEN);
- (void) fb_strlcat(name, fileset_name, MAXPATHLEN);
-
- if (avd_get_bool(flowop->fo_dsync)) {
-#ifdef sun
- open_attrs |= O_DSYNC;
-#else
- open_attrs |= O_FSYNC;
-#endif
- }
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "open raw device %s flags %d = %d", name, open_attrs, fd);
-
- if (FB_OPEN(&(threadflow->tf_fd[fd]), name,
- openflag | open_attrs, 0666) == FILEBENCH_ERROR) {
- filebench_log(LOG_ERROR,
- "Failed to open raw device %s: %s",
- name, strerror(errno));
- return (FILEBENCH_ERROR);
- }
-
- /* if running on Solaris, use un-buffered io */
-#ifdef sun
- (void) directio(threadflow->tf_fd[fd].fd_num, DIRECTIO_ON);
-#endif
-
- threadflow->tf_fse[fd] = NULL;
-
- return (FILEBENCH_OK);
- }
-#endif /* HAVE_RAW_SUPPORT */
-
- if ((err = flowoplib_pickfile(&file, flowop,
- FILESET_PICKEXISTS, tid)) != FILEBENCH_OK) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s failed to pick file from %s on fd %d",
- flowop->fo_name, fileset_name, fd);
- return (err);
- }
-
- threadflow->tf_fse[fd] = file;
-
- flowop_beginop(threadflow, flowop);
- err = fileset_openfile(&threadflow->tf_fd[fd], flowop->fo_fileset,
- file, openflag, 0666, flowoplib_fileattrs(flowop));
- flowop_endop(threadflow, flowop, 0);
-
- if (err == FILEBENCH_ERROR) {
- filebench_log(LOG_ERROR, "flowop %s failed to open file %s",
- flowop->fo_name, file->fse_path);
- return (FILEBENCH_ERROR);
- }
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s: opened %s fd[%d] = %d",
- flowop->fo_name, file->fse_path, fd, threadflow->tf_fd[fd]);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate create of a file. Uses the flowop's fdnumber to select
- * tf_fd and tf_fse array locations to put the created file's file
- * descriptor and filesetentry respectively. Uses flowoplib_pickfile()
- * to select a specific filesetentry whose file does not currently
- * exist for the file create operation. Then calls
- * fileset_openfile() with the O_CREATE flag set to create the
- * file. Returns FILEBENCH_ERROR if the array index specified by fdnumber is
- * already in use, the flowop has no associated fileset, or
- * the create call fails. Returns 1 if a filesetentry with a
- * nonexistent file cannot be found. Returns FILEBENCH_OK on success.
- */
-static int
-flowoplib_createfile(threadflow_t *threadflow, flowop_t *flowop)
-{
- filesetentry_t *file;
- int fd = flowop->fo_fdnumber;
- int err;
-
- if (threadflow->tf_fd[fd].fd_ptr != NULL) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted to create without closing on fd %d",
- flowop->fo_name, fd);
- return (FILEBENCH_ERROR);
- }
-
- if (flowop->fo_fileset == NULL) {
- filebench_log(LOG_ERROR, "flowop NULL file");
- return (FILEBENCH_ERROR);
- }
-
- if (avd_get_bool(flowop->fo_fileset->fs_readonly) == TRUE) {
- filebench_log(LOG_ERROR, "Can not CREATE the READONLY file %s",
- avd_get_str(flowop->fo_fileset->fs_name));
- return (FILEBENCH_ERROR);
- }
-
-
-#ifdef HAVE_RAW_SUPPORT
- /* can't be used with raw devices */
- if (flowop->fo_fileset->fs_attrs & FILESET_IS_RAW_DEV) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted to a createfile on RAW device",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-#endif /* HAVE_RAW_SUPPORT */
-
- if ((err = flowoplib_pickfile(&file, flowop,
- FILESET_PICKNOEXIST, 0)) != FILEBENCH_OK) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s failed to pick file from fileset %s",
- flowop->fo_name,
- avd_get_str(flowop->fo_fileset->fs_name));
- return (err);
- }
-
- threadflow->tf_fse[fd] = file;
-
- flowop_beginop(threadflow, flowop);
- err = fileset_openfile(&threadflow->tf_fd[fd], flowop->fo_fileset,
- file, O_RDWR | O_CREAT, 0666, flowoplib_fileattrs(flowop));
- flowop_endop(threadflow, flowop, 0);
-
- if (err == FILEBENCH_ERROR) {
- filebench_log(LOG_ERROR, "failed to create file %s",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s: created %s fd[%d] = %d",
- flowop->fo_name, file->fse_path, fd, threadflow->tf_fd[fd]);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulates delete of a file. If a valid fd is provided, it uses the
- * filesetentry stored at that fd location to select the file to be
- * deleted, otherwise it picks an arbitrary filesetentry
- * whose file exists. It then uses unlink() to delete it and Clears
- * the FSE_EXISTS flag for the filesetentry. Returns FILEBENCH_ERROR if the
- * flowop has no associated fileset. Returns FILEBENCH_NORSC if an appropriate
- * filesetentry cannot be found, and FILEBENCH_OK on success.
- */
-static int
-flowoplib_deletefile(threadflow_t *threadflow, flowop_t *flowop)
-{
- filesetentry_t *file;
- fileset_t *fileset;
- char path[MAXPATHLEN];
- char *pathtmp;
- int fd = flowop->fo_fdnumber;
-
- /* if fd specified, use it to access file */
- if ((fd > 0) && ((file = threadflow->tf_fse[fd]) != NULL)) {
-
- /* indicate that the file will be deleted */
- threadflow->tf_fse[fd] = NULL;
-
- /* if here, we still have a valid file pointer */
- fileset = file->fse_fileset;
- } else {
-
- /* Otherwise, pick arbitrary file */
- file = NULL;
- fileset = flowop->fo_fileset;
- }
-
-
- if (fileset == NULL) {
- filebench_log(LOG_ERROR, "flowop NULL file");
- return (FILEBENCH_ERROR);
- }
-
-#ifdef HAVE_RAW_SUPPORT
- /* can't be used with raw devices */
- if (fileset->fs_attrs & FILESET_IS_RAW_DEV) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted a deletefile on RAW device",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-#endif /* HAVE_RAW_SUPPORT */
-
- if (file == NULL) {
- int err;
-
- /* pick arbitrary, existing (allocated) file */
- if ((err = flowoplib_pickfile(&file, flowop,
- FILESET_PICKEXISTS, 0)) != FILEBENCH_OK) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s failed to pick file", flowop->fo_name);
- return (err);
- }
- } else {
- /* delete specific file. wait for it to be non-busy */
- (void) ipc_mutex_lock(&fileset->fs_pick_lock);
- while (file->fse_flags & FSE_BUSY) {
- file->fse_flags |= FSE_THRD_WAITNG;
- (void) pthread_cond_wait(&fileset->fs_thrd_wait_cv,
- &fileset->fs_pick_lock);
- }
-
- /* File now available, grab it for deletion */
- file->fse_flags |= FSE_BUSY;
- fileset->fs_idle_files--;
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
- }
-
- /* don't delete if anyone (other than me) has file open */
- if ((fd > 0) && (threadflow->tf_fd[fd].fd_num > 0)) {
- if (file->fse_open_cnt > 1) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s can't delete file opened by other"
- " threads at fd = %d", flowop->fo_name, fd);
- fileset_unbusy(file, FALSE, FALSE, 0);
- return (FILEBENCH_OK);
- } else {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s deleting still open file at fd = %d",
- flowop->fo_name, fd);
- }
- } else if (file->fse_open_cnt > 0) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s can't delete file opened by other"
- " threads at fd = %d, open count = %d",
- flowop->fo_name, fd, file->fse_open_cnt);
- fileset_unbusy(file, FALSE, FALSE, 0);
- return (FILEBENCH_OK);
- }
-
- (void) fb_strlcpy(path, avd_get_str(fileset->fs_path), MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, avd_get_str(fileset->fs_name), MAXPATHLEN);
- pathtmp = fileset_resolvepath(file);
- (void) fb_strlcat(path, pathtmp, MAXPATHLEN);
- free(pathtmp);
-
- /* delete the selected file */
- flowop_beginop(threadflow, flowop);
- (void) FB_UNLINK(path);
- flowop_endop(threadflow, flowop, 0);
-
- /* indicate that it is no longer busy and no longer exists */
- fileset_unbusy(file, TRUE, FALSE, -file->fse_open_cnt);
-
- filebench_log(LOG_DEBUG_SCRIPT, "deleted file %s", file->fse_path);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulates fsync of a file. Obtains the file descriptor index
- * from the flowop, obtains the actual file descriptor from
- * the threadflow's table, checks to be sure it is still an
- * open file, then does an fsync operation on it. Returns FILEBENCH_ERROR
- * if the file no longer is open, FILEBENCH_OK otherwise.
- */
-static int
-flowoplib_fsync(threadflow_t *threadflow, flowop_t *flowop)
-{
- filesetentry_t *file;
- int fd = flowop->fo_fdnumber;
-
- if (threadflow->tf_fd[fd].fd_ptr == NULL) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted to fsync a closed fd %d",
- flowop->fo_name, fd);
- return (FILEBENCH_ERROR);
- }
-
- file = threadflow->tf_fse[fd];
-
- if ((file == NULL) ||
- (file->fse_fileset->fs_attrs & FILESET_IS_RAW_DEV)) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted to a fsync a RAW device",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- /* Measure time to fsync */
- flowop_beginop(threadflow, flowop);
- (void) FB_FSYNC(&threadflow->tf_fd[fd]);
- flowop_endop(threadflow, flowop, 0);
-
- filebench_log(LOG_DEBUG_SCRIPT, "fsync file %s", file->fse_path);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate fsync of an entire fileset. Search through the
- * threadflow's file descriptor array, doing fsync() on each
- * open file that belongs to the flowop's fileset. Always
- * returns FILEBENCH_OK.
- */
-static int
-flowoplib_fsyncset(threadflow_t *threadflow, flowop_t *flowop)
-{
- int fd;
-
- for (fd = 0; fd < THREADFLOW_MAXFD; fd++) {
- filesetentry_t *file;
-
- /* Match the file set to fsync */
- if ((threadflow->tf_fse[fd] == NULL) ||
- (flowop->fo_fileset != threadflow->tf_fse[fd]->fse_fileset))
- continue;
-
- /* Measure time to fsync */
- flowop_beginop(threadflow, flowop);
- (void) FB_FSYNC(&threadflow->tf_fd[fd]);
- flowop_endop(threadflow, flowop, 0);
-
- file = threadflow->tf_fse[fd];
-
- filebench_log(LOG_DEBUG_SCRIPT, "fsync file %s",
- file->fse_path);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate close of a file. Obtains the file descriptor index
- * from the flowop, obtains the actual file descriptor from the
- * threadflow's table, checks to be sure it is still an open
- * file, then does a close operation on it. Then sets the
- * threadflow file descriptor table entry to 0, and the file set
- * entry pointer to NULL. Returns FILEBENCH_ERROR if the file was not open,
- * FILEBENCH_OK otherwise.
- */
-static int
-flowoplib_closefile(threadflow_t *threadflow, flowop_t *flowop)
-{
- filesetentry_t *file;
- fileset_t *fileset;
- int fd = flowop->fo_fdnumber;
-
- if (threadflow->tf_fd[fd].fd_ptr == NULL) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted to close an already closed fd %d",
- flowop->fo_name, fd);
- return (FILEBENCH_ERROR);
- }
-
- file = threadflow->tf_fse[fd];
- fileset = file->fse_fileset;
-
- /* Wait for it to be non-busy */
- (void) ipc_mutex_lock(&fileset->fs_pick_lock);
- while (file->fse_flags & FSE_BUSY) {
- file->fse_flags |= FSE_THRD_WAITNG;
- (void) pthread_cond_wait(&fileset->fs_thrd_wait_cv,
- &fileset->fs_pick_lock);
- }
-
- /* File now available, grab it for closing */
- file->fse_flags |= FSE_BUSY;
-
- /* if last open, set declare idle */
- if (file->fse_open_cnt == 1)
- fileset->fs_idle_files--;
-
- (void) ipc_mutex_unlock(&fileset->fs_pick_lock);
-
- /* Measure time to close */
- flowop_beginop(threadflow, flowop);
- (void) FB_CLOSE(&threadflow->tf_fd[fd]);
- flowop_endop(threadflow, flowop, 0);
-
- fileset_unbusy(file, FALSE, FALSE, -1);
-
- threadflow->tf_fd[fd].fd_ptr = NULL;
-
- filebench_log(LOG_DEBUG_SCRIPT, "closed file %s", file->fse_path);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Obtain the full pathname of the directory described by the filesetentry
- * indicated by "dir", and copy it into the character array pointed to by
- * path. Returns FILEBENCH_ERROR on errors, FILEBENCH_OK otherwise.
- */
-static int
-flowoplib_getdirpath(filesetentry_t *dir, char *path)
-{
- char *fileset_path;
- char *fileset_name;
- char *part_path;
-
- if ((fileset_path = avd_get_str(dir->fse_fileset->fs_path)) == NULL) {
- filebench_log(LOG_ERROR, "Fileset path not set");
- return (FILEBENCH_ERROR);
- }
-
- if ((fileset_name = avd_get_str(dir->fse_fileset->fs_name)) == NULL) {
- filebench_log(LOG_ERROR, "Fileset name not set");
- return (FILEBENCH_ERROR);
- }
-
- (void) fb_strlcpy(path, fileset_path, MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, fileset_name, MAXPATHLEN);
-
- if ((part_path = fileset_resolvepath(dir)) == NULL)
- return (FILEBENCH_ERROR);
-
- (void) fb_strlcat(path, part_path, MAXPATHLEN);
- free(part_path);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Use mkdir to create a directory. Obtains the fileset name from the
- * flowop, selects a non-existent leaf directory and obtains its full
- * path, then uses mkdir to create it on the storage subsystem (make it
- * existent). Returns FILEBENCH_NORSC is there are no more non-existent
- * directories in the fileset, FILEBENCH_ERROR on other errors, and
- * FILEBENCH_OK on success.
- */
-static int
-flowoplib_makedir(threadflow_t *threadflow, flowop_t *flowop)
-{
- filesetentry_t *dir;
- int ret;
- char full_path[MAXPATHLEN];
-
- if ((ret = flowoplib_pickleafdir(&dir, flowop,
- FILESET_PICKNOEXIST)) != FILEBENCH_OK)
- return (ret);
-
- if ((ret = flowoplib_getdirpath(dir, full_path)) != FILEBENCH_OK)
- return (ret);
-
- flowop_beginop(threadflow, flowop);
- (void) FB_MKDIR(full_path, 0755);
- flowop_endop(threadflow, flowop, 0);
-
- /* indicate that it is no longer busy and now exists */
- fileset_unbusy(dir, TRUE, TRUE, 0);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Use rmdir to delete a directory. Obtains the fileset name from the
- * flowop, selects an existent leaf directory and obtains its full path,
- * then uses rmdir to remove it from the storage subsystem (make it
- * non-existent). Returns FILEBENCH_NORSC is there are no more existent
- * directories in the fileset, FILEBENCH_ERROR on other errors, and
- * FILEBENCH_OK on success.
- */
-static int
-flowoplib_removedir(threadflow_t *threadflow, flowop_t *flowop)
-{
- filesetentry_t *dir;
- int ret;
- char full_path[MAXPATHLEN];
-
- if ((ret = flowoplib_pickleafdir(&dir, flowop,
- FILESET_PICKEXISTS)) != FILEBENCH_OK)
- return (ret);
-
- if ((ret = flowoplib_getdirpath(dir, full_path)) != FILEBENCH_OK)
- return (ret);
-
- flowop_beginop(threadflow, flowop);
- (void) FB_RMDIR(full_path);
- flowop_endop(threadflow, flowop, 0);
-
- /* indicate that it is no longer busy and no longer exists */
- fileset_unbusy(dir, TRUE, FALSE, 0);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Use opendir(), multiple readdir() calls, and closedir() to list the
- * contents of a directory. Obtains the fileset name from the
- * flowop, selects a normal subdirectory (which always exist) and obtains
- * its full path, then uses opendir() to get a DIR handle to it from the
- * file system, a readdir() loop to access each directory entry, and
- * finally cleans up with a closedir(). The latency reported is the total
- * for all this activity, and it also reports the total number of bytes
- * in the entries as the amount "read". Returns FILEBENCH_ERROR on errors,
- * and FILEBENCH_OK on success.
- */
-static int
-flowoplib_listdir(threadflow_t *threadflow, flowop_t *flowop)
-{
- fileset_t *fileset;
- filesetentry_t *dir;
- DIR *dir_handle;
- struct dirent *direntp;
- int dir_bytes = 0;
- int ret;
- char full_path[MAXPATHLEN];
-
- if ((fileset = flowop->fo_fileset) == NULL) {
- filebench_log(LOG_ERROR, "flowop NO fileset");
- return (FILEBENCH_ERROR);
- }
-
- if ((dir = fileset_pick(fileset, FILESET_PICKDIR, 0, 0)) == NULL) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s failed to pick directory from fileset %s",
- flowop->fo_name,
- avd_get_str(fileset->fs_name));
- return (FILEBENCH_ERROR);
- }
-
- if ((ret = flowoplib_getdirpath(dir, full_path)) != FILEBENCH_OK)
- return (ret);
-
- flowop_beginop(threadflow, flowop);
-
- /* open the directory */
- if ((dir_handle = FB_OPENDIR(full_path)) == NULL) {
- filebench_log(LOG_ERROR,
- "flowop %s failed to open directory in fileset %s\n",
- flowop->fo_name, avd_get_str(fileset->fs_name));
- return (FILEBENCH_ERROR);
- }
-
- /* read through the directory entries */
- while ((direntp = FB_READDIR(dir_handle)) != NULL) {
- dir_bytes += (strlen(direntp->d_name) +
- sizeof (struct dirent) - 1);
- }
-
- /* close the directory */
- (void) FB_CLOSEDIR(dir_handle);
-
- flowop_endop(threadflow, flowop, dir_bytes);
-
- /* indicate that it is no longer busy */
- fileset_unbusy(dir, FALSE, FALSE, 0);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate stat of a file. Picks an arbitrary filesetentry with
- * an existing file from the flowop's fileset, then performs a
- * stat() operation on it. Returns FILEBENCH_ERROR if the flowop has no
- * associated fileset. Returns FILEBENCH_NORSC if an appropriate filesetentry
- * cannot be found, and FILEBENCH_OK on success.
- */
-static int
-flowoplib_statfile(threadflow_t *threadflow, flowop_t *flowop)
-{
- filesetentry_t *file;
- fileset_t *fileset;
- struct stat64 statbuf;
- int fd = flowop->fo_fdnumber;
-
- /* if fd specified and the file is open, use it to access file */
- if ((fd > 0) && (threadflow->tf_fd[fd].fd_num > 0)) {
-
- /* check whether file handle still valid */
- if ((file = threadflow->tf_fse[fd]) == NULL) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s trying to stat NULL file at fd = %d",
- flowop->fo_name, fd);
- return (FILEBENCH_ERROR);
- }
-
- /* if here, we still have a valid file pointer */
- fileset = file->fse_fileset;
- } else {
- /* Otherwise, pick arbitrary file */
- file = NULL;
- fileset = flowop->fo_fileset;
- }
-
- if (fileset == NULL) {
- filebench_log(LOG_ERROR,
- "statfile with no fileset specified");
- return (FILEBENCH_ERROR);
- }
-
-#ifdef HAVE_RAW_SUPPORT
- /* can't be used with raw devices */
- if (fileset->fs_attrs & FILESET_IS_RAW_DEV) {
- filebench_log(LOG_ERROR,
- "flowop %s attempted do a statfile on a RAW device",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-#endif /* HAVE_RAW_SUPPORT */
-
- if (file == NULL) {
- char path[MAXPATHLEN];
- char *pathtmp;
- int err;
-
- /* pick arbitrary, existing (allocated) file */
- if ((err = flowoplib_pickfile(&file, flowop,
- FILESET_PICKEXISTS, 0)) != FILEBENCH_OK) {
- filebench_log(LOG_DEBUG_SCRIPT,
- "Statfile flowop %s failed to pick file",
- flowop->fo_name);
- return (err);
- }
-
- /* resolve path and do a stat on file */
- (void) fb_strlcpy(path, avd_get_str(fileset->fs_path),
- MAXPATHLEN);
- (void) fb_strlcat(path, "/", MAXPATHLEN);
- (void) fb_strlcat(path, avd_get_str(fileset->fs_name),
- MAXPATHLEN);
- pathtmp = fileset_resolvepath(file);
- (void) fb_strlcat(path, pathtmp, MAXPATHLEN);
- free(pathtmp);
-
- /* stat the file */
- flowop_beginop(threadflow, flowop);
- if (FB_STAT(path, &statbuf) == -1)
- filebench_log(LOG_ERROR,
- "statfile flowop %s failed", flowop->fo_name);
- flowop_endop(threadflow, flowop, 0);
-
- fileset_unbusy(file, FALSE, FALSE, 0);
- } else {
- /* stat specific file */
- flowop_beginop(threadflow, flowop);
- if (FB_FSTAT(&threadflow->tf_fd[fd], &statbuf) == -1)
- filebench_log(LOG_ERROR,
- "statfile flowop %s failed", flowop->fo_name);
- flowop_endop(threadflow, flowop, 0);
-
- }
-
- return (FILEBENCH_OK);
-}
-
-
-/*
- * Additional reads and writes. Read and write whole files, write
- * and append to files. Some of these work with both fileobjs and
- * filesets, others only with filesets. The flowoplib_write routine
- * writes from thread memory, while the others read or write using
- * fo_buf memory. Note that both flowoplib_read() and
- * flowoplib_aiowrite() use thread memory as well.
- */
-
-
-/*
- * Emulate a read of a whole file. The file must be open with
- * file descriptor and filesetentry stored at the locations indexed
- * by the flowop's fdnumber. It then seeks to the beginning of the
- * associated file, and reads fs_iosize bytes at a time until the end
- * of the file. Returns FILEBENCH_ERROR on error, FILEBENCH_NORSC if
- * out of files, and FILEBENCH_OK on success.
- */
-static int
-flowoplib_readwholefile(threadflow_t *threadflow, flowop_t *flowop)
-{
- caddr_t iobuf;
- off64_t bytes = 0;
- fb_fdesc_t *fdesc;
- uint64_t wss;
- fbint_t iosize;
- int ret;
- char zerordbuf;
-
- /* get the file to use */
- if ((ret = flowoplib_filesetup(threadflow, flowop, &wss,
- &fdesc)) != FILEBENCH_OK)
- return (ret);
-
- /* an I/O size of zero means read entire working set with one I/O */
- if ((iosize = avd_get_int(flowop->fo_iosize)) == 0)
- iosize = wss;
-
- /*
- * The file may actually be 0 bytes long, in which case skip
- * the buffer set up call (which would fail) and substitute
- * a small buffer, which won't really be used.
- */
- if (iosize == 0) {
- iobuf = (caddr_t)&zerordbuf;
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s read zero length file", flowop->fo_name);
- } else {
- if (flowoplib_iobufsetup(threadflow, flowop, &iobuf,
- iosize) != 0)
- return (FILEBENCH_ERROR);
- }
-
- /* Measure time to read bytes */
- flowop_beginop(threadflow, flowop);
- (void) FB_LSEEK(fdesc, 0, SEEK_SET);
- while ((ret = FB_READ(fdesc, iobuf, iosize)) > 0)
- bytes += ret;
-
- flowop_endop(threadflow, flowop, bytes);
-
- if (ret < 0) {
- filebench_log(LOG_ERROR,
- "readwhole fail Failed to read whole file: %s",
- strerror(errno));
- return (FILEBENCH_ERROR);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate a write to a file of size fo_iosize. Will write
- * to a file from a fileset if the flowop's fo_fileset field
- * specifies one or its fdnumber is non zero. Otherwise it
- * will write to a fileobj file, if one exists. If the file
- * is not currently open, the routine will attempt to open
- * it. The flowop's fo_wss parameter will be used to set the
- * maximum file size if it is non-zero, otherwise the
- * filesetentry's fse_size will be used. A random memory
- * buffer offset is calculated, and, if fo_random is TRUE,
- * a random file offset is used for the write. Otherwise the
- * write is to the next sequential location. Returns
- * FILEBENCH_ERROR on errors, FILEBENCH_NORSC if iosetup can't
- * obtain a file, or FILEBENCH_OK on success.
- */
-static int
-flowoplib_write(threadflow_t *threadflow, flowop_t *flowop)
-{
- caddr_t iobuf;
- fbint_t wss;
- fbint_t iosize;
- fb_fdesc_t *fdesc;
- int ret;
-
- iosize = avd_get_int(flowop->fo_iosize);
- if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf,
- &fdesc, iosize)) != FILEBENCH_OK)
- return (ret);
-
- if (avd_get_bool(flowop->fo_random)) {
- uint64_t fileoffset;
-
- if (filebench_randomno64(&fileoffset,
- wss, iosize, NULL) == -1) {
- filebench_log(LOG_ERROR,
- "file size smaller than IO size for thread %s",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
- flowop_beginop(threadflow, flowop);
- if (FB_PWRITE(fdesc, iobuf,
- iosize, (off64_t)fileoffset) == -1) {
- filebench_log(LOG_ERROR, "write failed, "
- "offset %llu io buffer %zd: %s",
- (u_longlong_t)fileoffset, iobuf, strerror(errno));
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
- flowop_endop(threadflow, flowop, iosize);
- } else {
- flowop_beginop(threadflow, flowop);
- if (FB_WRITE(fdesc, iobuf, iosize) == -1) {
- filebench_log(LOG_ERROR,
- "write failed, io buffer %zd: %s",
- iobuf, strerror(errno));
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
- flowop_endop(threadflow, flowop, iosize);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate a write of a whole file. The size of the file
- * is taken from a filesetentry identified by fo_srcfdnumber or
- * from the working set size, while the file descriptor used is
- * identified by fo_fdnumber. Does multiple writes of fo_iosize
- * length length until full file has been written. Returns FILEBENCH_ERROR on
- * error, FILEBENCH_NORSC if out of files, FILEBENCH_OK on success.
- */
-static int
-flowoplib_writewholefile(threadflow_t *threadflow, flowop_t *flowop)
-{
- caddr_t iobuf;
- filesetentry_t *file;
- int wsize;
- off64_t seek;
- off64_t bytes = 0;
- uint64_t wss;
- fbint_t iosize;
- fb_fdesc_t *fdesc;
- int srcfd = flowop->fo_srcfdnumber;
- int ret;
- char zerowrtbuf;
-
- /* get the file to use */
- if ((ret = flowoplib_filesetup(threadflow, flowop, &wss,
- &fdesc)) != FILEBENCH_OK)
- return (ret);
-
- /* an I/O size of zero means write entire working set with one I/O */
- if ((iosize = avd_get_int(flowop->fo_iosize)) == 0)
- iosize = wss;
-
- /*
- * The file may actually be 0 bytes long, in which case skip
- * the buffer set up call (which would fail) and substitute
- * a small buffer, which won't really be used.
- */
- if (iosize == 0) {
- iobuf = (caddr_t)&zerowrtbuf;
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %s wrote zero length file", flowop->fo_name);
- } else {
- if (flowoplib_iobufsetup(threadflow, flowop, &iobuf,
- iosize) != 0)
- return (FILEBENCH_ERROR);
- }
-
- file = threadflow->tf_fse[srcfd];
- if ((srcfd != 0) && (file == NULL)) {
- filebench_log(LOG_ERROR, "flowop %s: NULL src file",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- if (file)
- wss = file->fse_size;
-
- wsize = (int)MIN(wss, iosize);
-
- /* Measure time to write bytes */
- flowop_beginop(threadflow, flowop);
- for (seek = 0; seek < wss; seek += wsize) {
- ret = FB_WRITE(fdesc, iobuf, wsize);
- if (ret != wsize) {
- filebench_log(LOG_ERROR,
- "Failed to write %d bytes on fd %d: %s",
- wsize, fdesc->fd_num, strerror(errno));
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
- wsize = (int)MIN(wss - seek, iosize);
- bytes += ret;
- }
- flowop_endop(threadflow, flowop, bytes);
-
- return (FILEBENCH_OK);
-}
-
-
-/*
- * Emulate a fixed size append to a file. Will append data to
- * a file chosen from a fileset if the flowop's fo_fileset
- * field specifies one or if its fdnumber is non zero.
- * Otherwise it will write to a fileobj file, if one exists.
- * The flowop's fo_wss parameter will be used to set the
- * maximum file size if it is non-zero, otherwise the
- * filesetentry's fse_size will be used. A random memory
- * buffer offset is calculated, then a logical seek to the
- * end of file is done followed by a write of fo_iosize
- * bytes. Writes are actually done from fo_buf, rather than
- * tf_mem as is done with flowoplib_write(), and no check
- * is made to see if fo_iosize exceeds the size of fo_buf.
- * Returns FILEBENCH_ERROR on error, FILEBENCH_NORSC if out of
- * files in the fileset, FILEBENCH_OK on success.
- */
-static int
-flowoplib_appendfile(threadflow_t *threadflow, flowop_t *flowop)
-{
- caddr_t iobuf;
- fb_fdesc_t *fdesc;
- fbint_t wss;
- fbint_t iosize;
- int ret;
-
- iosize = avd_get_int(flowop->fo_iosize);
- if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf,
- &fdesc, iosize)) != FILEBENCH_OK)
- return (ret);
-
- /* XXX wss is not being used */
-
- /* Measure time to write bytes */
- flowop_beginop(threadflow, flowop);
- (void) FB_LSEEK(fdesc, 0, SEEK_END);
- ret = FB_WRITE(fdesc, iobuf, iosize);
- if (ret != iosize) {
- filebench_log(LOG_ERROR,
- "Failed to write %llu bytes on fd %d: %s",
- (u_longlong_t)iosize, fdesc->fd_num, strerror(errno));
- flowop_endop(threadflow, flowop, ret);
- return (FILEBENCH_ERROR);
- }
- flowop_endop(threadflow, flowop, ret);
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Emulate a random size append to a file. Will append data
- * to a file chosen from a fileset if the flowop's fo_fileset
- * field specifies one or if its fdnumber is non zero. Otherwise
- * it will write to a fileobj file, if one exists. The flowop's
- * fo_wss parameter will be used to set the maximum file size
- * if it is non-zero, otherwise the filesetentry's fse_size
- * will be used. A random transfer size (but at most fo_iosize
- * bytes) and a random memory offset are calculated. A logical
- * seek to the end of file is done, then writes of up to
- * FILE_ALLOC_BLOCK in size are done until the full transfer
- * size has been written. Writes are actually done from fo_buf,
- * rather than tf_mem as is done with flowoplib_write().
- * Returns FILEBENCH_ERROR on error, FILEBENCH_NORSC if out of
- * files in the fileset, FILEBENCH_OK on success.
- */
-static int
-flowoplib_appendfilerand(threadflow_t *threadflow, flowop_t *flowop)
-{
- caddr_t iobuf;
- uint64_t appendsize;
- fb_fdesc_t *fdesc;
- fbint_t wss;
- fbint_t iosize;
- int ret = 0;
-
- if ((iosize = avd_get_int(flowop->fo_iosize)) == 0) {
- filebench_log(LOG_ERROR, "zero iosize for flowop %s",
- flowop->fo_name);
- return (FILEBENCH_ERROR);
- }
-
- if (filebench_randomno64(&appendsize, iosize, 1LL, NULL) != 0)
- return (FILEBENCH_ERROR);
-
- /* skip if attempting zero length append */
- if (appendsize == 0) {
- flowop_beginop(threadflow, flowop);
- flowop_endop(threadflow, flowop, 0LL);
- return (FILEBENCH_OK);
- }
-
- if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf,
- &fdesc, appendsize)) != FILEBENCH_OK)
- return (ret);
-
- /* XXX wss is not being used */
-
- /* Measure time to write bytes */
- flowop_beginop(threadflow, flowop);
-
- (void) FB_LSEEK(fdesc, 0, SEEK_END);
- ret = FB_WRITE(fdesc, iobuf, appendsize);
- if (ret != appendsize) {
- filebench_log(LOG_ERROR,
- "Failed to write %llu bytes on fd %d: %s",
- (u_longlong_t)appendsize, fdesc->fd_num, strerror(errno));
- flowop_endop(threadflow, flowop, 0);
- return (FILEBENCH_ERROR);
- }
-
- flowop_endop(threadflow, flowop, appendsize);
-
- return (FILEBENCH_OK);
-}
-
-typedef struct testrandvar_priv {
- uint64_t sample_count;
- double val_sum;
- double sqr_sum;
-} testrandvar_priv_t;
-
-/*
- * flowop to calculate various statistics from the number stream
- * produced by a random variable. This allows verification that the
- * random distribution used to define the random variable is producing
- * the expected distribution of random numbers.
- */
-/* ARGSUSED */
-static int
-flowoplib_testrandvar(threadflow_t *threadflow, flowop_t *flowop)
-{
- testrandvar_priv_t *mystats;
- double value;
-
- if ((mystats = (testrandvar_priv_t *)flowop->fo_private) == NULL) {
- filebench_log(LOG_ERROR, "testrandvar not initialized\n");
- filebench_shutdown(1);
- return (-1);
- }
-
- value = avd_get_dbl(flowop->fo_value);
-
- mystats->sample_count++;
- mystats->val_sum += value;
- mystats->sqr_sum += (value * value);
-
- return (0);
-}
-
-/*
- * Initialize the private data area used to accumulate the statistics
- */
-static int
-flowoplib_testrandvar_init(flowop_t *flowop)
-{
- testrandvar_priv_t *mystats;
-
- if ((mystats = (testrandvar_priv_t *)
- malloc(sizeof (testrandvar_priv_t))) == NULL) {
- filebench_log(LOG_ERROR, "could not initialize testrandvar");
- filebench_shutdown(1);
- return (-1);
- }
-
- mystats->sample_count = 0;
- mystats->val_sum = 0;
- mystats->sqr_sum = 0;
- flowop->fo_private = (void *)mystats;
-
- (void) ipc_mutex_unlock(&flowop->fo_lock);
- return (0);
-}
-
-/*
- * Print out the accumulated statistics, and free the private storage
- */
-static void
-flowoplib_testrandvar_destruct(flowop_t *flowop)
-{
- testrandvar_priv_t *mystats;
- double mean, std_dev, dbl_count;
-
- (void) ipc_mutex_lock(&flowop->fo_lock);
- if ((mystats = (testrandvar_priv_t *)
- flowop->fo_private) == NULL) {
- (void) ipc_mutex_unlock(&flowop->fo_lock);
- return;
- }
-
- flowop->fo_private = NULL;
- (void) ipc_mutex_unlock(&flowop->fo_lock);
-
- dbl_count = (double)mystats->sample_count;
- mean = mystats->val_sum / dbl_count;
- std_dev = sqrt((mystats->sqr_sum / dbl_count) - (mean * mean)) / mean;
-
- filebench_log(LOG_VERBOSE,
- "testrandvar: ops = %llu, mean = %8.2lf, stddev = %8.2lf",
- (u_longlong_t)mystats->sample_count, mean, std_dev);
- free(mystats);
-}
-
-/*
- * prints message to the console from within a thread
- */
-static int
-flowoplib_print(threadflow_t *threadflow, flowop_t *flowop)
-{
- procflow_t *procflow;
-
- procflow = threadflow->tf_process;
- filebench_log(LOG_INFO,
- "Message from process (%s,%d), thread (%s,%d): %s",
- procflow->pf_name, procflow->pf_instance,
- threadflow->tf_name, threadflow->tf_instance,
- avd_get_str(flowop->fo_value));
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Prints usage information for flowop operations.
- */
-void
-flowoplib_usage()
-{
- (void) fprintf(stderr,
- "flowop [openfile|createfile] name=<name>,fileset=<fname>\n");
- (void) fprintf(stderr,
- " [,fd=<file desc num>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr,
- "flowop closefile name=<name>,fd=<file desc num>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop deletefile name=<name>\n");
- (void) fprintf(stderr, " [,fileset=<fname>]\n");
- (void) fprintf(stderr,
- " [,fd=<file desc num>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop statfile name=<name>\n");
- (void) fprintf(stderr, " [,fileset=<fname>]\n");
- (void) fprintf(stderr,
- " [,fd=<file desc num>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr,
- "flowop fsync name=<name>,fd=<file desc num>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr,
- "flowop fsyncset name=<name>,fileset=<fname>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop [write|read|aiowrite] name=<name>, \n");
- (void) fprintf(stderr,
- " filename|fileset=<fname>,\n");
- (void) fprintf(stderr, " iosize=<size>\n");
- (void) fprintf(stderr, " [,directio]\n");
- (void) fprintf(stderr, " [,dsync]\n");
- (void) fprintf(stderr, " [,iters=<count>]\n");
- (void) fprintf(stderr, " [,random]\n");
- (void) fprintf(stderr, " [,opennext]\n");
- (void) fprintf(stderr, " [,workingset=<size>]\n");
- (void) fprintf(stderr,
- "flowop [appendfile|appendfilerand] name=<name>, \n");
- (void) fprintf(stderr,
- " filename|fileset=<fname>,\n");
- (void) fprintf(stderr, " iosize=<size>\n");
- (void) fprintf(stderr, " [,dsync]\n");
- (void) fprintf(stderr, " [,iters=<count>]\n");
- (void) fprintf(stderr, " [,workingset=<size>]\n");
- (void) fprintf(stderr,
- "flowop [readwholefile|writewholefile] name=<name>, \n");
- (void) fprintf(stderr,
- " filename|fileset=<fname>,\n");
- (void) fprintf(stderr, " iosize=<size>\n");
- (void) fprintf(stderr, " [,dsync]\n");
- (void) fprintf(stderr, " [,iters=<count>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop aiowait name=<name>,target="
- "<aiowrite-flowop>\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop sempost name=<name>,"
- "target=<semblock-flowop>,\n");
- (void) fprintf(stderr,
- " value=<increment-to-post>\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop semblock name=<name>,value="
- "<decrement-to-receive>,\n");
- (void) fprintf(stderr, " highwater="
- "<inbound-queue-max>\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop block name=<name>\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr,
- "flowop wakeup name=<name>,target=<block-flowop>,\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr,
- "flowop hog name=<name>,value=<number-of-mem-ops>\n");
- (void) fprintf(stderr,
- "flowop delay name=<name>,value=<number-of-seconds>\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "flowop eventlimit name=<name>\n");
- (void) fprintf(stderr, "flowop bwlimit name=<name>,value=<mb/s>\n");
- (void) fprintf(stderr, "flowop iopslimit name=<name>,value=<iop/s>\n");
- (void) fprintf(stderr,
- "flowop finishoncount name=<name>,value=<ops/s>\n");
- (void) fprintf(stderr,
- "flowop finishonbytes name=<name>,value=<bytes>\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "\n");
-}
diff --git a/usr/src/cmd/filebench/common/fsplug.h b/usr/src/cmd/filebench/common/fsplug.h
deleted file mode 100644
index 61f3e1ddfa..0000000000
--- a/usr/src/cmd/filebench/common/fsplug.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- */
-
-
-#ifndef _FSPLUG_H
-#define _FSPLUG_H
-
-#include <dirent.h>
-#include "config.h"
-#include <sys/stat.h>
-
-/*
- * Type of file system client plug-in desired.
- */
-typedef enum fb_plugin_type {
- LOCAL_FS_PLUG = 0,
- NFS3_PLUG,
- NFS4_PLUG,
- CIFS_PLUG
-} fb_plugin_type_t;
-
-/* universal file descriptor for both local and nfs file systems */
-typedef union fb_fdesc {
- int fd_num; /* OS file descriptor number */
- void *fd_ptr; /* Pointer to nfs information block */
-} fb_fdesc_t;
-
-typedef struct aiolist aiol_t;
-
-/* Functions vector for file system plug-ins */
-typedef struct fsplug_func_s {
- char fs_name[16];
- int (*fsp_freemem)(fb_fdesc_t *, off64_t);
- int (*fsp_open)(fb_fdesc_t *, char *, int, int);
- int (*fsp_pread)(fb_fdesc_t *, caddr_t, fbint_t, off64_t);
- int (*fsp_read)(fb_fdesc_t *, caddr_t, fbint_t);
- int (*fsp_pwrite)(fb_fdesc_t *, caddr_t, fbint_t, off64_t);
- int (*fsp_write)(fb_fdesc_t *, caddr_t, fbint_t);
- int (*fsp_lseek)(fb_fdesc_t *, off64_t, int);
- int (*fsp_ftrunc)(fb_fdesc_t *, off64_t);
- int (*fsp_rename)(const char *, const char *);
- int (*fsp_close)(fb_fdesc_t *);
- int (*fsp_link)(const char *, const char *);
- int (*fsp_symlink)(const char *, const char *);
- int (*fsp_unlink)(char *);
- ssize_t (*fsp_readlink)(const char *, char *, size_t);
- int (*fsp_mkdir)(char *, int);
- int (*fsp_rmdir)(char *);
- DIR *(*fsp_opendir)(char *);
- struct dirent *(*fsp_readdir)(DIR *);
- int (*fsp_closedir)(DIR *);
- int (*fsp_fsync)(fb_fdesc_t *);
- int (*fsp_stat)(char *, struct stat64 *);
- int (*fsp_fstat)(fb_fdesc_t *, struct stat64 *);
- int (*fsp_access)(const char *, int);
- void (*fsp_recur_rm)(char *);
-} fsplug_func_t;
-
-extern fsplug_func_t *fs_functions_vec;
-
-/* Macros for calling functions */
-#define FB_FREEMEM(fd, sz) \
- (*fs_functions_vec->fsp_freemem)(fd, sz)
-
-#define FB_OPEN(fd, path, flags, perms) \
- (*fs_functions_vec->fsp_open)(fd, path, flags, perms)
-
-#define FB_PREAD(fdesc, iobuf, iosize, offset) \
- (*fs_functions_vec->fsp_pread)(fdesc, iobuf, iosize, offset)
-
-#define FB_READ(fdesc, iobuf, iosize) \
- (*fs_functions_vec->fsp_read)(fdesc, iobuf, iosize)
-
-#define FB_PWRITE(fdesc, iobuf, iosize, offset) \
- (*fs_functions_vec->fsp_pwrite)(fdesc, iobuf, iosize, offset)
-
-#define FB_WRITE(fdesc, iobuf, iosize) \
- (*fs_functions_vec->fsp_write)(fdesc, iobuf, iosize)
-
-#define FB_LSEEK(fdesc, amnt, whence) \
- (*fs_functions_vec->fsp_lseek)(fdesc, amnt, whence)
-
-#define FB_CLOSE(fdesc) \
- (*fs_functions_vec->fsp_close)(fdesc)
-
-#define FB_UNLINK(path) \
- (*fs_functions_vec->fsp_unlink)(path)
-
-#define FB_MKDIR(path, perm) \
- (*fs_functions_vec->fsp_mkdir)(path, perm)
-
-#define FB_RMDIR(path) \
- (*fs_functions_vec->fsp_rmdir)(path)
-
-#define FB_OPENDIR(path) \
- (*fs_functions_vec->fsp_opendir)(path)
-
-#define FB_READDIR(dir) \
- (*fs_functions_vec->fsp_readdir)(dir)
-
-#define FB_CLOSEDIR(dir) \
- (*fs_functions_vec->fsp_closedir)(dir)
-
-#define FB_FSYNC(fdesc) \
- (*fs_functions_vec->fsp_fsync)(fdesc)
-
-#define FB_RECUR_RM(path) \
- (*fs_functions_vec->fsp_recur_rm)(path)
-
-#define FB_STAT(path, statp) \
- (*fs_functions_vec->fsp_stat)(path, statp)
-
-#define FB_FSTAT(fdesc, statp) \
- (*fs_functions_vec->fsp_fstat)(fdesc, statp)
-
-#define FB_FTRUNC(fdesc, size) \
- (*fs_functions_vec->fsp_ftrunc)(fdesc, size)
-
-#define FB_LINK(existing, new) \
- (*fs_functions_vec->fsp_link)(existing, new)
-
-#define FB_SYMLINK(name1, name2) \
- (*fs_functions_vec->fsp_symlink)(name1, name2)
-
-#endif /* _FSPLUG_H */
diff --git a/usr/src/cmd/filebench/common/gamma_dist.c b/usr/src/cmd/filebench/common/gamma_dist.c
deleted file mode 100644
index 3ba0a74e8d..0000000000
--- a/usr/src/cmd/filebench/common/gamma_dist.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdlib.h>
-#include <math.h>
-
-/*
- * This is valid for 0 < a <= 1
- *
- * From Knuth Volume 2, 3rd edition, pages 586 - 587.
- */
-static double
-gamma_dist_knuth_algG(double a, double (*src)(unsigned short *),
- unsigned short *xi)
-{
- double p, U, V, X, q;
-
- p = M_E/(a + M_E);
-G2:
- /* get a random number U */
- U = (*src)(xi);
-
- do {
- /* get a random number V */
- V = (*src)(xi);
-
- } while (V == 0);
-
- if (U < p) {
- X = pow(V, 1/a);
- /* q = e^(-X) */
- q = exp(-X);
- } else {
- X = 1 - log(V);
- q = pow(X, a-1);
- }
-
- /*
- * X now has density g, and q = f(X)/cg(X)
- */
-
- /* get a random number U */
- U = (*src)(xi);
-
- if (U >= q)
- goto G2;
- return (X);
-}
-
-/*
- * This is valid for a > 1
- *
- * From Knuth Volume 2, 3rd edition, page 134.
- */
-static double
-gamma_dist_knuth_algA(double a, double (*src)(unsigned short *),
- unsigned short *xi)
-{
- double U, Y, X, V;
-
-A1:
- /* get a random number U */
- U = (*src)(xi);
-
- Y = tan(M_PI*U);
- X = (sqrt((2*a) - 1) * Y) + a - 1;
-
- if (X <= 0)
- goto A1;
-
- /* get a random number V */
- V = (*src)(xi);
-
- if (V > ((1 + (Y*Y)) * exp((a-1) * log(X/(a-1)) - sqrt(2*a -1) * Y)))
- goto A1;
-
- return (X);
-}
-
-/*
- * fetch a uniformly distributed random number using the drand48 generator
- */
-/* ARGSUSED */
-static double
-default_src(unsigned short *xi)
-{
- return (drand48());
-}
-
-/*
- * Sample the gamma distributed random variable with gamma 'a' and
- * result mulitplier 'b', which is usually mean/gamma. Uses the default
- * drand48 random number generator as input
- */
-double
-gamma_dist_knuth(double a, double b)
-{
- if (a <= 1.0)
- return (b * gamma_dist_knuth_algG(a, default_src, NULL));
- else
- return (b * gamma_dist_knuth_algA(a, default_src, NULL));
-}
-
-/*
- * Sample the gamma distributed random variable with gamma 'a' and
- * multiplier 'b', which is mean / gamma adjusted for the specified
- * minimum value. The suppled random number source function is
- * used to optain the uniformly distributed random numbers.
- */
-double
-gamma_dist_knuth_src(double a, double b,
- double (*src)(unsigned short *), unsigned short *xi)
-{
- if (a <= 1.0)
- return (b * gamma_dist_knuth_algG(a, src, xi));
- else
- return (b * gamma_dist_knuth_algA(a, src, xi));
-}
diff --git a/usr/src/cmd/filebench/common/gamma_dist.h b/usr/src/cmd/filebench/common/gamma_dist.h
deleted file mode 100644
index ff9375fe75..0000000000
--- a/usr/src/cmd/filebench/common/gamma_dist.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_GAMMA_DIST_H
-#define _FB_GAMMA_DIST_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-double gamma_dist_knuth(double a, double b);
-double gamma_dist_knuth_src(double a, double b,
- double (*src)(unsigned short *), unsigned short *xi);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_GAMMA_DIST_H */
diff --git a/usr/src/cmd/filebench/common/ipc.c b/usr/src/cmd/filebench/common/ipc.c
deleted file mode 100644
index f0bf6fd14e..0000000000
--- a/usr/src/cmd/filebench/common/ipc.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/errno.h>
-#include <signal.h>
-#include <pthread.h>
-#include <sys/shm.h>
-#include "filebench.h"
-
-/* IPC Hub and Simple memory allocator */
-
-static int shmfd;
-filebench_shm_t *filebench_shm = NULL;
-
-/*
- * Interprocess Communication mechanisms. If multiple processes
- * are used, filebench opens a shared file in memory mapped mode to hold
- * a variety of global variables and data structures. If only using
- * multiple threads, it just allocates a region of local memory. A
- * region of interprocess shared memory and a set of shared semaphores
- * are also created. Routines are provided to manage the creation,
- * destruction, and allocation of these resoures.
- */
-
-
-/*
- * Locks a mutex and logs any errors.
- */
-int
-ipc_mutex_lock(pthread_mutex_t *mutex)
-{
- int error;
-
- error = pthread_mutex_lock(mutex);
-
-#ifdef HAVE_ROBUST_MUTEX
- if (error == EOWNERDEAD) {
- if (pthread_mutex_consistent_np(mutex) != 0) {
- filebench_log(LOG_FATAL, "mutex make consistent "
- "failed: %s", strerror(error));
- return (-1);
- }
- return (0);
- }
-#endif /* HAVE_ROBUST_MUTEX */
-
- if (error != 0) {
- filebench_log(LOG_FATAL, "mutex lock failed: %s",
- strerror(error));
- }
-
- return (error);
-}
-
-/*
- * Unlocks a mutex and logs any errors.
- */
-int
-ipc_mutex_unlock(pthread_mutex_t *mutex)
-{
- int error;
-
- error = pthread_mutex_unlock(mutex);
-
-#ifdef HAVE_ROBUST_MUTEX
- if (error == EOWNERDEAD) {
- if (pthread_mutex_consistent_np(mutex) != 0) {
- filebench_log(LOG_FATAL, "mutex make consistent "
- "failed: %s", strerror(error));
- return (-1);
- }
- return (0);
- }
-#endif /* HAVE_ROBUST_MUTEX */
-
- if (error != 0) {
- filebench_log(LOG_FATAL, "mutex unlock failed: %s",
- strerror(error));
- }
-
- return (error);
-}
-
-/*
- * Initialize mutex attributes for the various flavors of mutexes
- */
-static void
-ipc_mutexattr_init(int mtx_type)
-{
- pthread_mutexattr_t *mtx_attrp;
-
- mtx_attrp = &(filebench_shm->shm_mutexattr[mtx_type]);
-
- (void) pthread_mutexattr_init(mtx_attrp);
-
-#ifdef USE_PROCESS_MODEL
-#ifdef HAVE_PROCSCOPE_PTHREADS
- if (pthread_mutexattr_setpshared(mtx_attrp,
- PTHREAD_PROCESS_SHARED) != 0) {
- filebench_log(LOG_ERROR, "cannot set mutex attr "
- "PROCESS_SHARED on this platform");
- filebench_shutdown(1);
- }
-#ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
- if (mtx_type & IPC_MUTEX_PRIORITY) {
- if (pthread_mutexattr_setprotocol(mtx_attrp,
- PTHREAD_PRIO_INHERIT) != 0) {
- filebench_log(LOG_ERROR,
- "cannot set mutex attr "
- "PTHREAD_PRIO_INHERIT on this platform");
- filebench_shutdown(1);
- }
- }
-#endif /* HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL */
-#endif /* HAVE_PROCSCOPE_PTHREADS */
-#ifdef HAVE_ROBUST_MUTEX
- if (mtx_type & IPC_MUTEX_ROBUST) {
- if (pthread_mutexattr_setrobust_np(mtx_attrp,
- PTHREAD_MUTEX_ROBUST_NP) != 0) {
- filebench_log(LOG_ERROR,
- "cannot set mutex attr "
- "PTHREAD_MUTEX_ROBUST_NP on this platform");
- filebench_shutdown(1);
- }
- if (pthread_mutexattr_settype(mtx_attrp,
- PTHREAD_MUTEX_ERRORCHECK) != 0) {
- filebench_log(LOG_ERROR,
- "cannot set mutex attr "
- "PTHREAD_MUTEX_ERRORCHECK "
- "on this platform");
- filebench_shutdown(1);
- }
- }
-#endif /* HAVE_ROBUST_MUTEX */
-#endif /* USE_PROCESS_MODEL */
-}
-
-/*
- * On first invocation, allocates a mutex attributes structure
- * and initializes it with appropriate attributes. In all cases,
- * returns a pointer to the structure.
- */
-pthread_mutexattr_t *
-ipc_mutexattr(int mtx_type)
-{
- if ((mtx_type >= IPC_NUM_MUTEX_ATTRS) ||
- (mtx_type < IPC_MUTEX_NORMAL)) {
- filebench_log(LOG_ERROR,
- "ipc_mutexattr called with undefined attr selector %d",
- mtx_type);
- return (&(filebench_shm->shm_mutexattr[IPC_MUTEX_NORMAL]));
- }
-
- return (&(filebench_shm->shm_mutexattr[mtx_type]));
-}
-
-static pthread_condattr_t *condattr = NULL;
-
-/*
- * On first invocation, allocates a condition variable attributes
- * structure and initializes it with appropriate attributes. In
- * all cases, returns a pointer to the structure.
- */
-pthread_condattr_t *
-ipc_condattr(void)
-{
-#ifdef USE_PROCESS_MODEL
- if (condattr == NULL) {
- if ((condattr = malloc(sizeof (pthread_condattr_t))) == NULL) {
- filebench_log(LOG_ERROR, "cannot alloc cond attr");
- filebench_shutdown(1);
- }
-#ifdef HAVE_PROCSCOPE_PTHREADS
- (void) pthread_condattr_init(condattr);
- if (pthread_condattr_setpshared(condattr,
- PTHREAD_PROCESS_SHARED) != 0) {
- filebench_log(LOG_ERROR,
- "cannot set cond attr PROCESS_SHARED");
- filebench_shutdown(1);
- }
-#endif /* HAVE_PROCSCOPE_PTHREADS */
- }
-#endif /* USE_PROCESS_MODEL */
- return (condattr);
-}
-
-static pthread_rwlockattr_t *rwlockattr = NULL;
-
-/*
- * On first invocation, allocates a readers/writers attributes
- * structure and initializes it with appropriate attributes.
- * In all cases, returns a pointer to the structure.
- */
-static pthread_rwlockattr_t *
-ipc_rwlockattr(void)
-{
-#ifdef USE_PROCESS_MODEL
- if (rwlockattr == NULL) {
- if ((rwlockattr =
- malloc(sizeof (pthread_rwlockattr_t))) == NULL) {
- filebench_log(LOG_ERROR, "cannot alloc rwlock attr");
- filebench_shutdown(1);
- }
-#ifdef HAVE_PROCSCOPE_PTHREADS
- (void) pthread_rwlockattr_init(rwlockattr);
- if (pthread_rwlockattr_setpshared(rwlockattr,
- PTHREAD_PROCESS_SHARED) != 0) {
- filebench_log(LOG_ERROR,
- "cannot set rwlock attr PROCESS_SHARED");
- filebench_shutdown(1);
- }
-#endif /* HAVE_PROCSCOPE_PTHREADS */
- }
-#endif /* USE_PROCESS_MODEL */
- return (rwlockattr);
-}
-
-char *shmpath = NULL;
-
-/*
- * Calls semget() to get a set of shared system V semaphores.
- */
-void
-ipc_seminit(void)
-{
- key_t key = filebench_shm->shm_semkey;
- int sys_semid;
-
- /* Already done? */
- if (filebench_shm->shm_sys_semid >= 0)
- return;
-
- if ((sys_semid = semget(key, FILEBENCH_NSEMS, IPC_CREAT |
- S_IRUSR | S_IWUSR)) == -1) {
- filebench_log(LOG_ERROR,
- "could not create sysv semaphore set "
- "(need to increase sems?): %s",
- strerror(errno));
- filebench_shutdown(1);
- }
-
- filebench_shm->shm_sys_semid = sys_semid;
-}
-
-/*
- * Initialize the Interprocess Communication system and its
- * associated shared memory structure. It first creates a
- * temporary file using either the mkstemp() function or the
- * tempnam() and open() functions. If the process model is in
- * use,it than sets the file large enough to hold the
- * filebench_shm and an additional Megabyte. The file is then
- * memory mapped. If the process model is not in use, it simply
- * mallocs a region of sizeof (filebench_shm_t).
- *
- * Once the shared memory region / file is created, ipc_init
- * initializes various locks pointers, and variables in the
- * shared memory. It also uses ftok() to get a shared memory
- * semaphore key for later use in allocating shared semaphores.
- */
-void
-ipc_init(void)
-{
- filebench_shm_t *buf = malloc(MB);
- key_t key;
- caddr_t c1;
- caddr_t c2;
-#ifdef HAVE_SEM_RMID
- int sys_semid;
-#endif
-
-#ifdef HAVE_MKSTEMP
- shmpath = (char *)malloc(128);
- (void) strcpy(shmpath, "/var/tmp/fbenchXXXXXX");
- shmfd = mkstemp(shmpath);
-#else
- shmfd = open(shmpath, O_CREAT | O_RDWR | O_TRUNC, 0666);
- shmpath = tempnam("/var/tmp", "fbench");
-#endif /* HAVE_MKSTEMP */
-
-#ifdef USE_PROCESS_MODEL
-
- if (shmfd < 0) {
- filebench_log(LOG_FATAL, "Cannot open shm %s: %s",
- shmpath,
- strerror(errno));
- exit(1);
- }
-
- (void) lseek(shmfd, sizeof (filebench_shm_t), SEEK_SET);
- if (write(shmfd, buf, MB) != MB) {
- filebench_log(LOG_FATAL,
- "Cannot allocate shm: %s", strerror(errno));
- exit(1);
- }
-
- /* LINTED E_BAD_PTR_CAST_ALIGN */
- if ((filebench_shm = (filebench_shm_t *)mmap((caddr_t)0,
- sizeof (filebench_shm_t), PROT_READ | PROT_WRITE,
- MAP_SHARED, shmfd, 0)) == NULL) {
- filebench_log(LOG_FATAL, "Cannot mmap shm");
- exit(1);
- }
-
-#else
- if ((filebench_shm =
- (filebench_shm_t *)malloc(sizeof (filebench_shm_t))) == NULL) {
- filebench_log(LOG_FATAL, "Cannot malloc shm");
- exit(1);
- }
-#endif /* USE_PROCESS_MODEL */
-
- c1 = (caddr_t)filebench_shm;
- c2 = (caddr_t)&filebench_shm->shm_marker;
-
- (void) memset(filebench_shm, 0, c2 - c1);
- filebench_shm->shm_epoch = gethrtime();
- filebench_shm->shm_debug_level = LOG_VERBOSE;
- filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT;
- filebench_shm->shm_string_ptr = &filebench_shm->shm_strings[0];
- filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr;
- filebench_shm->shm_path_ptr = &filebench_shm->shm_filesetpaths[0];
-
- /* Setup mutexes for object lists */
- ipc_mutexattr_init(IPC_MUTEX_NORMAL);
- ipc_mutexattr_init(IPC_MUTEX_PRIORITY);
- ipc_mutexattr_init(IPC_MUTEX_ROBUST);
- ipc_mutexattr_init(IPC_MUTEX_PRI_ROB);
- (void) pthread_mutex_init(&filebench_shm->shm_fileset_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&filebench_shm->shm_procflow_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&filebench_shm->shm_procs_running_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&filebench_shm->shm_threadflow_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&filebench_shm->shm_flowop_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&filebench_shm->shm_msg_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&filebench_shm->shm_eventgen_lock,
- ipc_mutexattr(IPC_MUTEX_PRI_ROB));
- (void) pthread_mutex_init(&filebench_shm->shm_malloc_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_mutex_init(&filebench_shm->shm_ism_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
- (void) pthread_cond_init(&filebench_shm->shm_eventgen_cv,
- ipc_condattr());
- (void) pthread_rwlock_init(&filebench_shm->shm_flowop_find_lock,
- ipc_rwlockattr());
-#ifdef USE_PROCESS_MODEL
- (void) pthread_cond_init(&filebench_shm->shm_procflow_procs_cv,
- ipc_condattr());
-#endif
- (void) pthread_rwlock_init(&filebench_shm->shm_run_lock,
- ipc_rwlockattr());
- (void) pthread_rwlock_rdlock(&filebench_shm->shm_run_lock);
-
- (void) ipc_mutex_lock(&filebench_shm->shm_ism_lock);
-
- /* Create semaphore */
- if ((key = ftok(shmpath, 1)) < 0) {
- filebench_log(LOG_ERROR, "cannot create sem: %s",
- strerror(errno));
- exit(1);
- }
-
-#ifdef HAVE_SEM_RMID
- if ((sys_semid = semget(key, 0, 0)) != -1)
- (void) semctl(sys_semid, 0, IPC_RMID);
-#endif
-
- filebench_shm->shm_semkey = key;
- filebench_shm->shm_sys_semid = -1;
- filebench_shm->shm_log_fd = -1;
- filebench_shm->shm_dump_fd = -1;
- filebench_shm->shm_eventgen_hz = 0;
- filebench_shm->shm_id = -1;
-
- free(buf);
-}
-
-/*
- * If compiled to use process model, just unlinks the shmpath.
- * Otherwise a no-op.
- */
-void
-ipc_fini(void)
-{
-#ifdef USE_PROCESS_MODEL
- (void) unlink(shmpath);
-#endif /* USE_PROCESS_MODEL */
-
-#ifdef HAVE_SEM_RMID
- if (filebench_shm->shm_sys_semid != -1) {
- (void) semctl(filebench_shm->shm_sys_semid, 0, IPC_RMID);
- filebench_shm->shm_sys_semid = -1;
- }
-#endif
-}
-
-/*
- * Attach to shared memory. Used by worker processes to open
- * and mmap the shared memory region. If successful, it
- * initializes the worker process' filebench_shm to point to
- * the region and returns 0. Otherwise it returns -1.
- */
-int
-ipc_attach(caddr_t shmaddr)
-{
- if ((shmfd = open(shmpath, O_RDWR, 0666)) < 0) {
- filebench_log(LOG_ERROR, "Cannot open shm");
- return (-1);
- }
-
- /* LINTED E_BAD_PTR_CAST_ALIGN */
- if ((filebench_shm = (filebench_shm_t *)mmap(shmaddr,
- sizeof (filebench_shm_t), PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_FIXED, shmfd, 0)) == NULL) {
- filebench_log(LOG_ERROR, "Cannot mmap shm");
- return (-1);
- }
-
- filebench_log(LOG_DEBUG_IMPL, "addr = %zx", filebench_shm);
-
- return (0);
-}
-
-static int filebench_sizes[] = {
- FILEBENCH_NPROCFLOWS, /* number of procflows */
- FILEBENCH_NTHREADFLOWS, /* number of threadflows */
- FILEBENCH_NFLOWOPS, /* number of flowops */
- (FILEBENCH_NVARS * 2), /* number of attribute value dscrs */
- FILEBENCH_NVARS, /* number of variables */
- FILEBENCH_NFILESETS, /* number of filesets */
- FILEBENCH_NFILESETENTRIES, /* number of fileset entries */
- FILEBENCH_NRANDDISTS}; /* number of random distributions */
-
-/*
- * Allocates filebench objects from pre allocated region of
- * shareable memory. The memory region is partitioned into sets
- * of objects during initialization. This routine scans for
- * the first unallocated object of type "type" in the set of
- * available objects, and makes it as allocated. The routine
- * returns a pointer to the object, or NULL if all objects have
- * been allocated.
- */
-void *
-ipc_malloc(int type)
-{
- int i;
- int max = filebench_sizes[type];
- int start_idx = filebench_shm->shm_lastbitmapindex[type];
-
- (void) ipc_mutex_lock(&filebench_shm->shm_malloc_lock);
-
- i = start_idx;
- do {
- i++;
- if (i >= max)
- i = 0;
-
- if (filebench_shm->shm_bitmap[type][i] == 0)
- break;
-
- } while (i != start_idx);
-
- if (i == start_idx) {
- filebench_log(LOG_ERROR, "Out of shared memory (%d)!", type);
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return (NULL);
- }
-
- filebench_shm->shm_bitmap[type][i] = 1;
- filebench_shm->shm_lastbitmapindex[type] = i;
-
- switch (type) {
- case FILEBENCH_FILESET:
- (void) memset((char *)&filebench_shm->shm_fileset[i], 0,
- sizeof (fileset_t));
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_fileset[i]);
-
- case FILEBENCH_FILESETENTRY:
- (void) memset((char *)&filebench_shm->shm_filesetentry[i], 0,
- sizeof (filesetentry_t));
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_filesetentry[i]);
-
- case FILEBENCH_PROCFLOW:
- (void) memset((char *)&filebench_shm->shm_procflow[i], 0,
- sizeof (procflow_t));
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_procflow[i]);
-
- case FILEBENCH_THREADFLOW:
- (void) memset((char *)&filebench_shm->shm_threadflow[i], 0,
- sizeof (threadflow_t));
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_threadflow[i]);
-
- case FILEBENCH_FLOWOP:
- (void) memset((char *)&filebench_shm->shm_flowop[i], 0,
- sizeof (flowop_t));
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_flowop[i]);
-
- case FILEBENCH_AVD:
- filebench_shm->shm_avd_ptrs[i].avd_type = AVD_INVALID;
- filebench_shm->shm_avd_ptrs[i].avd_val.varptr = NULL;
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_avd_ptrs[i]);
-
- case FILEBENCH_VARIABLE:
- (void) memset((char *)&filebench_shm->shm_var[i], 0,
- sizeof (var_t));
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_var[i]);
-
- case FILEBENCH_RANDDIST:
- (void) memset((char *)&filebench_shm->shm_randdist[i], 0,
- sizeof (randdist_t));
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
- return ((char *)&filebench_shm->shm_randdist[i]);
- }
-
- filebench_log(LOG_ERROR, "Attempt to ipc_malloc unknown type (%d)!",
- type);
- return (NULL);
-}
-
-/*
- * Frees a filebench object of type "type" at the location
- * pointed to by "addr". It uses the type and address to
- * calculate which object is being freed, and clears its
- * allocation map entry.
- */
-void
-ipc_free(int type, char *addr)
-{
- int item;
- caddr_t base;
- size_t offset;
- size_t size;
-
- if (addr == NULL) {
- filebench_log(LOG_ERROR, "Freeing type %d %zx", type, addr);
- return;
- }
-
- switch (type) {
-
- case FILEBENCH_FILESET:
- base = (caddr_t)&filebench_shm->shm_fileset[0];
- size = sizeof (fileset_t);
- break;
-
- case FILEBENCH_FILESETENTRY:
- base = (caddr_t)&filebench_shm->shm_filesetentry[0];
- size = sizeof (filesetentry_t);
- break;
-
- case FILEBENCH_PROCFLOW:
- base = (caddr_t)&filebench_shm->shm_procflow[0];
- size = sizeof (procflow_t);
- break;
-
- case FILEBENCH_THREADFLOW:
- base = (caddr_t)&filebench_shm->shm_threadflow[0];
- size = sizeof (threadflow_t);
- break;
-
- case FILEBENCH_FLOWOP:
- base = (caddr_t)&filebench_shm->shm_flowop[0];
- size = sizeof (flowop_t);
- break;
-
- case FILEBENCH_AVD:
- base = (caddr_t)&filebench_shm->shm_avd_ptrs[0];
- size = sizeof (avd_t);
- break;
-
- case FILEBENCH_VARIABLE:
- base = (caddr_t)&filebench_shm->shm_var[0];
- size = sizeof (var_t);
- break;
-
- case FILEBENCH_RANDDIST:
- base = (caddr_t)&filebench_shm->shm_randdist[0];
- size = sizeof (randdist_t);
- break;
- }
-
- offset = ((size_t)addr - (size_t)base);
- item = offset / size;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_malloc_lock);
- filebench_shm->shm_bitmap[type][item] = 0;
- (void) ipc_mutex_unlock(&filebench_shm->shm_malloc_lock);
-}
-
-/*
- * Allocate a string from filebench string memory. The length
- * of the allocated string is the same as the length of the
- * supplied string "string", and the contents of string are
- * copied to the newly allocated string.
- */
-char *
-ipc_stralloc(char *string)
-{
- char *allocstr = filebench_shm->shm_string_ptr;
-
- filebench_shm->shm_string_ptr += strlen(string) + 1;
-
- if ((filebench_shm->shm_string_ptr - &filebench_shm->shm_strings[0]) >
- FILEBENCH_STRINGMEMORY) {
- filebench_log(LOG_ERROR, "Out of ipc string memory");
- return (NULL);
- }
-
- (void) strncpy(allocstr, string, strlen(string));
-
- return (allocstr);
-}
-
-/*
- * Allocate a path string from filebench path string memory.
- * Specifically used for allocating fileset paths. The length
- * of the allocated path string is the same as the length of
- * the supplied path string "path", and the contents of path
- * are copied to the newly allocated path string. Checks for
- * out-of-path-string-memory condition and returns NULL if so.
- * Otherwise it returns a pointer to the newly allocated path
- * string.
- */
-char *
-ipc_pathalloc(char *path)
-{
- char *allocpath = filebench_shm->shm_path_ptr;
-
- filebench_shm->shm_path_ptr += strlen(path) + 1;
-
- if ((filebench_shm->shm_path_ptr -
- &filebench_shm->shm_filesetpaths[0]) >
- FILEBENCH_FILESETPATHMEMORY) {
- filebench_log(LOG_ERROR, "Out of fileset path memory");
- return (NULL);
- }
-
- (void) strncpy(allocpath, path, strlen(path));
-
- return (allocpath);
-}
-
-/*
- * This is a limited functionality deallocator for path
- * strings - it can only free all path strings at once,
- * in order to avoid fragmentation.
- */
-void
-ipc_freepaths(void)
-{
- filebench_shm->shm_path_ptr = &filebench_shm->shm_filesetpaths[0];
-}
-
-/*
- * Allocates a semid from the table of semids for pre intialized
- * semaphores. Searches for the first available semaphore, and
- * sets the entry in the table to "1" to indicate allocation.
- * Returns the allocated semid. Stops the run if all semaphores
- * are already in use.
- */
-int
-ipc_semidalloc(void)
-{
- int semid;
-
- for (semid = 0; filebench_shm->shm_semids[semid] == 1; semid++)
- ;
- if (semid == FILEBENCH_NSEMS) {
- filebench_log(LOG_ERROR,
- "Out of semaphores, increase system tunable limit");
- filebench_shutdown(1);
- }
- filebench_shm->shm_semids[semid] = 1;
- return (semid);
-}
-
-/*
- * Frees up the supplied semid by seting its position in the
- * allocation table to "0".
- */
-void
-ipc_semidfree(int semid)
-{
- filebench_shm->shm_semids[semid] = 0;
-}
-
-/*
- * Create a pool of shared memory to fit the per-thread
- * allocations. Uses shmget() to create a shared memory region
- * of size "size", attaches to it using shmat(), and stores
- * the returned address of the region in filebench_shm->shm_addr.
- * The pool is only created on the first call. The routine
- * returns 0 if successful or the pool already exists,
- * -1 otherwise.
- */
-int
-ipc_ismcreate(size_t size)
-{
-#ifdef HAVE_SHM_SHARE_MMU
- int flag = SHM_SHARE_MMU;
-#else
- int flag = 0;
-#endif /* HAVE_SHM_SHARE_MMU */
-
- /* Already done? */
- if (filebench_shm->shm_id != -1)
- return (0);
-
- filebench_log(LOG_VERBOSE,
- "Creating %zd bytes of ISM Shared Memory...", size);
-
- if ((filebench_shm->shm_id =
- shmget(0, size, IPC_CREAT | 0666)) == -1) {
- filebench_log(LOG_ERROR,
- "Failed to create %zd bytes of ISM shared memory", size);
- return (-1);
- }
-
- if ((filebench_shm->shm_addr = (caddr_t)shmat(filebench_shm->shm_id,
- 0, flag)) == (void *)-1) {
- filebench_log(LOG_ERROR,
- "Failed to attach %zd bytes of created ISM shared memory",
- size);
- return (-1);
- }
-
- filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr;
-
- filebench_log(LOG_VERBOSE,
- "Allocated %zd bytes of ISM Shared Memory... at %zx",
- size, filebench_shm->shm_addr);
-
- /* Locked until allocated to block allocs */
- (void) ipc_mutex_unlock(&filebench_shm->shm_ism_lock);
-
- return (0);
-}
-
-/* Per addr space ism */
-static int ism_attached = 0;
-
-/*
- * Attach to interprocess shared memory. If already attached
- * just return, otherwise use shmat() to attached to the region
- * with ID of filebench_shm->shm_id. Returns -1 if shmat()
- * fails, otherwise 0.
- */
-static int
-ipc_ismattach(void)
-{
-#ifdef HAVE_SHM_SHARE_MMU
- int flag = SHM_SHARE_MMU;
-#else
- int flag = 0;
-#endif /* HAVE_SHM_SHARE_MMU */
-
-
- if (ism_attached)
- return (0);
-
- /* Does it exist? */
- if (filebench_shm->shm_id == 999)
- return (0);
-
- if (shmat(filebench_shm->shm_id, filebench_shm->shm_addr,
- flag) == NULL)
- return (-1);
-
- ism_attached = 1;
-
- return (0);
-}
-
-/*
- * Allocate from interprocess shared memory. Attaches to ism
- * if necessary, then allocates "size" bytes, updates allocation
- * information and returns a pointer to the allocated memory.
- */
-/*
- * XXX No check is made for out-of-memory condition
- */
-char *
-ipc_ismmalloc(size_t size)
-{
- char *allocstr;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_ism_lock);
-
- /* Map in shared memory */
- (void) ipc_ismattach();
-
- allocstr = filebench_shm->shm_ptr;
-
- filebench_shm->shm_ptr += size;
- filebench_shm->shm_allocated += size;
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_ism_lock);
-
- return (allocstr);
-}
-
-/*
- * Deletes shared memory region and resets shared memory region
- * information in filebench_shm.
- */
-void
-ipc_ismdelete(void)
-{
- if (filebench_shm->shm_id == -1)
- return;
-
- filebench_log(LOG_VERBOSE, "Deleting ISM...");
-
- (void) ipc_mutex_lock(&filebench_shm->shm_ism_lock);
-#ifdef HAVE_SEM_RMID
- (void) shmctl(filebench_shm->shm_id, IPC_RMID, 0);
-#endif
- filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr;
- filebench_shm->shm_id = -1;
- filebench_shm->shm_allocated = 0;
- (void) ipc_mutex_unlock(&filebench_shm->shm_ism_lock);
-}
diff --git a/usr/src/cmd/filebench/common/ipc.h b/usr/src/cmd/filebench/common/ipc.h
deleted file mode 100644
index 1df49ca881..0000000000
--- a/usr/src/cmd/filebench/common/ipc.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_IPC_H
-#define _FB_IPC_H
-
-#include "config.h"
-#include <pthread.h>
-
-#include "procflow.h"
-#include "threadflow.h"
-#include "fileset.h"
-#include "flowop.h"
-#include "fb_random.h"
-#include "fsplug.h"
-#include "filebench.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef USE_PROCESS_MODEL
-#define FILEBENCH_MEMSIZE 4096
-#else
-#define FILEBENCH_MEMSIZE 2048
-#endif /* USE_PROCESS_MODEL */
-
-/* Mutex Priority Inheritance and Robustness flags */
-#define IPC_MUTEX_NORMAL 0x0
-#define IPC_MUTEX_PRIORITY 0x1
-#define IPC_MUTEX_ROBUST 0x2
-#define IPC_MUTEX_PRI_ROB 0x3
-#define IPC_NUM_MUTEX_ATTRS 4
-
-#define FILEBENCH_NFILESETS FILEBENCH_MEMSIZE
-#define FILEBENCH_NFILESETENTRIES (1024 * 1024)
-#define FILEBENCH_NPROCFLOWS FILEBENCH_MEMSIZE
-#define FILEBENCH_NTHREADFLOWS (64 * FILEBENCH_MEMSIZE)
-#define FILEBENCH_NFLOWOPS (64 * FILEBENCH_MEMSIZE)
-#define FILEBENCH_NVARS FILEBENCH_MEMSIZE
-#define FILEBENCH_NRANDDISTS (FILEBENCH_MEMSIZE/4)
-#define FILEBENCH_FILESETPATHMEMORY (FILEBENCH_NFILESETENTRIES*FSE_MAXPATHLEN)
-#define FILEBENCH_STRINGMEMORY (FILEBENCH_NVARS * 128)
-#define FILEBENCH_MAXBITMAP FILEBENCH_NFILESETENTRIES
-
-#define FILEBENCH_PROCFLOW 0
-#define FILEBENCH_THREADFLOW 1
-#define FILEBENCH_FLOWOP 2
-#define FILEBENCH_AVD 3
-#define FILEBENCH_VARIABLE 4
-#define FILEBENCH_FILESET 5
-#define FILEBENCH_FILESETENTRY 6
-#define FILEBENCH_RANDDIST 7
-#define FILEBENCH_TYPES 8
-
-#define FILEBENCH_NSEMS 128
-
-#define FILEBENCH_ABORT_ERROR 1
-#define FILEBENCH_ABORT_DONE 2
-#define FILEBENCH_ABORT_RSRC 3
-#define FILEBENCH_ABORT_FINI 4
-
- /* run modes */
-#define FILEBENCH_MODE_TIMEOUT 0x0
-#define FILEBENCH_MODE_Q1STDONE 0x1
-#define FILEBENCH_MODE_QALLDONE 0x2
-
- /* misc. modes */
-#define FILEBENCH_MODE_NOUSAGE 0x01
-
-typedef struct filebench_shm {
- /*
- * All state down to shm_marker are set to zero during filebench
- * initialization
- */
-
- /*
- * list of defined filesets and related locks.
- */
- fileset_t *shm_filesetlist; /* list of defined filesets */
- pthread_mutex_t shm_fileset_lock; /* protects access to list */
-
- /*
- * parallel file allocation control. Restricts number of spawned
- * allocation threads and allows waiting for allocation to finish.
- */
- pthread_cond_t shm_fsparalloc_cv; /* cv to wait for alloc threads */
- int shm_fsparalloc_count; /* active alloc thread count */
- pthread_mutex_t shm_fsparalloc_lock; /* lock to protect count */
-
- /*
- * Procflow and process state
- */
- procflow_t *shm_proclist; /* list of defined procflows */
- pthread_mutex_t shm_procflow_lock; /* protects shm_proclist */
- int shm_procs_running; /* count of running processes */
- pthread_mutex_t shm_procs_running_lock; /* protects shm_procs_running */
- int shm_f_abort; /* stop the run NOW! */
- pthread_rwlock_t shm_run_lock; /* used as barrier to sync run */
-#ifdef USE_PROCESS_MODEL
- pthread_cond_t shm_procflow_procs_cv; /* pauses procflow_init till */
-#endif /* all procflows are created */
-
- /*
- * flowop state
- */
- flowop_t *shm_flowoplist; /* list of defined flowops */
- pthread_mutex_t shm_flowop_lock; /* protects flowoplist */
- pthread_rwlock_t shm_flowop_find_lock; /* prevents flowop_find() */
- /* during initial flowop creation */
-
- /*
- * lists related to variables
- */
-
- var_t *shm_var_list; /* normal variables */
- var_t *shm_var_dyn_list; /* special system variables */
- var_t *shm_var_loc_list; /* variables local to comp flowops */
- randdist_t *shm_rand_list; /* random variables */
-
- /*
- * log and statistics dumping controls and state
- */
- int shm_debug_level;
- int shm_bequiet; /* pause run while collecting stats */
- int shm_log_fd; /* log file descriptor */
- int shm_dump_fd; /* dump file descriptor */
- char shm_dump_filename[MAXPATHLEN];
-
- /*
- * Event generator state
- */
- int shm_eventgen_enabled; /* event gen in operation */
- avd_t shm_eventgen_hz; /* number of events per sec. */
- uint64_t shm_eventgen_q; /* count of unclaimed events */
- pthread_mutex_t shm_eventgen_lock; /* lock protecting count */
- pthread_cond_t shm_eventgen_cv; /* cv to wait on for more events */
-
- /*
- * System 5 semaphore state
- */
- key_t shm_semkey;
- int shm_sys_semid;
- char shm_semids[FILEBENCH_NSEMS];
-
- /*
- * Misc. pointers and state
- */
- char shm_fscriptname[1024];
- int shm_id;
- int shm_rmode; /* run mode settings */
- int shm_mmode; /* misc. mode settings */
- int shm_1st_err;
- pthread_mutex_t shm_threadflow_lock;
- pthread_mutex_t shm_msg_lock;
- pthread_mutexattr_t shm_mutexattr[IPC_NUM_MUTEX_ATTRS];
- char *shm_string_ptr;
- char *shm_path_ptr;
- hrtime_t shm_epoch;
- hrtime_t shm_starttime;
- int shm_utid;
-
- /*
- * Shared memory allocation control
- */
- pthread_mutex_t shm_malloc_lock;
- pthread_mutex_t shm_ism_lock;
- int shm_bitmap[FILEBENCH_TYPES][FILEBENCH_MAXBITMAP];
- int shm_lastbitmapindex[FILEBENCH_TYPES];
- size_t shm_required;
- size_t shm_allocated;
- caddr_t shm_addr;
- char *shm_ptr;
-
- /*
- * Type of plug-in file system client to use. Defaults to
- * local file system, which is type "0".
- */
- fb_plugin_type_t shm_filesys_type;
-
- /*
- * end of pre-zeroed data
- */
- int shm_marker;
-
- /*
- * actual storage for shared entities.
- * These are not zeroed during initialization
- */
- fileset_t shm_fileset[FILEBENCH_NFILESETS];
- filesetentry_t shm_filesetentry[FILEBENCH_NFILESETENTRIES];
- char shm_filesetpaths[FILEBENCH_FILESETPATHMEMORY];
- procflow_t shm_procflow[FILEBENCH_NPROCFLOWS];
- threadflow_t shm_threadflow[FILEBENCH_NTHREADFLOWS];
- flowop_t shm_flowop[FILEBENCH_NFLOWOPS];
- var_t shm_var[FILEBENCH_NVARS];
- randdist_t shm_randdist[FILEBENCH_NRANDDISTS];
- struct avd shm_avd_ptrs[FILEBENCH_NVARS * 2];
- char shm_strings[FILEBENCH_STRINGMEMORY];
-} filebench_shm_t;
-
-extern char *shmpath;
-
-void ipc_init(void);
-void *ipc_malloc(int type);
-void ipc_free(int type, char *addr);
-int ipc_attach(caddr_t shmaddr);
-pthread_mutexattr_t *ipc_mutexattr(int);
-pthread_condattr_t *ipc_condattr(void);
-int ipc_semidalloc(void);
-void ipc_semidfree(int semid);
-char *ipc_stralloc(char *string);
-char *ipc_pathalloc(char *string);
-int ipc_mutex_lock(pthread_mutex_t *mutex);
-int ipc_mutex_unlock(pthread_mutex_t *mutex);
-void ipc_seminit(void);
-char *ipc_ismmalloc(size_t size);
-int ipc_ismcreate(size_t size);
-void ipc_ismdelete(void);
-void ipc_fini(void);
-
-extern filebench_shm_t *filebench_shm;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_IPC_H */
diff --git a/usr/src/cmd/filebench/common/misc.c b/usr/src/cmd/filebench/common/misc.c
deleted file mode 100644
index 8f7f0be119..0000000000
--- a/usr/src/cmd/filebench/common/misc.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <time.h>
-#include <libgen.h>
-#include <unistd.h>
-#include <strings.h>
-#include "filebench.h"
-#include "ipc.h"
-#include "eventgen.h"
-#include "utils.h"
-#include "fsplug.h"
-
-/* File System functions vector */
-fsplug_func_t *fs_functions_vec;
-
-/*
- * Routines to access high resolution system time, initialize and
- * shutdown filebench, log filebench run progress and errors, and
- * access system information strings.
- */
-
-#if !defined(sun) && defined(USE_RDTSC)
-/*
- * Lets us use the rdtsc instruction to get highres time.
- * Thanks to libmicro
- */
-uint64_t cpu_hz = 0;
-
-/*
- * Uses the rdtsc instruction to get high resolution (cpu
- * clock ticks) time. Only used for non Sun compiles.
- */
-__inline__ long long
-rdtsc(void)
-{
- unsigned long long x;
- __asm__ volatile(".byte 0x0f, 0x31" : "=A" (x));
- return (x);
-}
-
-/*
- * Get high resolution time in nanoseconds. This is the version
- * used when not compiled for Sun systems. It uses rdtsc call to
- * get clock ticks and converts to nanoseconds
- */
-uint64_t
-gethrtime(void)
-{
- uint64_t hrt;
-
- /* convert to nanosecs and return */
- hrt = 1000000000UL * rdtsc() / cpu_hz;
- return (hrt);
-}
-
-/*
- * Gets CPU clock frequency in MHz from cpuinfo file.
- * Converts to cpu_hz and stores in cpu_hz global uint64_t.
- * Only used for non Sun compiles.
- */
-static uint64_t
-parse_cpu_hz(void)
-{
- /*
- * Parse the following from /proc/cpuinfo.
- * cpu MHz : 2191.563
- */
- FILE *cpuinfo;
- double hertz = -1;
- uint64_t hz;
-
- if ((cpuinfo = fopen("/proc/cpuinfo", "r")) == NULL) {
- filebench_log(LOG_ERROR, "open /proc/cpuinfo failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
- while (!feof(cpuinfo)) {
- char buffer[80];
-
- fgets(buffer, 80, cpuinfo);
- if (strlen(buffer) == 0) continue;
- if (strncasecmp(buffer, "cpu MHz", 7) == 0) {
- char *token = strtok(buffer, ":");
-
- if (token != NULL) {
- token = strtok((char *)NULL, ":");
- hertz = strtod(token, NULL);
- }
- break;
- }
- }
- hz = hertz * 1000000;
-
- return (hz);
-}
-
-#elif !defined(sun)
-
-/*
- * Get high resolution time in nanoseconds. This is the version
- * used if compiled for Sun systems. It calls gettimeofday
- * to get current time and converts it to nanoseconds.
- */
-uint64_t
-gethrtime(void)
-{
- struct timeval tv;
- uint64_t hrt;
-
- gettimeofday(&tv, NULL);
-
- hrt = (uint64_t)tv.tv_sec * 1000000000UL +
- (uint64_t)tv.tv_usec * 1000UL;
- return (hrt);
-}
-#endif
-
-/*
- * Main filebench initialization. Opens the random number
- * "device" file or shuts down the run if one is not found.
- * Sets the cpu clock frequency variable or shuts down the
- * run if one is not found.
- */
-void
-filebench_init(void)
-{
- fb_random_init();
-
-#if defined(USE_RDTSC) && (LINUX_PORT)
- cpu_hz = parse_cpu_hz();
- if (cpu_hz <= 0) {
- filebench_log(LOG_ERROR, "Error getting CPU Mhz: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
-#endif /* USE_RDTSC */
-}
-
-extern int lex_lineno;
-
-/*
- * Writes a message consisting of information formated by
- * "fmt" to the log file, dump file or stdout. The supplied
- * "level" argument determines which file to write to and
- * what other actions to take. The level LOG_LOG writes to
- * the "log" file, and will open the file on the first
- * invocation. The level LOG_DUMP writes to the "dump" file,
- * and will open it on the first invocation. Other levels
- * print to the stdout device, with the amount of information
- * dependent on the error level and the current error level
- * setting in filebench_shm->shm_debug_level.
- */
-void filebench_log
-__V((int level, const char *fmt, ...))
-{
- va_list args;
- hrtime_t now;
- char line[131072];
- char buf[131072];
-
- if (level == LOG_FATAL)
- goto fatal;
-
- /* open logfile if not already open and writing to it */
- if ((level == LOG_LOG) &&
- (filebench_shm->shm_log_fd < 0)) {
- char path[MAXPATHLEN];
- char *s;
-
- (void) strcpy(path, filebench_shm->shm_fscriptname);
- if ((s = strstr(path, ".f")))
- *s = 0;
- else
- (void) strcpy(path, "filebench");
-
- (void) strcat(path, ".csv");
-
- filebench_shm->shm_log_fd =
- open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
- }
-
- /*
- * if logfile still not open, switch to LOG_ERROR level so
- * it gets reported to stdout
- */
- if ((level == LOG_LOG) &&
- (filebench_shm->shm_log_fd < 0)) {
- (void) snprintf(line, sizeof (line), "Open logfile failed: %s",
- strerror(errno));
- level = LOG_ERROR;
- }
-
- /* open dumpfile if not already open and writing to it */
- if ((level == LOG_DUMP) &&
- (*filebench_shm->shm_dump_filename == 0))
- return;
-
- if ((level == LOG_DUMP) &&
- (filebench_shm->shm_dump_fd < 0)) {
-
- filebench_shm->shm_dump_fd =
- open(filebench_shm->shm_dump_filename,
- O_RDWR | O_CREAT | O_TRUNC, 0666);
- }
-
- if ((level == LOG_DUMP) &&
- (filebench_shm->shm_dump_fd < 0)) {
- (void) snprintf(line, sizeof (line), "Open logfile failed: %s",
- strerror(errno));
- level = LOG_ERROR;
- }
-
- /* Quit if this is a LOG_ERROR messages and they are disabled */
- if ((filebench_shm->shm_1st_err) && (level == LOG_ERROR))
- return;
-
- if (level == LOG_ERROR1) {
- if (filebench_shm->shm_1st_err)
- return;
-
- /* A LOG_ERROR1 temporarily disables LOG_ERROR messages */
- filebench_shm->shm_1st_err = 1;
- level = LOG_ERROR;
- }
-
- /* Only log greater than debug setting */
- if ((level != LOG_DUMP) && (level != LOG_LOG) &&
- (level > filebench_shm->shm_debug_level))
- return;
-
- now = gethrtime();
-
-fatal:
-
-#ifdef __STDC__
- va_start(args, fmt);
-#else
- char *fmt;
- va_start(args);
- fmt = va_arg(args, char *);
-#endif
-
- (void) vsprintf(line, fmt, args);
-
- va_end(args);
-
- if (level == LOG_FATAL) {
- (void) fprintf(stderr, "%s\n", line);
- return;
- }
-
- /* Serialize messages to log */
- (void) ipc_mutex_lock(&filebench_shm->shm_msg_lock);
-
- if (level == LOG_LOG) {
- if (filebench_shm->shm_log_fd > 0) {
- (void) snprintf(buf, sizeof (buf), "%s\n", line);
- (void) write(filebench_shm->shm_log_fd, buf,
- strlen(buf));
- (void) fsync(filebench_shm->shm_log_fd);
- (void) ipc_mutex_unlock(&filebench_shm->shm_msg_lock);
- return;
- }
-
- } else if (level == LOG_DUMP) {
- if (filebench_shm->shm_dump_fd != -1) {
- (void) snprintf(buf, sizeof (buf), "%s\n", line);
- (void) write(filebench_shm->shm_dump_fd, buf,
- strlen(buf));
- (void) fsync(filebench_shm->shm_dump_fd);
- (void) ipc_mutex_unlock(&filebench_shm->shm_msg_lock);
- return;
- }
-
- } else if (filebench_shm->shm_debug_level > LOG_INFO) {
- if (level < LOG_INFO)
- (void) fprintf(stderr, "%5d: ", (int)my_pid);
- else
- (void) fprintf(stdout, "%5d: ", (int)my_pid);
- }
-
- if (level < LOG_INFO) {
- (void) fprintf(stderr, "%4.3f: %s",
- (now - filebench_shm->shm_epoch) / FSECS,
- line);
-
- if (my_procflow == NULL)
- (void) fprintf(stderr, " on line %d", lex_lineno);
-
- (void) fprintf(stderr, "\n");
- (void) fflush(stderr);
- } else {
- (void) fprintf(stdout, "%4.3f: %s",
- (now - filebench_shm->shm_epoch) / FSECS,
- line);
- (void) fprintf(stdout, "\n");
- (void) fflush(stdout);
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_msg_lock);
-}
-
-/*
- * Stops the run and exits filebench. If filebench is
- * currently running a workload, calls procflow_shutdown()
- * to stop the run. Also closes and deletes shared memory.
- */
-void
-filebench_shutdown(int error) {
-
- if (error) {
- filebench_log(LOG_DEBUG_IMPL, "Shutdown on error %d", error);
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
- if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_FINI) {
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_procflow_lock);
- return;
- }
- filebench_shm->shm_f_abort = FILEBENCH_ABORT_ERROR;
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
- } else {
- filebench_log(LOG_DEBUG_IMPL, "Shutdown");
- }
-
- procflow_shutdown();
-
- (void) unlink("/tmp/filebench_shm");
- ipc_ismdelete();
- exit(error);
-}
-
-/*
- * Put the hostname in ${hostname}. The system supplied
- * host name string is copied into an allocated string and
- * the pointer to the string is placed in the supplied
- * variable "var". If var->var_val.string already points to
- * a string, the string is freed. The routine always
- * returns zero (0).
- */
-var_t *
-host_var(var_t *var)
-{
- char hoststr[128];
- char *strptr;
-
- (void) gethostname(hoststr, 128);
- if (VAR_HAS_STRING(var) && var->var_val.string)
- free(var->var_val.string);
-
- if ((strptr = fb_stralloc(hoststr)) == NULL) {
- filebench_log(LOG_ERROR,
- "unable to allocate string for host name");
- return (NULL);
- }
-
- VAR_SET_STR(var, strptr);
- return (0);
-}
-
-/*
- * Put the date string in ${date}. The system supplied date is
- * copied into an allocated string and the pointer to the string
- * is placed in the supplied var_t's var_val.string. If
- * var->var_val.string already points to a string, the string
- * is freed. The routine returns a pointer to the supplied var_t,
- * unless it is unable to allocate string for the date, in which
- * case it returns NULL.
- */
-var_t *
-date_var(var_t *var)
-{
- char datestr[128];
- char *strptr;
-#ifdef HAVE_CFTIME
- time_t t = time(NULL);
-#else
- struct tm t;
-#endif
-
-#ifdef HAVE_CFTIME
- cftime(datestr, "%y%m%d%H" "%M", &t);
-#else
- (void) strftime(datestr, sizeof (datestr), "%y%m%d%H %M", &t);
-#endif
-
- if (VAR_HAS_STRING(var) && var->var_val.string)
- free(var->var_val.string);
-
- if ((strptr = fb_stralloc(datestr)) == NULL) {
- filebench_log(LOG_ERROR,
- "unable to allocate string for date");
- return (NULL);
- }
-
- VAR_SET_STR(var, strptr);
-
- return (var);
-}
-
-extern char *fscriptname;
-
-/*
- * Put the script name in ${script}. The path name of the script
- * used with this filebench run trimmed of the trailing ".f" and
- * all leading subdirectories. The remaining script name is
- * copied into the var_val.string field of the supplied variable
- * "var". The routine returns a pointer to the supplied var_t,
- * unless it is unable to allocate string space, in which case it
- * returns NULL.
- */
-var_t *
-script_var(var_t *var)
-{
- char *scriptstr;
- char *f = fb_stralloc(fscriptname);
- char *strptr;
-
- /* Trim the .f suffix */
- for (scriptstr = f + strlen(f) - 1; scriptstr != f; scriptstr--) {
- if (*scriptstr == '.') {
- *scriptstr = 0;
- break;
- }
- }
-
- if ((strptr = fb_stralloc(basename(f))) == NULL) {
- filebench_log(LOG_ERROR,
- "unable to allocate string for script name");
- free(f);
- return (NULL);
- }
-
- VAR_SET_STR(var, strptr);
- free(f);
-
- return (var);
-}
-
-void fb_lfs_funcvecinit(void);
-
-/*
- * Initialize any "plug-in" I/O function vectors. Called by each
- * filebench process that is forked, as the vector is relative to
- * its image.
- */
-void
-filebench_plugin_funcvecinit(void)
-{
-
- switch (filebench_shm->shm_filesys_type) {
- case LOCAL_FS_PLUG:
- fb_lfs_funcvecinit();
- break;
-
- case NFS3_PLUG:
- case NFS4_PLUG:
- case CIFS_PLUG:
- break;
- default:
- filebench_log(LOG_ERROR,
- "filebench_plugin_funcvecinit: unknown file system");
- break;
- }
-}
diff --git a/usr/src/cmd/filebench/common/misc.h b/usr/src/cmd/filebench/common/misc.h
deleted file mode 100644
index 1f4cdf75d7..0000000000
--- a/usr/src/cmd/filebench/common/misc.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_MISC_H
-#define _FB_MISC_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "config.h"
-
-#include <stdio.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#include <sys/times.h>
-
-#include "vars.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define DATE_VAR "date"
-#define SCRIPT_VAR "scriptname"
-#define HOST_VAR "hostname"
-
-#ifndef HAVE_HRTIME
-uint64_t gethrtime();
-#define hrtime_t uint64_t
-#endif
-#define FSECS (double)1000000000.0
-
-#define LOG_ERROR 0 /* a major error */
-#define LOG_ERROR1 1 /* also major error, but turn off error reporting */
- /* for now */
-#define LOG_INFO 2 /* some useful information. Default is to print */
-#define LOG_VERBOSE 3 /* four more levels of detailed information */
-#define LOG_DEBUG_SCRIPT 4
-#define LOG_DEBUG_IMPL 6
-#define LOG_DEBUG_NEVER 10
-#define LOG_FATAL 999 /* really bad error, shut down */
-#define LOG_LOG 1000
-#define LOG_DUMP 1001
-
-var_t *date_var(var_t *var);
-var_t *script_var(var_t *var);
-var_t *host_var(var_t *var);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_MISC_H */
diff --git a/usr/src/cmd/filebench/common/multi_client_sync.c b/usr/src/cmd/filebench/common/multi_client_sync.c
deleted file mode 100644
index 459f18229f..0000000000
--- a/usr/src/cmd/filebench/common/multi_client_sync.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include "filebench.h"
-#include "multi_client_sync.h"
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#define MCS_NAMELENGTH 128
-#define MCS_MSGLENGTH (MCS_NAMELENGTH * 8)
-
-static int mc_sync_sock_id;
-static char this_client_name[MCS_NAMELENGTH];
-
-/*
- * Open a socket to the master synchronization host
- */
-int
-mc_sync_open_sock(char *master_name, int master_port, char *my_name)
-{
- struct sockaddr_in client_in;
- struct sockaddr_in master_in;
- struct hostent master_info;
- int error_num;
- char buffer[MCS_MSGLENGTH];
-
- (void) strncpy(this_client_name, my_name, MCS_NAMELENGTH);
- if ((mc_sync_sock_id = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
- filebench_log(LOG_ERROR, "could not create a client socket");
- return (FILEBENCH_ERROR);
- }
-
- client_in.sin_family = AF_INET;
- client_in.sin_port = INADDR_ANY;
- client_in.sin_addr.s_addr = INADDR_ANY;
-
- if (bind(mc_sync_sock_id, (struct sockaddr *)&client_in,
- sizeof (client_in)) == -1) {
- filebench_log(LOG_ERROR, "could not bind to client socket");
- return (FILEBENCH_ERROR);
- }
-
- if (gethostbyname_r(master_name, &master_info, buffer, MCS_MSGLENGTH,
- &error_num) == NULL) {
- filebench_log(LOG_ERROR, "could not locate sync master");
- return (FILEBENCH_ERROR);
- }
-
- master_in.sin_family = AF_INET;
- master_in.sin_port = htons((uint16_t)master_port);
- (void) memcpy(&master_in.sin_addr.s_addr, *master_info.h_addr_list,
- sizeof (master_in.sin_addr.s_addr));
-
- if (connect(mc_sync_sock_id, (struct sockaddr *)&master_in,
- sizeof (master_in)) == -1) {
- filebench_log(LOG_ERROR,
- "connection refused to sync master, error %d", errno);
- return (FILEBENCH_ERROR);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Send a synchronization message and wait for a reply
- */
-int
-mc_sync_synchronize(int sync_point)
-{
- char msg[MCS_MSGLENGTH];
- int amnt;
-
- (void) snprintf(msg, MCS_MSGLENGTH,
- "cmd=SYNC,id=xyzzy,name=%s,sample=%d\n",
- this_client_name, sync_point);
- (void) send(mc_sync_sock_id, msg, strlen(msg), 0);
-
- amnt = 0;
- msg[0] = 0;
-
- while (strchr(msg, '\n') == NULL)
- amnt += recv(mc_sync_sock_id, msg, sizeof (msg), 0);
-
- filebench_log(LOG_INFO, "sync point %d succeeded!\n", sync_point);
- return (FILEBENCH_OK);
-}
diff --git a/usr/src/cmd/filebench/common/multi_client_sync.h b/usr/src/cmd/filebench/common/multi_client_sync.h
deleted file mode 100644
index 5c3961f474..0000000000
--- a/usr/src/cmd/filebench/common/multi_client_sync.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _MULTI_CLIENT_SYNC_H
-#define _MULTI_CLIENT_SYNC_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <inet/ip.h>
-
-int mc_sync_open_sock(char *master_name, int master_port, char *client_name);
-int mc_sync_synchronize(int synch_point);
-
-#endif /* _MULTI_CLIENT_SYNC_H */
diff --git a/usr/src/cmd/filebench/common/parser_gram.y b/usr/src/cmd/filebench/common/parser_gram.y
deleted file mode 100644
index c92fc93ab5..0000000000
--- a/usr/src/cmd/filebench/common/parser_gram.y
+++ /dev/null
@@ -1,4580 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-%{
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <locale.h>
-#include <sys/utsname.h>
-#include <sys/statvfs.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#ifdef HAVE_LIBTECLA
-#include <libtecla.h>
-#endif
-#include "parsertypes.h"
-#include "filebench.h"
-#include "utils.h"
-#include "stats.h"
-#include "vars.h"
-#include "eventgen.h"
-#ifdef HAVE_LIBTECLA
-#include "auto_comp.h"
-#endif
-#include "multi_client_sync.h"
-
-int dofile = FS_FALSE;
-static const char cmdname[] = "filebench";
-static const char cmd_options[] = "pa:f:hi:s:m:";
-static void usage(int);
-
-static cmd_t *cmd = NULL; /* Command being processed */
-#ifdef HAVE_LIBTECLA
-static GetLine *gl; /* GetLine resource object */
-#endif
-
-char *execname;
-char *fbbasepath = FILEBENCHDIR;
-char *fscriptname;
-int noproc = 0;
-var_t *var_list = NULL;
-pidlist_t *pidlist = NULL;
-char *cwd = NULL;
-FILE *parentscript = NULL;
-
-static int filecreate_done = 0;
-
-/* yacc externals */
-extern FILE *yyin;
-extern int yydebug;
-extern void yyerror(char *s);
-
-/* utilities */
-static void terminate(void);
-static cmd_t *alloc_cmd(void);
-static attr_t *alloc_attr(void);
-static attr_t *alloc_lvar_attr(var_t *var);
-static attr_t *get_attr(cmd_t *cmd, int64_t name);
-static attr_t *get_attr_fileset(cmd_t *cmd, int64_t name);
-static attr_t *get_attr_integer(cmd_t *cmd, int64_t name);
-static attr_t *get_attr_bool(cmd_t *cmd, int64_t name);
-static void get_attr_lvars(cmd_t *cmd, flowop_t *flowop);
-static var_t *alloc_var(void);
-static var_t *get_var(cmd_t *cmd, int64_t name);
-static list_t *alloc_list();
-static probtabent_t *alloc_probtabent(void);
-static void add_lvar_to_list(var_t *newlvar, var_t **lvar_list);
-
-/* Info Commands */
-static void parser_list(cmd_t *);
-static void parser_flowop_list(cmd_t *);
-
-/* Define Commands */
-static void parser_proc_define(cmd_t *);
-static void parser_thread_define(cmd_t *, procflow_t *, int instances);
-static void parser_flowop_define(cmd_t *, threadflow_t *, flowop_t **, int);
-static void parser_file_define(cmd_t *);
-static void parser_fileset_define(cmd_t *);
-static void parser_randvar_define(cmd_t *);
-static void parser_randvar_set(cmd_t *);
-static void parser_composite_flowop_define(cmd_t *);
-
-/* Create Commands */
-static void parser_proc_create(cmd_t *);
-static void parser_thread_create(cmd_t *);
-static void parser_flowop_create(cmd_t *);
-static void parser_fileset_create(cmd_t *);
-
-/* set commands */
-static void parser_set_integer(cmd_t *cmd);
-static void parser_set_var(cmd_t *cmd);
-static void parser_set_var_op_int(cmd_t *cmd);
-static void parser_set_int_op_var(cmd_t *cmd);
-static void parser_set_var_op_var(cmd_t *cmd);
-
-/* Shutdown Commands */
-static void parser_proc_shutdown(cmd_t *);
-static void parser_filebench_shutdown(cmd_t *cmd);
-
-/* Other Commands */
-static void parser_echo(cmd_t *cmd);
-static void parser_foreach_integer(cmd_t *cmd);
-static void parser_foreach_string(cmd_t *cmd);
-static void parser_fscheck(cmd_t *cmd);
-static void parser_fsflush(cmd_t *cmd);
-static void parser_log(cmd_t *cmd);
-static void parser_statscmd(cmd_t *cmd);
-static void parser_statsdump(cmd_t *cmd);
-static void parser_statsxmldump(cmd_t *cmd);
-static void parser_statsmultidump(cmd_t *cmd);
-static void parser_usage(cmd_t *cmd);
-static void parser_vars(cmd_t *cmd);
-static void parser_printvars(cmd_t *cmd);
-static void parser_system(cmd_t *cmd);
-static void parser_statssnap(cmd_t *cmd);
-static void parser_directory(cmd_t *cmd);
-static void parser_eventgen(cmd_t *cmd);
-static void parser_enable_mc(cmd_t *cmd);
-static void parser_domultisync(cmd_t *cmd);
-static void parser_run(cmd_t *cmd);
-static void parser_run_variable(cmd_t *cmd);
-static void parser_sleep(cmd_t *cmd);
-static void parser_sleep_variable(cmd_t *cmd);
-static void parser_warmup(cmd_t *cmd);
-static void parser_warmup_variable(cmd_t *cmd);
-static void parser_help(cmd_t *cmd);
-static void arg_parse(const char *command);
-static void parser_abort(int arg);
-static void parser_version(cmd_t *cmd);
-
-%}
-
-%union {
- int64_t ival;
- uchar_t bval;
- char * sval;
- fs_u val;
- avd_t avd;
- cmd_t *cmd;
- attr_t *attr;
- list_t *list;
- probtabent_t *rndtb;
-}
-
-%start commands
-
-%token FSC_LIST FSC_DEFINE FSC_EXEC FSC_QUIT FSC_DEBUG FSC_CREATE
-%token FSC_SLEEP FSC_STATS FSC_FOREACH FSC_SET FSC_SHUTDOWN FSC_LOG
-%token FSC_SYSTEM FSC_FLOWOP FSC_EVENTGEN FSC_ECHO FSC_LOAD FSC_RUN
-%token FSC_WARMUP FSC_NOUSESTATS FSC_FSCHECK FSC_FSFLUSH
-%token FSC_USAGE FSC_HELP FSC_VARS FSC_VERSION FSC_ENABLE FSC_DOMULTISYNC
-%token FSV_STRING FSV_VAL_INT FSV_VAL_BOOLEAN FSV_VARIABLE FSV_WHITESTRING
-%token FSV_RANDUNI FSV_RANDTAB FSV_RANDVAR FSV_URAND FSV_RAND48
-%token FST_INT FST_BOOLEAN
-%token FSE_FILE FSE_PROC FSE_THREAD FSE_CLEAR FSE_ALL FSE_SNAP FSE_DUMP
-%token FSE_DIRECTORY FSE_COMMAND FSE_FILESET FSE_XMLDUMP FSE_RAND FSE_MODE
-%token FSE_MULTI FSE_MULTIDUMP
-%token FSK_SEPLST FSK_OPENLST FSK_CLOSELST FSK_ASSIGN FSK_IN FSK_QUOTE
-%token FSK_DIRSEPLST FSK_PLUS FSK_MINUS FSK_MULTIPLY FSK_DIVIDE
-%token FSA_SIZE FSA_PREALLOC FSA_PARALLOC FSA_PATH FSA_REUSE
-%token FSA_PROCESS FSA_MEMSIZE FSA_RATE FSA_CACHED FSA_READONLY FSA_TRUSTTREE
-%token FSA_IOSIZE FSA_FILE FSA_WSS FSA_NAME FSA_RANDOM FSA_INSTANCES
-%token FSA_DSYNC FSA_TARGET FSA_ITERS FSA_NICE FSA_VALUE FSA_BLOCKING
-%token FSA_HIGHWATER FSA_DIRECTIO FSA_DIRWIDTH FSA_FD FSA_SRCFD FSA_ROTATEFD
-%token FSA_NAMELENGTH FSA_FILESIZE FSA_ENTRIES FSA_FILESIZEGAMMA FSA_DIRDEPTHRV
-%token FSA_DIRGAMMA FSA_USEISM FSA_TYPE FSA_RANDTABLE FSA_RANDSRC FSA_RANDROUND
-%token FSA_LEAFDIRS FSA_INDEXED FSA_FSTYPE
-%token FSA_RANDSEED FSA_RANDGAMMA FSA_RANDMEAN FSA_RANDMIN FSA_MASTER
-%token FSA_CLIENT
-%token FSS_TYPE FSS_SEED FSS_GAMMA FSS_MEAN FSS_MIN FSS_SRC FSS_ROUND
-%token FSV_SET_LOCAL_VAR FSA_LVAR_ASSIGN
-%token FSA_ALLDONE FSA_FIRSTDONE FSA_TIMEOUT
-
-%type <ival> FSV_VAL_INT
-%type <bval> FSV_VAL_BOOLEAN
-%type <sval> FSV_STRING
-%type <sval> FSV_WHITESTRING
-%type <sval> FSV_VARIABLE
-%type <sval> FSV_RANDVAR
-%type <sval> FSK_ASSIGN
-%type <sval> FSV_SET_LOCAL_VAR
-
-%type <ival> FSC_LIST FSC_DEFINE FSC_SET FSC_LOAD FSC_RUN FSC_ENABLE
-%type <ival> FSC_DOMULTISYNC
-%type <ival> FSE_FILE FSE_PROC FSE_THREAD FSE_CLEAR FSC_HELP FSC_VERSION
-
-%type <sval> name
-%type <ival> entity
-%type <val> value
-
-%type <cmd> command inner_commands load_command run_command list_command
-%type <cmd> proc_define_command files_define_command randvar_define_command
-%type <cmd> fo_define_command debug_command create_command
-%type <cmd> sleep_command stats_command set_command shutdown_command
-%type <cmd> foreach_command log_command system_command flowop_command
-%type <cmd> eventgen_command quit_command flowop_list thread_list
-%type <cmd> thread echo_command usage_command help_command vars_command
-%type <cmd> version_command enable_command multisync_command
-%type <cmd> warmup_command fscheck_command fsflush_command
-%type <cmd> set_integer_command set_other_command
-
-%type <attr> files_attr_op files_attr_ops pt_attr_op pt_attr_ops
-%type <attr> fo_attr_op fo_attr_ops ev_attr_op ev_attr_ops
-%type <attr> randvar_attr_op randvar_attr_ops randvar_attr_typop
-%type <attr> randvar_attr_srcop attr_value attr_list_value
-%type <attr> comp_lvar_def comp_attr_op comp_attr_ops
-%type <attr> enable_multi_ops enable_multi_op multisync_op
-%type <attr> fscheck_attr_op
-%type <list> integer_seplist string_seplist string_list var_string_list
-%type <list> var_string whitevar_string whitevar_string_list
-%type <ival> attrs_define_file attrs_define_thread attrs_flowop
-%type <ival> attrs_define_fileset attrs_define_proc attrs_eventgen attrs_define_comp
-%type <ival> files_attr_name pt_attr_name fo_attr_name ev_attr_name
-%type <ival> randvar_attr_name FSA_TYPE randtype_name randvar_attr_param
-%type <ival> randsrc_name FSA_RANDSRC randvar_attr_tsp em_attr_name
-%type <ival> FSS_TYPE FSS_SEED FSS_GAMMA FSS_MEAN FSS_MIN FSS_SRC
-%type <ival> fscheck_attr_name FSA_FSTYPE binary_op
-
-%type <rndtb> probtabentry_list probtabentry
-%type <avd> var_int_val
-%%
-
-commands: commands command
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- if ($2->cmd != NULL)
- $2->cmd($2);
-
- free($2);
-}
-| commands error
-{
- if (dofile)
- YYABORT;
-}
-|;
-
-inner_commands: command
-{
- filebench_log(LOG_DEBUG_IMPL, "inner_command %zx", $1);
- $$ = $1;
-}
-| inner_commands command
-{
- cmd_t *list = NULL;
- cmd_t *list_end = NULL;
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->cmd_next)
- list_end = list;
-
- list_end->cmd_next = $2;
-
- filebench_log(LOG_DEBUG_IMPL,
- "inner_commands adding cmd %zx to list %zx", $2, $1);
-
- $$ = $1;
-};
-
-command:
- proc_define_command
-| files_define_command
-| randvar_define_command
-| fo_define_command
-| debug_command
-| eventgen_command
-| create_command
-| echo_command
-| usage_command
-| vars_command
-| foreach_command
-| fscheck_command
-| fsflush_command
-| help_command
-| list_command
-| load_command
-| log_command
-| run_command
-| set_command
-| shutdown_command
-| sleep_command
-| warmup_command
-| stats_command
-| system_command
-| version_command
-| enable_command
-| multisync_command
-| quit_command;
-
-foreach_command: FSC_FOREACH
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- filebench_log(LOG_DEBUG_IMPL, "foreach_command %zx", $$);
-}
-| foreach_command FSV_VARIABLE FSK_IN integer_seplist FSK_OPENLST inner_commands FSK_CLOSELST
-{
- cmd_t *cmd, *inner_cmd;
- list_t *list;
-
- $$ = $1;
- $$->cmd_list = $6;
- $$->cmd_tgt1 = $2;
- $$->cmd_param_list = $4;
- $$->cmd = parser_foreach_integer;
-
- for (list = $$->cmd_param_list; list != NULL;
- list = list->list_next) {
- for (inner_cmd = $$->cmd_list;
- inner_cmd != NULL;
- inner_cmd = inner_cmd->cmd_next) {
- filebench_log(LOG_DEBUG_IMPL,
- "packing foreach: %zx %s=%llu, cmd %zx",
- $$, $$->cmd_tgt1,
- (u_longlong_t)avd_get_int(list->list_integer),
- inner_cmd);
- }
- }
-}| foreach_command FSV_VARIABLE FSK_IN string_seplist FSK_OPENLST inner_commands FSK_CLOSELST
-{
- cmd_t *cmd, *inner_cmd;
- list_t *list;
-
- $$ = $1;
- $$->cmd_list = $6;
- $$->cmd_tgt1 = $2;
- $$->cmd_param_list = $4;
- $$->cmd = parser_foreach_string;
-
- for (list = $$->cmd_param_list; list != NULL;
- list = list->list_next) {
- for (inner_cmd = $$->cmd_list;
- inner_cmd != NULL;
- inner_cmd = inner_cmd->cmd_next) {
- filebench_log(LOG_DEBUG_IMPL,
- "packing foreach: %zx %s=%s, cmd %zx",
- $$,
- $$->cmd_tgt1,
- *list->list_string, inner_cmd);
- }
- }
-};
-
-integer_seplist: FSV_VAL_INT
-{
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_integer = avd_int_alloc($1);
-}
-| integer_seplist FSK_SEPLST FSV_VAL_INT
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_integer = avd_int_alloc($3);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-};
-
-string_seplist: FSK_QUOTE FSV_WHITESTRING FSK_QUOTE
-{
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-}
-| string_seplist FSK_SEPLST FSK_QUOTE FSV_WHITESTRING FSK_QUOTE
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($4);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-};
-
-eventgen_command: FSC_EVENTGEN
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_eventgen;
-}
-| eventgen_command ev_attr_ops
-{
- $1->cmd_attr_list = $2;
-};
-
-system_command: FSC_SYSTEM whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd_param_list = $2;
- $$->cmd = parser_system;
-};
-
-echo_command: FSC_ECHO whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd_param_list = $2;
- $$->cmd = parser_echo;
-};
-
-version_command: FSC_VERSION
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_version;
-};
-
-usage_command: FSC_USAGE whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd_param_list = $2;
- $$->cmd = parser_usage;
-};
-
-vars_command: FSC_VARS
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd = parser_printvars;
-};
-
-enable_command: FSC_ENABLE FSE_MULTI
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd = parser_enable_mc;
-}
-| enable_command enable_multi_ops
-{
- $1->cmd_attr_list = $2;
-};
-
-multisync_command: FSC_DOMULTISYNC multisync_op
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd = parser_domultisync;
- $$->cmd_attr_list = $2;
-}
-
-string_list: FSV_VARIABLE
-{
- if (($$ = alloc_list()) == NULL)
- YYERROR;
- $$->list_string = avd_str_alloc($1);
-}
-| string_list FSK_SEPLST FSV_VARIABLE
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($3);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-};
-
-var_string: FSV_VARIABLE
-{
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($1);
-}
-| FSV_STRING
-{
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($1);
-};
-
-var_string_list: var_string
-{
- $$ = $1;
-}| var_string FSV_STRING
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add string */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-
-}| var_string FSV_VARIABLE
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add variable */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-} |var_string_list FSV_STRING
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add string */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-
-}| var_string_list FSV_VARIABLE
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add variable */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-};
-
-whitevar_string: FSK_QUOTE FSV_VARIABLE
-{
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-}
-| FSK_QUOTE FSV_WHITESTRING
-{
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-};
-
-whitevar_string_list: whitevar_string FSV_WHITESTRING
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add string */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-
-}| whitevar_string FSV_VARIABLE
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add variable */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-}| whitevar_string FSV_RANDVAR randvar_attr_tsp
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add variable */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
- $$->list_integer = avd_int_alloc($3);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-}| whitevar_string_list FSV_WHITESTRING
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add string */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-
-}| whitevar_string_list FSV_VARIABLE
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add variable */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-}| whitevar_string_list FSV_RANDVAR randvar_attr_tsp
-{
- list_t *list = NULL;
- list_t *list_end = NULL;
-
- /* Add variable */
- if (($$ = alloc_list()) == NULL)
- YYERROR;
-
- $$->list_string = avd_str_alloc($2);
- $$->list_integer = avd_int_alloc($3);
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->list_next)
- list_end = list;
- list_end->list_next = $$;
- $$ = $1;
-}| whitevar_string_list FSK_QUOTE
-{
- $$ = $1;
-}| whitevar_string FSK_QUOTE
-{
- $$ = $1;
-};
-
-list_command: FSC_LIST
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_list;
-}
-| list_command FSC_FLOWOP
-{
- $1->cmd = &parser_flowop_list;
-};
-
-fscheck_command: FSC_FSCHECK fscheck_attr_op
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_fscheck;
-
- $$->cmd_attr_list = $2;
-}
-| fscheck_command fscheck_attr_op
-{
- $1->cmd_attr_list->attr_next = $2;
-};
-
-fsflush_command: FSC_FSFLUSH fscheck_attr_op
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_fsflush;
-
- $$->cmd_attr_list = $2;
-};
-
-log_command: FSC_LOG whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_log;
- $$->cmd_param_list = $2;
-};
-
-debug_command: FSC_DEBUG FSV_VAL_INT
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = NULL;
- filebench_shm->shm_debug_level = $2;
- if (filebench_shm->shm_debug_level > 9)
- yydebug = 1;
-};
-
-set_command:
- set_integer_command
- | set_other_command;
-
-set_integer_command: FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_VAL_INT
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd_tgt1 = $2;
- $$->cmd_qty = $4;
- if (parentscript) {
- parser_vars($$);
- }
- $$->cmd = parser_set_integer;
-}| FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_VARIABLE
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- var_assign_var($2, $4);
- $$->cmd_tgt1 = $2;
- $$->cmd_tgt2 = $4;
- if (parentscript) {
- parser_vars($$);
- }
- $$->cmd = parser_set_var;
-}
-| set_integer_command binary_op FSV_VAL_INT
-{
- if ($1->cmd == parser_set_integer) {
- switch ($2) {
- case FSK_PLUS:
- var_assign_integer($1->cmd_tgt1, $1->cmd_qty + $3);
- break;
- case FSK_MINUS:
- var_assign_integer($1->cmd_tgt1, $1->cmd_qty - $3);
- break;
- case FSK_MULTIPLY:
- var_assign_integer($1->cmd_tgt1, $1->cmd_qty * $3);
- break;
- case FSK_DIVIDE:
- var_assign_integer($1->cmd_tgt1, $1->cmd_qty / $3);
- break;
- }
- $$->cmd = NULL;
- } else {
- $1->cmd_qty = $3;
- $1->cmd_subtype = $2;
- $1->cmd = parser_set_var_op_int;
- }
-}
-| set_integer_command binary_op FSV_VARIABLE
-{
- $1->cmd_tgt3 = $3;
- $1->cmd_subtype = $2;
- if ($1->cmd == parser_set_integer) {
- $$->cmd = parser_set_int_op_var;
- } else {
- $1->cmd = parser_set_var_op_var;
- }
-};
-
-set_other_command: FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_VAL_BOOLEAN
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- var_assign_boolean($2, $4);
- if (parentscript) {
- $$->cmd_tgt1 = $2;
- parser_vars($$);
- }
- $$->cmd = NULL;
-}
-| FSC_SET FSV_VARIABLE FSK_ASSIGN FSK_QUOTE FSV_WHITESTRING FSK_QUOTE
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- var_assign_string($2, $5);
- if (parentscript) {
- $$->cmd_tgt1 = $2;
- parser_vars($$);
- }
- $$->cmd = NULL;
-}| FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_STRING
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- var_assign_string($2, $4);
- if (parentscript) {
- $$->cmd_tgt1 = $2;
- parser_vars($$);
- }
- $$->cmd = NULL;
-} | FSC_SET FSE_MODE FSC_QUIT FSA_TIMEOUT
-{
- filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT;
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = NULL;
-} | FSC_SET FSE_MODE FSC_QUIT FSA_ALLDONE
-{
- filebench_shm->shm_rmode = FILEBENCH_MODE_QALLDONE;
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = NULL;
-} | FSC_SET FSE_MODE FSC_QUIT FSA_FIRSTDONE
-{
- filebench_shm->shm_rmode = FILEBENCH_MODE_Q1STDONE;
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = NULL;
-} | FSC_SET FSE_MODE FSC_NOUSESTATS
-{
- filebench_shm->shm_mmode |= FILEBENCH_MODE_NOUSAGE;
- filebench_log(LOG_INFO, "disabling CPU usage statistics");
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = NULL;
-} | FSC_SET FSV_RANDVAR FSS_TYPE FSK_ASSIGN randvar_attr_typop
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_randvar_set;
- $$->cmd_tgt1 = $2;
- $$->cmd_qty = FSS_TYPE;
- $$->cmd_attr_list = $5;
-
-} | FSC_SET FSV_RANDVAR FSS_SRC FSK_ASSIGN randvar_attr_srcop
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_randvar_set;
- $$->cmd_tgt1 = $2;
- $$->cmd_qty = FSS_SRC;
- $$->cmd_attr_list = $5;
-
-} | FSC_SET FSV_RANDVAR randvar_attr_param FSK_ASSIGN attr_value
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_randvar_set;
- $$->cmd_tgt1 = $2;
- $$->cmd_qty = $3;
- $$->cmd_attr_list = $5;
-
-};
-
-stats_command: FSC_STATS FSE_SNAP
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = (void (*)(struct cmd *))&parser_statssnap;
- break;
-
-}
-| FSC_STATS FSE_CLEAR
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = (void (*)(struct cmd *))&stats_clear;
-
-}
-| FSC_STATS FSE_DIRECTORY var_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd_param_list = $3;
- $$->cmd = (void (*)(struct cmd *))&parser_directory;
-
-}
-| FSC_STATS FSE_COMMAND whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd_param_list = $3;
- $$->cmd = parser_statscmd;
-
-}| FSC_STATS FSE_DUMP whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd_param_list = $3;
- $$->cmd = parser_statsdump;
-}| FSC_STATS FSE_XMLDUMP whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd_param_list = $3;
- $$->cmd = parser_statsxmldump;
-}| FSC_STATS FSE_MULTIDUMP whitevar_string_list
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- $$->cmd_param_list = $3;
- $$->cmd = parser_statsmultidump;
-};
-
-quit_command: FSC_QUIT
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_filebench_shutdown;
-};
-
-flowop_list: flowop_command
-{
- $$ = $1;
-}| flowop_list flowop_command
-{
- cmd_t *list = NULL;
- cmd_t *list_end = NULL;
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->cmd_next)
- list_end = list;
-
- list_end->cmd_next = $2;
-
- filebench_log(LOG_DEBUG_IMPL,
- "flowop_list adding cmd %zx to list %zx", $2, $1);
-
- $$ = $1;
-};
-
-thread: FSE_THREAD pt_attr_ops FSK_OPENLST flowop_list FSK_CLOSELST
-{
- /*
- * Allocate a cmd node per thread, with a
- * list of flowops attached to the cmd_list
- */
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd_list = $4;
- $$->cmd_attr_list = $2;
-};
-
-thread_list: thread
-{
- $$ = $1;
-}| thread_list thread
-{
- cmd_t *list = NULL;
- cmd_t *list_end = NULL;
-
- /* Find end of list */
- for (list = $1; list != NULL;
- list = list->cmd_next)
- list_end = list;
-
- list_end->cmd_next = $2;
-
- filebench_log(LOG_DEBUG_IMPL,
- "thread_list adding cmd %zx to list %zx", $2, $1);
-
- $$ = $1;
-};
-
-proc_define_command: FSC_DEFINE FSE_PROC pt_attr_ops FSK_OPENLST thread_list FSK_CLOSELST
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_proc_define;
- $$->cmd_list = $5;
- $$->cmd_attr_list = $3;
-
-}
-| proc_define_command pt_attr_ops
-{
- $1->cmd_attr_list = $2;
-};
-
-files_define_command: FSC_DEFINE FSE_FILE
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_file_define;
-}| FSC_DEFINE FSE_FILESET
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_fileset_define;
-}
-| files_define_command files_attr_ops
-{
- $1->cmd_attr_list = $2;
-};
-
-randvar_define_command: FSC_DEFINE FSE_RAND randvar_attr_ops
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_randvar_define;
- $$->cmd_attr_list = $3;
-};
-
-fo_define_command: FSC_DEFINE FSC_FLOWOP comp_attr_ops FSK_OPENLST flowop_list FSK_CLOSELST
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = &parser_composite_flowop_define;
- $$->cmd_list = $5;
- $$->cmd_attr_list = $3;
-}
-| fo_define_command comp_attr_ops
-{
- $1->cmd_attr_list = $2;
-};
-
-create_command: FSC_CREATE entity
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- switch ($2) {
- case FSE_PROC:
- $$->cmd = &parser_proc_create;
- break;
- case FSE_FILESET:
- case FSE_FILE:
- $$->cmd = &parser_fileset_create;
- break;
- default:
- filebench_log(LOG_ERROR, "unknown entity", $2);
- YYERROR;
- }
-
-};
-
-shutdown_command: FSC_SHUTDOWN entity
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- switch ($2) {
- case FSE_PROC:
- $$->cmd = &parser_proc_shutdown;
- break;
- case FSE_FILE:
- case FSE_FILESET:
- $$->cmd = &parser_fileset_shutdown;
- break;
- default:
- filebench_log(LOG_ERROR, "unknown entity", $2);
- YYERROR;
- }
-
-};
-
-warmup_command: FSC_WARMUP FSV_VAL_INT
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_warmup;
- $$->cmd_qty = $2;
-}
-| FSC_WARMUP FSV_VARIABLE
-{
- fbint_t *integer;
-
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_warmup_variable;
- $$->cmd_tgt1 = fb_stralloc($2);
-};
-
-sleep_command: FSC_SLEEP FSV_VAL_INT
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_sleep;
- $$->cmd_qty = $2;
-}
-| FSC_SLEEP FSV_VARIABLE
-{
- fbint_t *integer;
-
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_sleep_variable;
- $$->cmd_tgt1 = fb_stralloc($2);
-};
-
-run_command: FSC_RUN FSV_VAL_INT
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_run;
- $$->cmd_qty = $2;
-}
-| FSC_RUN FSV_VARIABLE
-{
- fbint_t *integer;
-
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_run_variable;
- $$->cmd_tgt1 = fb_stralloc($2);
-}
-| FSC_RUN
-{
- fbint_t *integer;
-
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_run;
- $$->cmd_qty = 60UL;
-};
-
-help_command: FSC_HELP
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd = parser_help;
-};
-
-flowop_command: FSC_FLOWOP name
-{
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
- $$->cmd_name = fb_stralloc($2);
-}
-| flowop_command fo_attr_ops
-{
- $1->cmd_attr_list = $2;
-};
-
-load_command: FSC_LOAD FSV_STRING
-{
- FILE *newfile;
- char loadfile[128];
-
- if (($$ = alloc_cmd()) == NULL)
- YYERROR;
-
- (void) strcpy(loadfile, $2);
- (void) strcat(loadfile, ".f");
-
- if ((newfile = fopen(loadfile, "r")) == NULL) {
- (void) strcpy(loadfile, fbbasepath);
- (void) strcat(loadfile, "/workloads/");
- (void) strcat(loadfile, $2);
- (void) strcat(loadfile, ".f");
- if ((newfile = fopen(loadfile, "r")) == NULL) {
- filebench_log(LOG_ERROR, "Cannot open %s", loadfile);
- YYERROR;
- }
- }
-
- parentscript = yyin;
- yyin = newfile;
- yy_switchfileparent(yyin);
-};
-
-
-entity: FSE_PROC {$$ = FSE_PROC;}
-| FSE_THREAD {$$ = FSE_THREAD;}
-| FSE_FILESET {$$ = FSE_FILESET;}
-| FSE_FILE {$$ = FSE_FILE;};
-
-value: FSV_VAL_INT { $$.i = $1;}
-| FSV_STRING { $$.s = $1;}
-| FSV_VAL_BOOLEAN { $$.b = $1;};
-
-name: FSV_STRING;
-
-/* attribute parsing for define file and define fileset */
-files_attr_ops: files_attr_op
-{
- $$ = $1;
-}
-| files_attr_ops FSK_SEPLST files_attr_op
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-};
-
-files_attr_op: files_attr_name FSK_ASSIGN attr_list_value
-{
- $$ = $3;
- $$->attr_name = $1;
-}
-| files_attr_name
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_name = $1;
-};
-
-/* attribute parsing for random variables */
-randvar_attr_ops: randvar_attr_op
-{
- $$ = $1;
-}
-| randvar_attr_ops FSK_SEPLST randvar_attr_op
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-}
-| randvar_attr_ops FSK_SEPLST FSA_RANDTABLE FSK_ASSIGN FSK_OPENLST probtabentry_list FSK_CLOSELST
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
-
- if ((attr = alloc_attr()) == NULL)
- YYERROR;
-
- attr->attr_name = FSA_RANDTABLE;
- attr->attr_obj = (void *)$6;
- list_end->attr_next = attr;
- $$ = $1;
-};
-
-randvar_attr_op: randvar_attr_name FSK_ASSIGN attr_list_value
-{
- $$ = $3;
- $$->attr_name = $1;
-}
-| randvar_attr_name
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_name = $1;
-}
-| FSA_TYPE FSK_ASSIGN randvar_attr_typop
-{
- $$ = $3;
- $$->attr_name = FSA_TYPE;
-}
-| FSA_RANDSRC FSK_ASSIGN randvar_attr_srcop
-{
- $$ = $3;
- $$->attr_name = FSA_RANDSRC;
-};
-
-probtabentry: FSK_OPENLST var_int_val FSK_SEPLST var_int_val FSK_SEPLST var_int_val FSK_CLOSELST
-{
- if (($$ = alloc_probtabent()) == NULL)
- YYERROR;
- $$->pte_percent = $2;
- $$->pte_segmin = $4;
- $$->pte_segmax = $6;
-};
-
-/* attribute parsing for prob density function table */
-probtabentry_list: probtabentry
-{
- $$ = $1;
-}
-| probtabentry_list FSK_SEPLST probtabentry
-{
- probtabent_t *pte = NULL;
- probtabent_t *ptelist_end = NULL;
-
- for (pte = $1; pte != NULL;
- pte = pte->pte_next)
- ptelist_end = pte; /* Find end of prob table entry list */
-
- ptelist_end->pte_next = $3;
-
- $$ = $1;
-};
-
-/* attribute parsing for define thread and process */
-pt_attr_ops: pt_attr_op
-{
- $$ = $1;
-}
-| pt_attr_ops FSK_SEPLST pt_attr_op
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-};
-
-pt_attr_op: pt_attr_name FSK_ASSIGN attr_value
-{
- $$ = $3;
- $$->attr_name = $1;
-}
-| pt_attr_name
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_name = $1;
-};
-
-/* attribute parsing for flowops */
-fo_attr_ops: fo_attr_op
-{
- $$ = $1;
-}
-| fo_attr_ops FSK_SEPLST fo_attr_op
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-}
-| fo_attr_ops FSK_SEPLST comp_lvar_def
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-};
-
-fo_attr_op: fo_attr_name FSK_ASSIGN attr_value
-{
- $$ = $3;
- $$->attr_name = $1;
-}
-| fo_attr_name
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_name = $1;
-};
-
-/* attribute parsing for Event Generator */
-ev_attr_ops: ev_attr_op
-{
- $$ = $1;
-}
-| ev_attr_ops FSK_SEPLST ev_attr_op
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-};
-
-ev_attr_op: ev_attr_name FSK_ASSIGN attr_value
-{
- $$ = $3;
- $$->attr_name = $1;
-}
-| ev_attr_name
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_name = $1;
-};
-
-/* attribute parsing for enable multiple client command */
-enable_multi_ops: enable_multi_op
-{
- $$ = $1;
-}
-| enable_multi_ops FSK_SEPLST enable_multi_op
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-};
-
-enable_multi_op: em_attr_name FSK_ASSIGN attr_value
-{
- $$ = $3;
- $$->attr_name = $1;
-};
-
-multisync_op: FSA_VALUE FSK_ASSIGN attr_value
-{
- $$ = $3;
- $$->attr_name = FSA_VALUE;
-};
-
-fscheck_attr_op: fscheck_attr_name FSK_ASSIGN FSV_STRING
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_str_alloc($3);
- $$->attr_name = $1;
-};
-
-binary_op:
- FSK_PLUS {$$ = FSK_PLUS;}
- | FSK_MINUS {$$ = FSK_MINUS;}
- | FSK_MULTIPLY {$$ = FSK_MULTIPLY;}
- | FSK_DIVIDE {$$ = FSK_DIVIDE;};
-
-files_attr_name: attrs_define_file
-|attrs_define_fileset;
-
-pt_attr_name: attrs_define_thread
-|attrs_define_proc;
-
-fo_attr_name: attrs_flowop;
-
-ev_attr_name: attrs_eventgen;
-
-attrs_define_proc:
- FSA_NICE { $$ = FSA_NICE;}
-| FSA_NAME { $$ = FSA_NAME;}
-| FSA_INSTANCES { $$ = FSA_INSTANCES;};
-
-attrs_define_file:
- FSA_SIZE { $$ = FSA_SIZE;}
-| FSA_NAME { $$ = FSA_NAME;}
-| FSA_PATH { $$ = FSA_PATH;}
-| FSA_READONLY { $$ = FSA_READONLY;}
-| FSA_TRUSTTREE { $$ = FSA_TRUSTTREE;}
-| FSA_REUSE { $$ = FSA_REUSE;}
-| FSA_PREALLOC { $$ = FSA_PREALLOC;}
-| FSA_PARALLOC { $$ = FSA_PARALLOC;};
-
-attrs_define_fileset:
- FSA_SIZE { $$ = FSA_SIZE;}
-| FSA_NAME { $$ = FSA_NAME;}
-| FSA_PATH { $$ = FSA_PATH;}
-| FSA_DIRWIDTH { $$ = FSA_DIRWIDTH;}
-| FSA_DIRDEPTHRV { $$ = FSA_DIRDEPTHRV;}
-| FSA_PREALLOC { $$ = FSA_PREALLOC;}
-| FSA_PARALLOC { $$ = FSA_PARALLOC;}
-| FSA_REUSE { $$ = FSA_REUSE;}
-| FSA_READONLY { $$ = FSA_READONLY;}
-| FSA_TRUSTTREE { $$ = FSA_TRUSTTREE;}
-| FSA_FILESIZEGAMMA { $$ = FSA_FILESIZEGAMMA;}
-| FSA_DIRGAMMA { $$ = FSA_DIRGAMMA;}
-| FSA_CACHED { $$ = FSA_CACHED;}
-| FSA_ENTRIES { $$ = FSA_ENTRIES;}
-| FSA_LEAFDIRS { $$ = FSA_LEAFDIRS;};
-
-randvar_attr_name:
- FSA_NAME { $$ = FSA_NAME;}
-| FSA_RANDSEED { $$ = FSA_RANDSEED;}
-| FSA_RANDGAMMA { $$ = FSA_RANDGAMMA;}
-| FSA_RANDMEAN { $$ = FSA_RANDMEAN;}
-| FSA_RANDMIN { $$ = FSA_RANDMIN;}
-| FSA_RANDROUND { $$ = FSA_RANDROUND;};
-
-randvar_attr_tsp:
- FSS_TYPE { $$ = FSS_TYPE;}
-| FSS_SRC { $$ = FSS_SRC;}
-| FSS_SEED { $$ = FSS_SEED;}
-| FSS_GAMMA { $$ = FSS_GAMMA;}
-| FSS_MEAN { $$ = FSS_MEAN;}
-| FSS_MIN { $$ = FSS_MIN;}
-| FSS_ROUND { $$ = FSS_ROUND;};
-
-
-randvar_attr_param:
- FSS_SEED { $$ = FSS_SEED;}
-| FSS_GAMMA { $$ = FSS_GAMMA;}
-| FSS_MEAN { $$ = FSS_MEAN;}
-| FSS_MIN { $$ = FSS_MIN;}
-| FSS_ROUND { $$ = FSS_ROUND;};
-
-randvar_attr_typop: randtype_name
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_int_alloc($1);
-};
-
-randtype_name:
- FSV_RANDUNI { $$ = FSV_RANDUNI;}
-| FSV_RANDTAB { $$ = FSV_RANDTAB;}
-| FSA_RANDGAMMA { $$ = FSA_RANDGAMMA;};
-
-randvar_attr_srcop: randsrc_name
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_int_alloc($1);
-};
-
-randsrc_name:
- FSV_URAND { $$ = FSV_URAND;}
-| FSV_RAND48 { $$ = FSV_RAND48;};
-
-attrs_define_thread:
- FSA_PROCESS { $$ = FSA_PROCESS;}
-| FSA_NAME { $$ = FSA_NAME;}
-| FSA_MEMSIZE { $$ = FSA_MEMSIZE;}
-| FSA_USEISM { $$ = FSA_USEISM;}
-| FSA_INSTANCES { $$ = FSA_INSTANCES;};
-
-attrs_flowop:
- FSA_WSS { $$ = FSA_WSS;}
-| FSA_FILE { $$ = FSA_FILE;}
-| FSA_NAME { $$ = FSA_NAME;}
-| FSA_RANDOM { $$ = FSA_RANDOM;}
-| FSA_FD { $$ = FSA_FD;}
-| FSA_SRCFD { $$ = FSA_SRCFD;}
-| FSA_ROTATEFD { $$ = FSA_ROTATEFD;}
-| FSA_DSYNC { $$ = FSA_DSYNC;}
-| FSA_DIRECTIO { $$ = FSA_DIRECTIO;}
-| FSA_INDEXED { $$ = FSA_INDEXED;}
-| FSA_TARGET { $$ = FSA_TARGET;}
-| FSA_ITERS { $$ = FSA_ITERS;}
-| FSA_VALUE { $$ = FSA_VALUE;}
-| FSA_BLOCKING { $$ = FSA_BLOCKING;}
-| FSA_HIGHWATER { $$ = FSA_HIGHWATER;}
-| FSA_IOSIZE { $$ = FSA_IOSIZE;};
-
-attrs_eventgen:
- FSA_RATE { $$ = FSA_RATE;};
-
-em_attr_name:
- FSA_MASTER { $$ = FSA_MASTER;}
-| FSA_CLIENT { $$ = FSA_CLIENT;};
-
-fscheck_attr_name:
- FSA_PATH { $$ = FSA_PATH;}
-| FSA_FSTYPE { $$ = FSA_FSTYPE;};
-
-comp_attr_ops: comp_attr_op
-{
- $$ = $1;
-}
-| comp_attr_ops FSK_SEPLST comp_attr_op
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-}
-| comp_attr_ops FSK_SEPLST comp_lvar_def
-{
- attr_t *attr = NULL;
- attr_t *list_end = NULL;
-
- for (attr = $1; attr != NULL;
- attr = attr->attr_next)
- list_end = attr; /* Find end of list */
-
- list_end->attr_next = $3;
-
- $$ = $1;
-};
-
-comp_attr_op: attrs_define_comp FSK_ASSIGN attr_value
-{
- $$ = $3;
- $$->attr_name = $1;
-};
-
-comp_lvar_def: FSV_VARIABLE FSK_ASSIGN FSV_VAL_BOOLEAN
-{
- if (($$ = alloc_lvar_attr(var_lvar_assign_boolean($1, $3))) == NULL)
- YYERROR;
-}
-| FSV_VARIABLE FSK_ASSIGN FSV_VAL_INT
-{
- if (($$ = alloc_lvar_attr(var_lvar_assign_integer($1, $3))) == NULL)
- YYERROR;
-}
-| FSV_VARIABLE FSK_ASSIGN FSK_QUOTE FSV_WHITESTRING FSK_QUOTE
-{
- if (($$ = alloc_lvar_attr(var_lvar_assign_string($1, $4))) == NULL)
- YYERROR;
-}
-| FSV_VARIABLE FSK_ASSIGN FSV_STRING
-{
- if (($$ = alloc_lvar_attr(var_lvar_assign_string($1, $3))) == NULL)
- YYERROR;
-}
-| FSV_VARIABLE FSK_ASSIGN FSV_VARIABLE
-{
- if (($$ = alloc_lvar_attr(var_lvar_assign_var($1, $3))) == NULL)
- YYERROR;
-}
-| FSV_VARIABLE
-{
- if (($$ = alloc_lvar_attr(var_lvar_alloc_local($1))) == NULL)
- YYERROR;
-};
-
-
-attrs_define_comp:
- FSA_NAME { $$ = FSA_NAME;}
-| FSA_ITERS { $$ = FSA_ITERS;};
-
-attr_value: FSV_STRING
-{
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_str_alloc($1);
-} | FSV_VAL_INT {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_int_alloc($1);
-} | FSV_VAL_BOOLEAN {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_bool_alloc($1);
-} | FSV_VARIABLE {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = var_ref_attr($1);
-};
-
-attr_list_value: var_string_list {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_param_list = $1;
-} | FSV_STRING {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_str_alloc($1);
-} | FSV_VAL_INT {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_int_alloc($1);
-} | FSV_VAL_BOOLEAN {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = avd_bool_alloc($1);
-} | FSV_VARIABLE {
- if (($$ = alloc_attr()) == NULL)
- YYERROR;
- $$->attr_avd = var_ref_attr($1);
-};
-
-var_int_val: FSV_VAL_INT
-{
- $$ = avd_int_alloc($1);
-} | FSV_VARIABLE
-{
- $$ = var_ref_attr($1);
-};
-
-%%
-
-/*
- * The following 'c' routines implement the various commands defined in the
- * above yacc parser code. The yacc portion checks the syntax of the commands
- * found in a workload file, or typed on interactive command lines, parsing
- * the commands' parameters into lists. The lists are then passed in a cmd_t
- * struct for each command to its related routine in the following section
- * for actual execution. This section also includes a few utility routines
- * and the main entry point for the program.
- */
-
-/*
- * Entry point for filebench. Processes command line arguements. The -f
- * option will read in a workload file (the full name and extension must
- * must be given). The -a, -s, -m and -i options are used by worker process
- * to receive their name, the base address of shared memory, its path, and
- * the process' instance number, respectively. This information is supplied
- * by the master process when it execs worker processes under the process
- * model of execution. If the worker process arguments are passed then main
- * will call the procflow_exec routine which creates worker threadflows and
- * flowops and executes the procflow's portion of the workload model until
- * completion. If worker process arguments are not passed to the process,
- * then it becomes the master process for a filebench run. It initializes
- * the various filebench components and either executes the supplied workload
- * file, or enters interactive mode.
- */
-
-int
-main(int argc, char *argv[])
-{
- int opt;
- int docmd = FS_FALSE;
- int instance;
- char procname[128];
- caddr_t shmaddr;
- char dir[MAXPATHLEN];
-#ifdef HAVE_SETRLIMIT
- struct rlimit rlp;
-#endif
-#ifdef HAVE_LIBTECLA
- char *line;
-#else
- char line[1024];
-#endif
- char shmpathtmp[1024];
-
-#ifdef HAVE_SETRLIMIT
- /* Set resource limits */
- (void) getrlimit(RLIMIT_NOFILE, &rlp);
- rlp.rlim_cur = rlp.rlim_max;
- setrlimit(RLIMIT_NOFILE, &rlp);
-#endif
-
- yydebug = 0;
- execname = argv[0];
- *procname = 0;
- cwd = getcwd(dir, MAXPATHLEN);
-
- while ((opt = getopt(argc, argv, cmd_options)) != (int)EOF) {
-
- switch (opt) {
- case 'h':
- usage(2);
- break;
-
- case 'p':
- noproc = 1;
- break;
-
- case 'f':
- if (optarg == NULL)
- usage(1);
- if ((yyin = fopen(optarg, "r")) == NULL) {
- (void) fprintf(stderr,
- "Cannot open file %s", optarg);
- exit(1);
- }
- dofile = FS_TRUE;
- fscriptname = optarg;
-
- break;
-
- case 'a':
- if (optarg == NULL)
- usage(1);
- sscanf(optarg, "%s", &procname[0]);
- break;
-
- case 's':
- if (optarg == NULL)
- usage(1);
-#if defined(_LP64) || (__WORDSIZE == 64)
- sscanf(optarg, "%llx", &shmaddr);
-#else
- sscanf(optarg, "%x", &shmaddr);
-#endif
- break;
-
- case 'm':
- if (optarg == NULL)
- usage(1);
- sscanf(optarg, "%s", shmpathtmp);
- shmpath = shmpathtmp;
- break;
-
- case 'i':
- if (optarg == NULL)
- usage(1);
- sscanf(optarg, "%d", &instance);
- break;
-
- case '?':
- default:
- usage(1);
- break;
- }
- }
-
-#ifdef USE_PROCESS_MODEL
- if (!(*procname))
-#endif
- printf("FileBench Version %s\n", FILEBENCH_VERSION);
- filebench_init();
-
- /* get process pid for use with message logging */
- my_pid = getpid();
-
-#ifdef USE_PROCESS_MODEL
- if (*procname) {
- /* A child FileBench instance */
- if (ipc_attach(shmaddr) < 0) {
- filebench_log(LOG_ERROR, "Cannot attach shm for %s",
- procname);
- exit(1);
- }
-
- /* get correct function pointer for each child process */
- filebench_plugin_funcvecinit();
-
- if (procflow_exec(procname, instance) < 0) {
- filebench_log(LOG_ERROR, "Cannot startup process %s",
- procname);
- exit(1);
- }
-
- exit(0);
- }
-#endif
-
- /* master (or only) process */
- ipc_init();
-
- if (fscriptname)
- (void) strcpy(filebench_shm->shm_fscriptname, fscriptname);
-
- filebench_plugin_funcvecinit();
- flowop_init();
- stats_init();
- eventgen_init();
-
- signal(SIGINT, parser_abort);
-
- if (dofile)
- yyparse();
- else {
-#ifdef HAVE_LIBTECLA
- if ((gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL) {
- filebench_log(LOG_ERROR,
- "Failed to create GetLine object");
- filebench_shutdown(1);
- }
-
- if (gl_customize_completion(gl, NULL, command_complete)) {
- filebench_log(LOG_ERROR,
- "Failed to register auto-completion function");
- filebench_shutdown(1);
- }
-
- while (line = gl_get_line(gl, FILEBENCH_PROMPT, NULL, -1)) {
- arg_parse(line);
- yyparse();
- }
-
- del_GetLine(gl);
-#else
- while (!feof(stdin)) {
- printf(FILEBENCH_PROMPT);
- fflush(stdout);
- if (fgets(line, sizeof (line), stdin) == NULL) {
- if (errno == EINTR)
- continue;
- else
- break;
- }
- arg_parse(line);
- yyparse();
- }
- printf("\n");
-#endif /* HAVE_LIBTECLA */
- }
-
- parser_filebench_shutdown((cmd_t *)0);
-
- return (0);
-}
-
-/*
- * arg_parse() puts the parser into command parsing mode. Create a tmpfile
- * and instruct the parser to read instructions from this location by setting
- * yyin to the value returned by tmpfile. Write the command into the file.
- * Then seek back to to the start of the file so that the parser can read
- * the instructions.
- */
-static void
-arg_parse(const char *command)
-{
- if ((yyin = tmpfile()) == NULL) {
- filebench_log(LOG_FATAL,
- "Exiting: Cannot create tmpfile: %s", strerror(errno));
- exit(1);
- }
-
- if (fwrite(command, strlen(command), 1, yyin) != 1)
- filebench_log(LOG_FATAL,
- "Cannot write tmpfile: %s", strerror(errno));
-
- if (fseek(yyin, 0, SEEK_SET) != 0)
- filebench_log(LOG_FATAL,
- "Cannot seek tmpfile: %s", strerror(errno));
-}
-
-/*
- * Converts a list of var_strings or ordinary strings to a single ordinary
- * string. It returns a pointer to the string (in malloc'd memory) if found,
- * or NULL otherwise.
- */
-char *
-parser_list2string(list_t *list)
-{
- list_t *l;
- char *string;
- char *tmp;
- fbint_t *integer;
- if ((string = malloc(MAXPATHLEN)) == NULL) {
- filebench_log(LOG_ERROR, "Failed to allocate memory");
- return (NULL);
- }
-
- *string = 0;
-
- /* printf("parser_list2string: called\n"); */
- /* Format args */
- for (l = list; l != NULL; l = l->list_next) {
- char *lstr = avd_get_str(l->list_string);
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "converting string '%s'", lstr);
-
- /* see if it is a random variable */
- if (l->list_integer) {
- fbint_t param_name;
-
- tmp = NULL;
- param_name = avd_get_int(l->list_integer);
- switch (param_name) {
- case FSS_TYPE:
- tmp = var_randvar_to_string(lstr,
- RAND_PARAM_TYPE);
- break;
-
- case FSS_SRC:
- tmp = var_randvar_to_string(lstr,
- RAND_PARAM_SRC);
- break;
-
- case FSS_SEED:
- tmp = var_randvar_to_string(lstr,
- RAND_PARAM_SEED);
- break;
-
- case FSS_MIN:
- tmp = var_randvar_to_string(lstr,
- RAND_PARAM_MIN);
- break;
-
- case FSS_MEAN:
- tmp = var_randvar_to_string(lstr,
- RAND_PARAM_MEAN);
- break;
-
- case FSS_GAMMA:
- tmp = var_randvar_to_string(lstr,
- RAND_PARAM_GAMMA);
- break;
-
- case FSS_ROUND:
- tmp = var_randvar_to_string(lstr,
- RAND_PARAM_ROUND);
- break;
- }
-
- if (tmp) {
- (void) strcat(string, tmp);
- free(tmp);
- } else {
- (void) strcat(string, lstr);
- }
- } else {
- /* perhaps a normal variable? */
- if ((tmp = var_to_string(lstr)) != NULL) {
- (void) strcat(string, tmp);
- free(tmp);
- } else {
- (void) strcat(string, lstr);
- }
- }
- }
- return (string);
-}
-
-/*
- * If the list just contains a single string starting with '$', then find
- * or create the named var and return the var's var_string component.
- * Otherwise, convert the list to a string, and allocate a var_string
- * containing a copy of that string. On failure either returns NULL
- * or shuts down the run.
- */
-avd_t
-parser_list2varstring(list_t *list)
-{
- char *lstr = avd_get_str(list->list_string);
-
- /* printf("parser_list2varstring: Called\n"); */
- /* Special case - variable name */
- if ((list->list_next == NULL) && (*lstr == '$'))
- return (var_ref_attr(lstr));
-
- return (avd_str_alloc(parser_list2string(list)));
-}
-
-/*
- * Looks for the var named in list_string of the first element of the
- * supplied list. If found, returns the var_val portion of the var in
- * an attribute value descriptor. If the var is not found, cannot be
- * allocated, the supplied list is NULL, or the list_string filed is
- * empty, returns NULL.
- */
-avd_t
-parser_list2avd(list_t *list)
-{
- avd_t avd;
- char *lstr;
-
- if (list && ((lstr = avd_get_str(list->list_string)) != NULL)) {
- avd = var_ref_attr(lstr);
- return (avd);
- }
-
- return (NULL);
-}
-
-/*
- * Sets the event generator rate from the attribute supplied with the
- * command. If the attribute doesn't exist the routine does nothing.
- */
-static void
-parser_eventgen(cmd_t *cmd)
-{
- attr_t *attr;
-
- /* Get the rate from attribute */
- if (attr = get_attr_integer(cmd, FSA_RATE)) {
- if (attr->attr_avd) {
- eventgen_setrate(attr->attr_avd);
- }
- }
-}
-
-/*
- * Assigns the designated integer variable successive values from the
- * supplied comma seperated integer list. After each successive integer
- * assignment, it executes the bracket enclosed list of commands. For
- * example, repeated runs of a workload with increasing io sizes can
- * be done using the following command line:
- * foreach $iosize in 2k, 4k, 8k {run 60}
- */
-static void
-parser_foreach_integer(cmd_t *cmd)
-{
- list_t *list = cmd->cmd_param_list;
- cmd_t *inner_cmd;
-
- for (; list != NULL; list = list->list_next) {
- fbint_t list_int = avd_get_int(list->list_integer);
-
- var_assign_integer(cmd->cmd_tgt1, list_int);
- filebench_log(LOG_VERBOSE, "Iterating %s=%llu",
- cmd->cmd_tgt1, (u_longlong_t)list_int);
- for (inner_cmd = cmd->cmd_list; inner_cmd != NULL;
- inner_cmd = inner_cmd->cmd_next) {
- inner_cmd->cmd(inner_cmd);
- }
- }
-}
-
-/*
- * Similar to parser_foreach_integer(), except takes a list of strings after
- * the "in" token. For example, to run twice using a different directory,
- * perhaps using a different filesystem, the following command line
- * could be used:
- * foreach $dir in "/ufs_top/fbt", "/zfs_top/fbt" {run 60)
- */
-static void
-parser_foreach_string(cmd_t *cmd)
-{
- list_t *list = cmd->cmd_param_list;
-
- for (; list != NULL; list = list->list_next) {
- cmd_t *inner_cmd;
- char *lstr = avd_get_str(list->list_string);
- var_assign_string(cmd->cmd_tgt1, lstr);
- filebench_log(LOG_VERBOSE, "Iterating %s=%s",
- cmd->cmd_tgt1, lstr);
- for (inner_cmd = cmd->cmd_list; inner_cmd != NULL;
- inner_cmd = inner_cmd->cmd_next) {
- inner_cmd->cmd(inner_cmd);
- }
- }
-}
-
-/*
- * Lists the fileset name, path name and average size for all defined
- * filesets.
- */
-static void
-parser_list(cmd_t *cmd)
-{
- (void) fileset_iter(fileset_print);
-}
-
-/*
- * Lists the flowop name and instance number for all flowops.
- */
-static void
-parser_flowop_list(cmd_t *cmd)
-{
- flowop_printall();
-}
-
-/*
- * Calls procflow_define() to allocate "instances" number of procflow(s)
- * (processes) with the supplied name. The default number of instances is
- * one. An optional priority level attribute can be supplied and is stored in
- * pf_nice. Finally the routine loops through the list of inner commands, if
- * any, which are defines for threadflows, and passes them one at a time to
- * parser_thread_define() to allocate threadflow entities for the process(es).
- */
-static void
-parser_proc_define(cmd_t *cmd)
-{
- procflow_t *procflow, template;
- char *name;
- attr_t *attr;
- avd_t var_instances;
- fbint_t instances;
- cmd_t *inner_cmd;
-
- /* Get the name of the process */
- if (attr = get_attr(cmd, FSA_NAME)) {
- name = avd_get_str(attr->attr_avd);
- } else {
- filebench_log(LOG_ERROR,
- "define proc: proc specifies no name");
- filebench_shutdown(1);
- }
-
- /* Get the memory size from attribute */
- if (attr = get_attr_integer(cmd, FSA_INSTANCES)) {
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "proc_define: Instances attr cannot be random");
- filebench_shutdown(1);
- }
- var_instances = attr->attr_avd;
- instances = avd_get_int(var_instances);
- filebench_log(LOG_DEBUG_IMPL,
- "Setting instances = %llu", (u_longlong_t)instances);
- } else {
- filebench_log(LOG_DEBUG_IMPL,
- "Defaulting to instances = 1");
- var_instances = avd_int_alloc(1);
- instances = 1;
- }
-
- if ((procflow = procflow_define(name, NULL, var_instances)) == NULL) {
- filebench_log(LOG_ERROR,
- "Failed to instantiate %d %s process(es)\n",
- instances, name);
- filebench_shutdown(1);
- }
-
- /* Get the pri from attribute */
- if (attr = get_attr_integer(cmd, FSA_NICE)) {
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "proc_define: priority cannot be random");
- filebench_shutdown(1);
- }
- filebench_log(LOG_DEBUG_IMPL, "Setting pri = %llu",
- (u_longlong_t)avd_get_int(attr->attr_avd));
- procflow->pf_nice = attr->attr_avd;
- } else
- procflow->pf_nice = avd_int_alloc(0);
-
-
- /* Create the list of threads for this process */
- for (inner_cmd = cmd->cmd_list; inner_cmd != NULL;
- inner_cmd = inner_cmd->cmd_next) {
- parser_thread_define(inner_cmd, procflow, instances);
- }
-}
-
-/*
- * Calls threadflow_define() to allocate "instances" number of threadflow(s)
- * (threads) with the supplied name. The default number of instances is
- * one. Two other optional attributes may be supplied, one to set the memory
- * size, stored in tf_memsize, and to select the use of Interprocess Shared
- * Memory, which sets the THREADFLOW_USEISM flag in tf_attrs. Finally
- * the routine loops through the list of inner commands, if any, which are
- * defines for flowops, and passes them one at a time to
- * parser_flowop_define() to allocate flowop entities for the threadflows.
- */
-static void
-parser_thread_define(cmd_t *cmd, procflow_t *procflow, int procinstances)
-{
- threadflow_t *threadflow, template;
- attr_t *attr;
- avd_t instances;
- cmd_t *inner_cmd;
- char *name;
-
- memset(&template, 0, sizeof (threadflow_t));
-
- /* Get the name of the thread */
- if (attr = get_attr(cmd, FSA_NAME)) {
- name = avd_get_str(attr->attr_avd);
- } else {
- filebench_log(LOG_ERROR,
- "define thread: thread in process %s specifies no name",
- procflow->pf_name);
- filebench_shutdown(1);
- }
-
- /* Get the number of instances from attribute */
- if (attr = get_attr_integer(cmd, FSA_INSTANCES)) {
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "define thread: Instances attr cannot be random");
- filebench_shutdown(1);
- }
- filebench_log(LOG_DEBUG_IMPL,
- "define thread: Setting instances = %llu",
- (u_longlong_t)avd_get_int(attr->attr_avd));
- instances = attr->attr_avd;
- } else
- instances = avd_int_alloc(1);
-
- /* Get the memory size from attribute */
- if (attr = get_attr_integer(cmd, FSA_MEMSIZE)) {
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "define thread: Memory size cannot be random");
- filebench_shutdown(1);
- }
- filebench_log(LOG_DEBUG_IMPL,
- "define thread: Setting memsize = %llu",
- (u_longlong_t)avd_get_int(attr->attr_avd));
- template.tf_memsize = attr->attr_avd;
- } else
- template.tf_memsize = avd_int_alloc(0);
-
- if ((threadflow = threadflow_define(procflow, name,
- &template, instances)) == NULL) {
- filebench_log(LOG_ERROR,
- "define thread: Failed to instantiate thread\n");
- filebench_shutdown(1);
- }
-
- /* Use ISM Memory? */
- if (attr = get_attr(cmd, FSA_USEISM)) {
- threadflow->tf_attrs |= THREADFLOW_USEISM;
- }
-
- /* Create the list of flowops */
- for (inner_cmd = cmd->cmd_list; inner_cmd != NULL;
- inner_cmd = inner_cmd->cmd_next) {
- parser_flowop_define(inner_cmd, threadflow,
- &threadflow->tf_thrd_fops, FLOW_MASTER);
- }
-}
-
-/*
- * Fills in the attributes for a newly allocated flowop
- */
-static void
-parser_flowop_get_attrs(cmd_t *cmd, flowop_t *flowop)
-{
- attr_t *attr;
-
- /* Get the filename from attribute */
- if (attr = get_attr(cmd, FSA_FILE)) {
- flowop->fo_filename = attr->attr_avd;
- if (flowop->fo_filename == NULL) {
- filebench_log(LOG_ERROR,
- "define flowop: no filename specfied");
- filebench_shutdown(1);
- }
- } else {
- /* no filename attribute specified */
- flowop->fo_filename = NULL;
- }
-
- /* Get the iosize of the op */
- if (attr = get_attr_integer(cmd, FSA_IOSIZE))
- flowop->fo_iosize = attr->attr_avd;
- else
- flowop->fo_iosize = avd_int_alloc(0);
-
- /* Get the working set size of the op */
- if (attr = get_attr_integer(cmd, FSA_WSS))
- flowop->fo_wss = attr->attr_avd;
- else
- flowop->fo_wss = avd_int_alloc(0);
-
- /* Random I/O? */
- if (attr = get_attr_bool(cmd, FSA_RANDOM))
- flowop->fo_random = attr->attr_avd;
- else
- flowop->fo_random = avd_bool_alloc(FALSE);
-
- /* Sync I/O? */
- if (attr = get_attr_bool(cmd, FSA_DSYNC))
- flowop->fo_dsync = attr->attr_avd;
- else
- flowop->fo_dsync = avd_bool_alloc(FALSE);
-
- /* Target, for wakeup etc */
- if (attr = get_attr(cmd, FSA_TARGET))
- (void) strcpy(flowop->fo_targetname,
- avd_get_str(attr->attr_avd));
-
- /* Value */
- if (attr = get_attr_integer(cmd, FSA_VALUE))
- flowop->fo_value = attr->attr_avd;
- else
- flowop->fo_value = avd_int_alloc(0);
-
- /* FD */
- if (attr = get_attr_integer(cmd, FSA_FD)) {
- flowop->fo_fdnumber = avd_get_int(attr->attr_avd);
- if (flowop->fo_filename != NULL)
- filebench_log(LOG_DEBUG_SCRIPT, "It is not "
- "advisable to supply both an fd number "
- "and a fileset name in most cases");
- }
-
- /* Rotatefd? */
- if (attr = get_attr_bool(cmd, FSA_ROTATEFD))
- flowop->fo_rotatefd = attr->attr_avd;
- else
- flowop->fo_rotatefd = avd_bool_alloc(FALSE);
-
- /* SRC FD, for copies etc... */
- if (attr = get_attr_integer(cmd, FSA_SRCFD))
- flowop->fo_srcfdnumber = avd_get_int(attr->attr_avd);
-
- /* Blocking operation? */
- if (attr = get_attr_bool(cmd, FSA_BLOCKING))
- flowop->fo_blocking = attr->attr_avd;
- else
- flowop->fo_blocking = avd_bool_alloc(FALSE);
-
- /* Direct I/O Operation */
- if (attr = get_attr_bool(cmd, FSA_DIRECTIO))
- flowop->fo_directio = attr->attr_avd;
- else
- flowop->fo_directio = avd_bool_alloc(FALSE);
-
- /* Highwater mark */
- if (attr = get_attr_integer(cmd, FSA_HIGHWATER)) {
- flowop->fo_highwater = attr->attr_avd;
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "define flowop: Highwater attr cannot be random");
- filebench_shutdown(1);
- }
- } else {
- flowop->fo_highwater = avd_int_alloc(1);
- }
-
- /* find file or leaf directory by index number */
- if (attr = get_attr_integer(cmd, FSA_INDEXED))
- flowop->fo_fileindex = attr->attr_avd;
- else
- flowop->fo_fileindex = NULL;
-}
-
-/*
- * defines the FLOW_MASTER flowops within a FLOW_MASTER instance of
- * a composit flowop. Default attributes from the FLOW_INNER_DEF instances
- * of the composit flowop's inner flowops are used if set. Otherwise
- * default attributes from the FLOW_MASTER instance of the composit flowop
- * are used, which may include defaults from the original FLOW_DEFINITION
- * of the composit flowop.
- */
-static void
-parser_inner_flowop_define(threadflow_t *thread, flowop_t *comp0_flow,
- flowop_t *comp_mstr_flow)
-{
- flowop_t *inner_flowtype, *inner_flowop;
-
- /* follow flowop list, creating composit names */
- inner_flowtype = comp0_flow->fo_comp_fops;
- comp_mstr_flow->fo_comp_fops = NULL;
-
- while (inner_flowtype) {
- char fullname[MAXPATHLEN];
-
- /* create composite_name.name for new flowop */
- snprintf(fullname, MAXPATHLEN, "%s.%s",
- comp_mstr_flow->fo_name, inner_flowtype->fo_name);
-
- if ((inner_flowop = flowop_define(thread, fullname,
- inner_flowtype, &comp_mstr_flow->fo_comp_fops,
- FLOW_MASTER, 0)) == NULL) {
- filebench_log(LOG_ERROR,
- "define flowop: Failed to instantiate flowop %s\n",
- fullname);
- filebench_shutdown(1);
- }
-
- /* if applicable, update filename attribute */
- if (inner_flowop->fo_filename) {
- char *name;
-
- /* fix up avd_t */
- avd_update(&inner_flowop->fo_filename,
- comp_mstr_flow->fo_lvar_list);
-
- /* see if ready to get the file or fileset */
- name = avd_get_str(inner_flowop->fo_filename);
- if (name) {
-
- inner_flowop->fo_fileset = fileset_find(name);
-
- if (inner_flowop->fo_fileset == NULL) {
- filebench_log(LOG_ERROR,
- "inr flowop %s: file %s not found",
- inner_flowop->fo_name, name);
- filebench_shutdown(1);
- }
- }
- }
-
- /* update attributes from local variables */
- avd_update(&inner_flowop->fo_iters,
- comp_mstr_flow->fo_lvar_list);
-
- /* if the inner flowop is a composit flowop, recurse */
- if (inner_flowtype->fo_type == FLOW_TYPE_COMPOSITE) {
- var_t *newlvar, *proto_lvars, *lvar_ptr;
-
- proto_lvars = inner_flowop->fo_lvar_list;
- inner_flowop->fo_lvar_list = 0;
-
- for (lvar_ptr = inner_flowtype->fo_lvar_list; lvar_ptr;
- lvar_ptr = lvar_ptr->var_next) {
-
- if ((newlvar = var_lvar_alloc_local(
- lvar_ptr->var_name)) != NULL) {
-
- add_lvar_to_list(newlvar,
- &inner_flowop->fo_lvar_list);
-
- var_update_comp_lvars(newlvar,
- proto_lvars,
- comp_mstr_flow->fo_lvar_list);
- }
- }
-
- parser_inner_flowop_define(thread,
- inner_flowtype,
- inner_flowop);
-
- inner_flowtype = inner_flowtype->fo_exec_next;
- continue;
- }
-
- avd_update(&inner_flowop->fo_iosize,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_wss,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_iters,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_value,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_random,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_dsync,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_rotatefd,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_blocking,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_directio,
- comp_mstr_flow->fo_lvar_list);
- avd_update(&inner_flowop->fo_highwater,
- comp_mstr_flow->fo_lvar_list);
-
- inner_flowtype = inner_flowtype->fo_exec_next;
- }
-}
-
-/*
- * Calls flowop_define() to allocate a flowop with the supplied name.
- * The allocated flowop inherits attributes from a base flowop of the
- * same type. If the new flowop has a file or fileset attribute specified,
- * it must specify a defined fileobj or fileset or an error will be logged.
- * The new flowop may also have the following attributes set by
- * the program:
- * - file size (fo_iosize)
- * - working set size (fo_wss)
- * - do random io (fo_random)
- * - do synchronous io (fo_dsync)
- * - perform each operation multiple times before advancing (fo_iter)
- * - target name (fo_targetname)
- * - An integer value (fo_value)
- * - a file descriptor (fo_fd)
- * - specify to rotate file descriptors (fo_rotatefd)
- * - a source fd (fo_srcfdnumber)
- * - specify a blocking operation (fo_blocking)
- * - specify a highwater mark (fo_highwater)
- *
- * After all the supplied attributes are stored in their respective locations
- * in the flowop object, the flowop's init function is called. No errors are
- * returned, but the filebench run will be terminated if the flowtype is not
- * specified, a name for the new flowop is not supplied, the flowop_define
- * call fails, or a file or fileset name is supplied but the corresponding
- * fileobj or fileset cannot be located.
- */
-static void
-parser_flowop_define(cmd_t *cmd, threadflow_t *thread,
- flowop_t **flowoplist_hdp, int category)
-{
- flowop_t *flowop, *flowop_type;
- char *type = (char *)cmd->cmd_name;
- char *name;
- attr_t *attr;
-
- /* Get the inherited flowop */
- flowop_type = flowop_find(type);
- if (flowop_type == NULL) {
- filebench_log(LOG_ERROR,
- "define flowop: flowop type %s not found",
- type);
- filebench_shutdown(1);
- }
-
- /* Get the name of the flowop */
- if (attr = get_attr(cmd, FSA_NAME)) {
- name = avd_get_str(attr->attr_avd);
- } else {
- filebench_log(LOG_ERROR,
- "define flowop: flowop %s specifies no name",
- flowop_type->fo_name);
- filebench_shutdown(1);
- }
-
- if ((flowop = flowop_define(thread, name,
- flowop_type, flowoplist_hdp, category, 0)) == NULL) {
- filebench_log(LOG_ERROR,
- "define flowop: Failed to instantiate flowop %s\n",
- cmd->cmd_name);
- filebench_shutdown(1);
- }
-
- /* Iterations */
- if (attr = get_attr_integer(cmd, FSA_ITERS))
- flowop->fo_iters = attr->attr_avd;
- else
- flowop->fo_iters = avd_int_alloc(1);
-
-
- /* if this is a use of a composit flowop, create inner FLOW MASTERS */
- if (flowop_type->fo_type == FLOW_TYPE_COMPOSITE) {
- get_attr_lvars(cmd, flowop);
- if (category == FLOW_MASTER)
- parser_inner_flowop_define(thread,
- flowop_type, flowop);
- }
- else {
- parser_flowop_get_attrs(cmd, flowop);
- }
-}
-
-static void
-parser_composite_flowop_define(cmd_t *cmd)
-{
- flowop_t *flowop;
- cmd_t *inner_cmd;
- char *name;
- attr_t *attr;
-
- /* Get the name of the flowop */
- if (attr = get_attr(cmd, FSA_NAME)) {
- name = avd_get_str(attr->attr_avd);
- } else {
- filebench_log(LOG_ERROR,
- "define flowop: Composit flowop specifies no name");
-
- filebench_shutdown(1);
- }
-
- if ((flowop = flowop_new_composite_define(name)) == NULL) {
- filebench_log(LOG_ERROR,
- "define flowop: Failed to instantiate flowop %s\n",
- cmd->cmd_name);
- filebench_shutdown(1);
- }
-
- /* place any local var_t variables on the flowop's local list */
- get_attr_lvars(cmd, flowop);
-
- /* Iterations */
- if (attr = get_attr_integer(cmd, FSA_ITERS))
- flowop->fo_iters = attr->attr_avd;
- else
- flowop->fo_iters = avd_int_alloc(1);
-
- /* define inner flowops */
- for (inner_cmd = cmd->cmd_list; inner_cmd != NULL;
- inner_cmd = inner_cmd->cmd_next) {
- parser_flowop_define(inner_cmd, NULL,
- &flowop->fo_comp_fops, FLOW_INNER_DEF);
- }
-}
-
-
-/*
- * Calls fileset_define() to allocate a fileset with the supplied name and
- * initializes the fileset's pathname attribute, and optionally the
- * fileset_cached, fileset_reuse, fileset_prealloc and fileset_size attributes.
- *
- */
-static fileset_t *
-parser_fileset_define_common(cmd_t *cmd)
-{
- fileset_t *fileset;
- avd_t name;
- attr_t *attr;
- avd_t pathname;
-
- /*
- * Make sure all plugin flowops are initialized.
- * Defaults to local fs for now
- */
- flowop_plugin_flowinit();
-
- /* Get the name of the file */
- if (attr = get_attr_fileset(cmd, FSA_NAME)) {
- name = attr->attr_avd;
- } else {
- filebench_log(LOG_ERROR,
- "define fileset: file or fileset specifies no name");
- return (NULL);
- }
-
- if ((fileset = fileset_define(name)) == NULL) {
- filebench_log(LOG_ERROR,
- "define file: failed to instantiate file %s\n",
- avd_get_str(name));
- return (NULL);
- }
-
- /* Get the pathname from attribute */
- if ((attr = get_attr(cmd, FSA_PATH)) == NULL) {
- filebench_log(LOG_ERROR, "define file: no pathname specified");
- return (NULL);
- }
-
- /* Expand variables in pathname */
- if ((pathname = parser_list2varstring(attr->attr_param_list))
- == NULL) {
- filebench_log(LOG_ERROR, "Cannot interpret path");
- return (NULL);
- }
-
- fileset->fs_path = pathname;
-
- /* How much should we preallocate? */
- if ((attr = get_attr_integer(cmd, FSA_PREALLOC)) &&
- attr->attr_avd) {
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "define fileset: Prealloc attr cannot be random");
- filebench_shutdown(1);
- }
- fileset->fs_preallocpercent = attr->attr_avd;
- } else if (attr && !attr->attr_avd) {
- fileset->fs_preallocpercent = avd_int_alloc(100);
- } else {
- fileset->fs_preallocpercent = avd_int_alloc(0);
- }
-
- /* Should we preallocate? */
- if (attr = get_attr_bool(cmd, FSA_PREALLOC))
- fileset->fs_prealloc = attr->attr_avd;
- else
- fileset->fs_prealloc = avd_bool_alloc(FALSE);
-
- /* Should we prealloc in parallel? */
- if (attr = get_attr_bool(cmd, FSA_PARALLOC))
- fileset->fs_paralloc = attr->attr_avd;
- else
- fileset->fs_paralloc = avd_bool_alloc(FALSE);
-
- /* Should we allow writes to the file? */
- if (attr = get_attr_bool(cmd, FSA_READONLY))
- fileset->fs_readonly = attr->attr_avd;
- else
- fileset->fs_readonly = avd_bool_alloc(FALSE);
-
- /* Should we reuse the existing file? */
- if (attr = get_attr_bool(cmd, FSA_REUSE))
- fileset->fs_reuse = attr->attr_avd;
- else
- fileset->fs_reuse = avd_bool_alloc(FALSE);
-
- /* Should we check for files actual existance? */
- if (attr = get_attr_bool(cmd, FSA_TRUSTTREE))
- fileset->fs_trust_tree = attr->attr_avd;
- else
- fileset->fs_trust_tree = avd_bool_alloc(FALSE);
-
- /* Should we leave in cache? */
- if (attr = get_attr_bool(cmd, FSA_CACHED))
- fileset->fs_cached = attr->attr_avd;
- else
- fileset->fs_cached = avd_bool_alloc(FALSE);
-
- /* Get the mean or absolute size of the file */
- if (attr = get_attr_integer(cmd, FSA_SIZE))
- fileset->fs_size = attr->attr_avd;
- else
- fileset->fs_size = avd_int_alloc(0);
-
- return (fileset);
-}
-
-/*
- * Calls parser_fileset_define_common() to allocate a fileset with
- * one entry and optionally the fileset_prealloc. sets the fileset_entries,
- * fileset_dirwidth, fileset_dirgamma, and fileset_sizegamma attributes
- * to appropriate values for emulating the old "fileobj" entity
- */
-static void
-parser_file_define(cmd_t *cmd)
-{
- fileset_t *fileset;
- attr_t *attr;
-
- if ((fileset = parser_fileset_define_common(cmd)) == NULL) {
- filebench_log(LOG_ERROR,
- "define file: failed to instantiate file");
- filebench_shutdown(1);
- return;
- }
-
- /* fileset is emulating a single file */
- fileset->fs_attrs = FILESET_IS_FILE;
-
- /* Set the size of the fileset to 1 */
- fileset->fs_entries = avd_int_alloc(1);
-
- /* Set the mean dir width to more than 1 */
- fileset->fs_dirwidth = avd_int_alloc(10);
-
- /* Set the dir and size gammas to 0 */
- fileset->fs_dirgamma = avd_int_alloc(0);
- fileset->fs_sizegamma = avd_int_alloc(0);
-}
-
-/*
- * Calls parser_fileset_define_common() to allocate a fileset with the
- * supplied name and initializes the fileset's fileset_preallocpercent,
- * fileset_prealloc, fileset_entries, fileset_dirwidth, fileset_dirgamma,
- * and fileset_sizegamma attributes.
- */
-static void
-parser_fileset_define(cmd_t *cmd)
-{
- fileset_t *fileset;
- attr_t *attr;
-
- if ((fileset = parser_fileset_define_common(cmd)) == NULL) {
- filebench_log(LOG_ERROR,
- "define fileset: failed to instantiate fileset");
- filebench_shutdown(1);
- return;
- }
- /* Get the number of files in the fileset */
- if (attr = get_attr_integer(cmd, FSA_ENTRIES)) {
- fileset->fs_entries = attr->attr_avd;
- } else {
- fileset->fs_entries = avd_int_alloc(0);
- }
-
- /* Get the number of leafdirs in the fileset */
- if (attr = get_attr_integer(cmd, FSA_LEAFDIRS)) {
- fileset->fs_leafdirs = attr->attr_avd;
- } else {
- fileset->fs_leafdirs = avd_int_alloc(0);
- }
-
- if ((avd_get_int(fileset->fs_entries) == 0) &&
- (avd_get_int(fileset->fs_leafdirs) == 0)) {
- filebench_log(LOG_ERROR, "Fileset has no files or leafdirs");
- }
-
- /* Get the mean dir width of the fileset */
- if (attr = get_attr_integer(cmd, FSA_DIRWIDTH)) {
- fileset->fs_dirwidth = attr->attr_avd;
- } else {
- filebench_log(LOG_ERROR, "Fileset has zero directory width");
- fileset->fs_dirwidth = avd_int_alloc(0);
- }
-
- /* Get the random variable for dir depth, if supplied */
- if (attr = get_attr_integer(cmd, FSA_DIRDEPTHRV)) {
- if (!AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "Define fileset: dirdepthrv must be random var");
- filebench_shutdown(1);
- }
- fileset->fs_dirdepthrv = attr->attr_avd;
- } else {
- fileset->fs_dirdepthrv = NULL;
- }
-
- /* Get the gamma value for dir depth distributions */
- if (attr = get_attr_integer(cmd, FSA_DIRGAMMA)) {
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "Define fileset: dirgamma attr cannot be random");
- filebench_shutdown(1);
- }
- fileset->fs_dirgamma = attr->attr_avd;
- } else
- fileset->fs_dirgamma = avd_int_alloc(1500);
-
- /* Get the gamma value for dir width distributions */
- if (attr = get_attr_integer(cmd, FSA_FILESIZEGAMMA)) {
- if (AVD_IS_RANDOM(attr->attr_avd)) {
- filebench_log(LOG_ERROR,
- "Define fileset: filesizegamma cannot be random");
- filebench_shutdown(1);
- }
- fileset->fs_sizegamma = attr->attr_avd;
- } else
- fileset->fs_sizegamma = avd_int_alloc(1500);
-}
-
-/*
- * Creates and starts all defined procflow processes. The call to
- * procflow_init() results in creation of the requested number of
- * process instances for each previously defined procflow. The
- * child processes exec() a new instance of filebench, passing it
- * the instance number and address of the shared memory region.
- * The child processes will then create their threads and flowops.
- * The routine then unlocks the run_lock to allow all the processes'
- * threads to start and waits for all of them to begin execution.
- * Finally, it records the start time and resets the event generation
- * system.
- */
-static void
-parser_proc_create(cmd_t *cmd)
-{
- filebench_shm->shm_1st_err = 0;
- filebench_shm->shm_f_abort = FILEBENCH_OK;
-
- if (procflow_init() != 0) {
- filebench_log(LOG_ERROR, "Failed to create processes\n");
- filebench_shutdown(1);
- }
-
- /* Release the read lock, allowing threads to start */
- (void) pthread_rwlock_unlock(&filebench_shm->shm_run_lock);
-
- /* Wait for all threads to start */
- if (procflow_allstarted() != 0) {
- filebench_log(LOG_ERROR, "Could not start run");
- return;
- }
-
-
- if (filebench_shm->shm_required &&
- (ipc_ismcreate(filebench_shm->shm_required) < 0)) {
- filebench_log(LOG_ERROR, "Could not allocate shared memory");
- return;
- }
-
- filebench_shm->shm_starttime = gethrtime();
- eventgen_reset();
-}
-
-/*
- * Calls fileset_createset() to populate all files and filesets and
- * create all associated, initially existant, files and subdirectories.
- * If errors are encountered, calls filebench_shutdown()
- * to exit filebench.
- */
-static void
-parser_fileset_create(cmd_t *cmd)
-{
- if (!filecreate_done) {
- filecreate_done = 1;
-
- /* initialize the random number system first */
- randdist_init();
-
- /* create all the filesets */
- if (fileset_createset(NULL) != 0) {
- filebench_log(LOG_ERROR, "Failed to create filesets");
- filebench_shutdown(1);
- }
- } else {
- filebench_log(LOG_INFO,
- "Attempting to create fileset more than once, ignoring");
- }
-
-}
-
-/*
- * Deletes the files and directories that represent files and filesets on the
- * storage medium.
- */
-static void
-parser_fileset_shutdown(cmd_t *cmd)
-{
- filebench_log(LOG_INFO, "Shutting down filesets");
- fileset_delete_all_filesets();
-}
-
-/*
- * Shuts down all processes and their associated threads. When finished
- * it deletes interprocess shared memory and resets the event generator.
- * It does not exit the filebench program though.
- */
-static void
-parser_proc_shutdown(cmd_t *cmd)
-{
- filebench_log(LOG_INFO, "Shutting down processes");
- filecreate_done = 0;
- procflow_shutdown();
- if (filebench_shm->shm_required)
- ipc_ismdelete();
- eventgen_reset();
-}
-
-/*
- * Ends filebench run after first destoring any interprocess
- * shared memory. The call to filebench_shutdown()
- * also causes filebench to exit.
- */
-static void
-parser_filebench_shutdown(cmd_t *cmd)
-{
- int f_abort = filebench_shm->shm_f_abort;
-
- ipc_fini();
-
- if (f_abort == FILEBENCH_ABORT_ERROR)
- filebench_shutdown(1);
- else
- filebench_shutdown(0);
-}
-
-/*
- * This is Used for timing runs.Pauses the master thread in one second
- * intervals until the supplied ptime runs out or the f_abort flag
- * is raised. If given a time of zero or less, or the mode is stop on
- * lack of resources, it will pause until f_abort is raised.
- */
-static int
-parser_pause(int ptime)
-{
- int timeslept = 0;
-
- if ((filebench_shm->shm_rmode == FILEBENCH_MODE_TIMEOUT) &&
- (ptime > 0)) {
- while (timeslept < ptime) {
- (void) sleep(1);
- timeslept++;
- if (filebench_shm->shm_f_abort)
- break;
- }
- } else {
- /* initial runtime of 0 means run till abort */
- /* CONSTCOND */
- while (1) {
- (void) sleep(1);
- timeslept++;
- if (filebench_shm->shm_f_abort)
- break;
- }
- }
- return (timeslept);
-}
-
-/*
- * Do a file bench run. Calls routines to create file sets, files, and
- * processes. It resets the statistics counters, then sleeps for the runtime
- * passed as an argument to it on the command line in 1 second increments.
- * When it is finished sleeping, it collects a snapshot of the statistics
- * and ends the run.
- */
-static void
-parser_run(cmd_t *cmd)
-{
- int runtime;
- int timeslept;
-
- runtime = cmd->cmd_qty;
-
- parser_fileset_create(cmd);
- parser_proc_create(cmd);
-
- /* check for startup errors */
- if (filebench_shm->shm_f_abort)
- return;
-
- filebench_log(LOG_INFO, "Running...");
- stats_clear();
-
- timeslept = parser_pause(runtime);
-
- filebench_log(LOG_INFO, "Run took %d seconds...", timeslept);
- parser_statssnap(cmd);
- parser_proc_shutdown(cmd);
-}
-
-/*
- * Similar to parser_run, but gets the sleep time from a variable
- * whose name is supplied as an argument to the command.
- */
-static void
-parser_run_variable(cmd_t *cmd)
-{
- avd_t integer = var_ref_attr(cmd->cmd_tgt1);
- int runtime;
- int timeslept;
-
- if (integer == NULL) {
- filebench_log(LOG_ERROR, "Unknown variable %s",
- cmd->cmd_tgt1);
- return;
- }
-
- runtime = avd_get_int(integer);
-
- /* check for startup errors */
- if (filebench_shm->shm_f_abort)
- return;
-
- filebench_log(LOG_INFO, "Running...");
- stats_clear();
-
- timeslept = parser_pause(runtime);
-
- filebench_log(LOG_INFO, "Run took %d seconds...", timeslept);
- parser_statssnap(cmd);
- parser_proc_shutdown(cmd);
-}
-
-char *usagestr = NULL;
-
-/*
- * Prints usage string if defined, else just a message requesting load of a
- * personality.
- */
-static void
-parser_help(cmd_t *cmd)
-{
- if (usagestr) {
- filebench_log(LOG_INFO, "%s", usagestr);
- } else {
- filebench_log(LOG_INFO,
- "load <personality> (ls "
- "%s/workloads for list)", fbbasepath);
- }
-}
-
-char *varstr = NULL;
-
-/*
- * Prints the string of all var definitions, if there is one.
- */
-static void
-parser_printvars(cmd_t *cmd)
-{
- char *str, *c;
-
- if (varstr) {
- str = strdup(varstr);
- for (c = str; *c != '\0'; c++) {
- if ((char)*c == '$')
- *c = ' ';
- }
- filebench_log(LOG_INFO, "%s", str);
- free(str);
- }
-}
-
-/*
- * Establishes multi-client synchronization socket with synch server.
- */
-static void
-parser_enable_mc(cmd_t *cmd)
-{
- attr_t *attr;
- char *master;
- char *client;
-
- if (attr= get_attr(cmd, FSA_MASTER)) {
- master = avd_get_str(attr->attr_avd);
- } else {
- filebench_log(LOG_ERROR,
- "enable multi: no master specified");
- return;
- }
-
- if (attr= get_attr(cmd, FSA_CLIENT)) {
- client = avd_get_str(attr->attr_avd);
- } else {
- filebench_log(LOG_ERROR,
- "enable multi: no client specified");
- return;
- }
-
- mc_sync_open_sock(master, 8001, client);
-}
-
-/*
- * Exchanges multi-client synchronization message with synch server.
- */
-static void
-parser_domultisync(cmd_t *cmd)
-{
- attr_t *attr;
- fbint_t value;
-
- if (attr = get_attr(cmd, FSA_VALUE))
- value = avd_get_int(attr->attr_avd);
- else
- value = 1;
-
- mc_sync_synchronize((int)value);
-}
-
-/*
- * Used by the SET command to add a var and default value string to the
- * varstr string. It allocates a new, larger varstr string, copies the
- * old contents of varstr into it, then adds the new var string on the end.
- */
-static void
-parser_vars(cmd_t *cmd)
-{
- char *string = cmd->cmd_tgt1;
- char *newvars;
-
- if (string == NULL)
- return;
-
- if (dofile)
- return;
-
- if (varstr == NULL) {
- newvars = malloc(strlen(string) + 2);
- *newvars = 0;
- } else {
- newvars = malloc(strlen(varstr) + strlen(string) + 2);
- (void) strcpy(newvars, varstr);
- }
- (void) strcat(newvars, string);
- (void) strcat(newvars, " ");
-
- if (varstr)
- free(varstr);
-
- varstr = newvars;
-}
-
-/*
- * used by the set command to set the integer part of a regular
- * variable, or the appropriate field of a random variable
- */
-static void
-parser_set_integer(cmd_t *cmd)
-{
- var_assign_integer(cmd->cmd_tgt1, cmd->cmd_qty);
-}
-
-/*
- * used by the set command to set the integer part of a regular
- * variable from another variable, or the appropriate field of a
- * random variable from another variable
- */
-static void
-parser_set_var(cmd_t *cmd)
-{
- var_assign_var(cmd->cmd_tgt1, cmd->cmd_tgt2);
-}
-
-/*
- * Used by the set command to set up for a binary operation of a
- * variable from a var, with an integer
- */
-static void
-parser_set_var_op_int(cmd_t *cmd)
-{
- printf("parser_set_var_op_int: Called\n");
- switch (cmd->cmd_subtype) {
- case FSK_PLUS:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_INT_SUM_IV,
- cmd->cmd_tgt2, cmd->cmd_qty);
- break;
-
- case FSK_MINUS:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_IV_DIF_INT,
- cmd->cmd_tgt2, cmd->cmd_qty);
- break;
-
- case FSK_MULTIPLY:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_INT_MUL_IV,
- cmd->cmd_tgt2, cmd->cmd_qty);
- break;
-
- case FSK_DIVIDE:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_IV_DIV_INT,
- cmd->cmd_tgt2, cmd->cmd_qty);
- break;
- }
-}
-
-/*
- * Used by the set command to set up for a binary operation of an
- * integer with a variable from a var
- */
-static void
-parser_set_int_op_var(cmd_t *cmd)
-{
- switch (cmd->cmd_subtype) {
- case FSK_PLUS:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_INT_SUM_IV,
- cmd->cmd_tgt3, cmd->cmd_qty);
- break;
-
- case FSK_MINUS:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_INT_DIF_IV,
- cmd->cmd_tgt3, cmd->cmd_qty);
- break;
-
- case FSK_MULTIPLY:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_INT_MUL_IV,
- cmd->cmd_tgt3, cmd->cmd_qty);
- break;
-
- case FSK_DIVIDE:
- var_assign_op_var_int(cmd->cmd_tgt1, VAR_IND_INT_DIV_IV,
- cmd->cmd_tgt3, cmd->cmd_qty);
- break;
- }
-}
-
-/*
- * Used by the set command to set up for a binary operation of two
- * variables from other vars.
- */
-static void
-parser_set_var_op_var(cmd_t *cmd)
-{
- switch (cmd->cmd_subtype) {
- case FSK_PLUS:
- var_assign_op_var_var(cmd->cmd_tgt1, VAR_IND_IV_SUM_IV,
- cmd->cmd_tgt2, cmd->cmd_tgt3);
- break;
-
- case FSK_MINUS:
- var_assign_op_var_var(cmd->cmd_tgt1, VAR_IND_IV_DIF_IV,
- cmd->cmd_tgt2, cmd->cmd_tgt3);
- break;
-
- case FSK_MULTIPLY:
- var_assign_op_var_var(cmd->cmd_tgt1, VAR_IND_IV_MUL_IV,
- cmd->cmd_tgt2, cmd->cmd_tgt3);
- break;
-
- case FSK_DIVIDE:
- var_assign_op_var_var(cmd->cmd_tgt1, VAR_IND_IV_DIV_IV,
- cmd->cmd_tgt2, cmd->cmd_tgt3);
- break;
- }
-}
-
-
-/*
- * Sleeps for cmd->cmd_qty seconds, one second at a time.
- */
-static void
-parser_warmup(cmd_t *cmd)
-{
- int sleeptime;
-
- /* check for startup errors */
- if (filebench_shm->shm_f_abort)
- return;
-
- sleeptime = cmd->cmd_qty;
- filebench_log(LOG_INFO, "Warming up...");
-
- (void) parser_pause(sleeptime);
-}
-
-/*
- * Same as parser_sleep, except the sleep time is obtained from a variable
- * whose name is passed to it as an argument on the command line.
- */
-static void
-parser_warmup_variable(cmd_t *cmd)
-{
- avd_t integer = var_ref_attr(cmd->cmd_tgt1);
- int sleeptime;
-
- if (integer == NULL) {
- filebench_log(LOG_ERROR, "Unknown variable %s",
- cmd->cmd_tgt1);
- return;
- }
-
- sleeptime = avd_get_int(integer);
-
- /* check for startup errors */
- if (filebench_shm->shm_f_abort)
- return;
-
- filebench_log(LOG_INFO, "Warming up...");
-
- (void) parser_pause(sleeptime);
-}
-
-/*
- * Sleeps for cmd->cmd_qty seconds, one second at a time.
- */
-static void
-parser_sleep(cmd_t *cmd)
-{
- int sleeptime;
- int timeslept;
-
- /* check for startup errors */
- if (filebench_shm->shm_f_abort)
- return;
-
- sleeptime = cmd->cmd_qty;
- filebench_log(LOG_INFO, "Running...");
-
- timeslept = parser_pause(sleeptime);
-
- filebench_log(LOG_INFO, "Run took %d seconds...", timeslept);
-}
-
-/*
- * Same as parser_sleep, except the sleep time is obtained from a variable
- * whose name is passed to it as an argument on the command line.
- */
-static void
-parser_sleep_variable(cmd_t *cmd)
-{
- avd_t integer = var_ref_attr(cmd->cmd_tgt1);
- int sleeptime;
- int timeslept;
-
- if (integer == NULL) {
- filebench_log(LOG_ERROR, "Unknown variable %s",
- cmd->cmd_tgt1);
- return;
- }
-
- sleeptime = avd_get_int(integer);
-
- /* check for startup errors */
- if (filebench_shm->shm_f_abort)
- return;
-
- filebench_log(LOG_INFO, "Running...");
-
- timeslept = parser_pause(sleeptime);
-
- filebench_log(LOG_INFO, "Run took %d seconds...", timeslept);
-}
-
-/*
- * Parser log prints the values of a list of variables to the log file.
- * The list of variables is placed on the command line, separated
- * by comas and the entire list is enclosed in quotes.
- * For example, if $dir contains "/export/home/tmp" and $filesize = 1048576,
- * then typing: log "$dir, $filesize" prints: log /export/home/tmp, 1048576
- */
-static void
-parser_log(cmd_t *cmd)
-{
- char *string;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- filebench_log(LOG_VERBOSE, "log %s", string);
- filebench_log(LOG_LOG, "%s", string);
-}
-
-/*
- * Implements the stats directory command. changes the directory for
- * dumping statistics to supplied directory path. For example:
- * stats directory /tmp
- * changes the stats directory to "/tmp".
- */
-static void
-parser_directory(cmd_t *cmd)
-{
- char newdir[MAXPATHLEN];
- char *dir;
-
- if ((dir = parser_list2string(cmd->cmd_param_list)) == NULL) {
- filebench_log(LOG_ERROR, "Cannot interpret directory");
- return;
- }
-
- *newdir = 0;
- /* Change dir relative to cwd if path not fully qualified */
- if (*dir != '/') {
- (void) strcat(newdir, cwd);
- (void) strcat(newdir, "/");
- }
- (void) strcat(newdir, dir);
- (void) mkdir(newdir, 0755);
- filebench_log(LOG_VERBOSE, "Change dir to %s", newdir);
- chdir(newdir);
- free(dir);
-}
-
-#define PIPE_PARENT 1
-#define PIPE_CHILD 0
-
-/*
- * Runs the quoted unix command as a background process. Intended for
- * running statistics gathering utilities such as mpstat while the filebench
- * workload is running. Also records the pid's of the background processes
- * so that parser_statssnap() can terminate them when the run completes.
- */
-static void
-parser_statscmd(cmd_t *cmd)
-{
- char *string;
- pid_t pid;
- pidlist_t *pidlistent;
- int pipe_fd[2];
- int newstdout;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- if ((pipe(pipe_fd)) < 0) {
- filebench_log(LOG_ERROR, "statscmd pipe failed");
- return;
- }
-
-#ifdef HAVE_FORK1
- if ((pid = fork1()) < 0) {
- filebench_log(LOG_ERROR, "statscmd fork failed");
- return;
- }
-#elif HAVE_FORK
- if ((pid = fork()) < 0) {
- filebench_log(LOG_ERROR, "statscmd fork failed");
- return;
- }
-#else
- Crash! - Need code to deal with no fork1!
-#endif /* HAVE_FORK1 */
-
- if (pid == 0) {
-
- setsid();
-
- filebench_log(LOG_VERBOSE,
- "Backgrounding %s", string);
- /*
- * Child
- * - close stdout
- * - dup to create new stdout
- * - close pipe fds
- */
- (void) close(1);
-
- if ((newstdout = dup(pipe_fd[PIPE_CHILD])) < 0) {
- filebench_log(LOG_ERROR,
- "statscmd dup failed: %s",
- strerror(errno));
- }
-
- (void) close(pipe_fd[PIPE_PARENT]);
- (void) close(pipe_fd[PIPE_CHILD]);
-
- if (system(string) < 0) {
- filebench_log(LOG_ERROR,
- "statscmd exec failed: %s",
- strerror(errno));
- }
- /* Failed! */
- exit(1);
-
- } else {
-
- /* Record pid in pidlist for subsequent reaping by stats snap */
- if ((pidlistent = (pidlist_t *)malloc(sizeof (pidlist_t)))
- == NULL) {
- filebench_log(LOG_ERROR, "pidlistent malloc failed");
- return;
- }
-
- pidlistent->pl_pid = pid;
- pidlistent->pl_fd = pipe_fd[PIPE_PARENT];
- (void) close(pipe_fd[PIPE_CHILD]);
-
- /* Add fileobj to global list */
- if (pidlist == NULL) {
- pidlist = pidlistent;
- pidlistent->pl_next = NULL;
- } else {
- pidlistent->pl_next = pidlist;
- pidlist = pidlistent;
- }
- }
-}
-
-/*
- * Launches a shell to run the unix command supplied in the argument.
- * The command should be enclosed in quotes, as in:
- * system "rm xyz"
- * which would run the "rm" utility to delete the file "xyz".
- */
-static void
-parser_system(cmd_t *cmd)
-{
- char *string;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- filebench_log(LOG_VERBOSE,
- "Running '%s'", string);
-
- if (system(string) < 0) {
- filebench_log(LOG_ERROR,
- "system exec failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
- free(string);
-}
-
-/*
- * Echos string supplied with command to the log.
- */
-static void
-parser_echo(cmd_t *cmd)
-{
- char *string;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- filebench_log(LOG_INFO, "%s", string);
-}
-
-/*
- * Checks to see if the specified data directory exists and it's mounted file
- * system is the correct type.
- */
-static void
-parser_fscheck(cmd_t *cmd)
-{
- int fstype_idx;
- char *pathname = NULL;
- char *filesys = "tmpfs";
- char string[MAXPATHLEN];
- struct statvfs64 statbuf;
- attr_t *attr;
-
- if (cmd->cmd_attr_list == NULL)
- return;
-
- for (attr = cmd->cmd_attr_list; attr; attr = attr->attr_next) {
-
- switch(attr->attr_name) {
- case FSA_PATH:
- pathname = avd_get_str(attr->attr_avd);
- break;
- case FSA_FSTYPE:
- filesys = avd_get_str(attr->attr_avd);
- break;
- }
- }
-
- if (pathname == NULL)
- return;
-
- if (statvfs64(pathname, &statbuf) < 0) {
- filebench_log(LOG_ERROR,
- "%s error with supplied data path name: %s; exiting",
- strerror(errno), pathname);
- filebench_shutdown(1);
- return;
- }
-
- if (strncmp(filesys, statbuf.f_basetype, FSTYPSZ) != 0) {
- filebench_log(LOG_ERROR,
- "File System is of type %s, NOT %s as indicated",
- statbuf.f_basetype, filesys);
- filebench_shutdown(1);
- return;
- }
-}
-
-/*
- * Checks to see if any filesets need to have their caches flushed, and
- * if so invokes the fs_flush script.
- */
-static void
-parser_fsflush(cmd_t *cmd)
-{
- fileset_t *fileset;
- char **fspathlist;
- char *pathname = NULL;
- char *filesys = NULL;
- char string[MAXPATHLEN];
- attr_t *attr;
- int fsidx;
-
- if ((attr = cmd->cmd_attr_list) == NULL)
- return;
-
- /* Get supplied file system type */
- if (attr->attr_name == FSA_FSTYPE)
- filesys = avd_get_str(attr->attr_avd);
-
- if (filesys == NULL) {
- filebench_log(LOG_ERROR,
- "FSFLUSH command lacks file system type");
- return;
- }
-
- /* Check all filesets for any that remain cached and count them*/
- fsidx = 0;
- for (fileset = filebench_shm->shm_filesetlist; fileset != NULL;
- fileset = fileset->fs_next) {
-
- if (avd_get_bool(fileset->fs_cached))
- return;
-
- fsidx++;
- }
-
- /* allocated space for fileset path pointers */
- fspathlist = (char **)malloc(fsidx * sizeof(char *));
-
- /* If flushing still required, flush all filesets */
- fsidx = 0;
- for (fileset = filebench_shm->shm_filesetlist; fileset != NULL;
- fileset = fileset->fs_next) {
- int idx;
-
- if ((pathname = avd_get_str(fileset->fs_path)) == NULL)
- return;
-
- for (idx = 0; idx < fsidx; idx++) {
- if (strcmp(pathname, fspathlist[idx]) == 0)
- break;
- }
-
- if (fsidx == idx) {
-
- /* found a new path */
- fspathlist[fsidx++] = pathname;
-
- /* now flush it */
- snprintf(string, MAXPATHLEN,
- "%s/scripts/fs_flush %s %s", fbbasepath,
- filesys, pathname);
-
- if (system(string) < 0) {
- filebench_log(LOG_ERROR,
- "exec of fs_flush script failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
- }
- }
-}
-
-/*
- * Prints out the version of FileBench.
- */
-static void
-parser_version(cmd_t *cmd)
-{
- filebench_log(LOG_INFO, "FileBench Version: %s", FILEBENCH_VERSION);
-}
-
-/*
- * Adds the string supplied as the argument to the usage command
- * to the end of the string printed by the help command.
- */
-static void
-parser_usage(cmd_t *cmd)
-{
- char *string;
- char *newusage;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- if (dofile)
- return;
-
- if (usagestr == NULL) {
- newusage = malloc(strlen(string) + 2);
- *newusage = 0;
- } else {
- newusage = malloc(strlen(usagestr) + strlen(string) + 2);
- (void) strcpy(newusage, usagestr);
- }
- (void) strcat(newusage, "\n");
- (void) strcat(newusage, string);
-
- if (usagestr)
- free(usagestr);
-
- usagestr = newusage;
-
- filebench_log(LOG_INFO, "%s", string);
-}
-
-/*
- * Updates the global dump filename with the filename supplied
- * as the command's argument. Then dumps the statistics of each
- * worker flowop into the dump file, followed by a summary of
- * overall totals.
- */
-static void
-parser_statsdump(cmd_t *cmd)
-{
- char *string;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- filebench_log(LOG_VERBOSE,
- "Stats dump to file '%s'", string);
-
- stats_dump(string);
-
- free(string);
-}
-
-/*
- * Same as statsdump, but outputs in a computer friendly format.
- */
-static void
-parser_statsmultidump(cmd_t *cmd)
-{
- char *string;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- filebench_log(LOG_VERBOSE,
- "Stats dump to file '%s'", string);
-
- stats_multidump(string);
-
- free(string);
-}
-
-/*
- * Same as parser_statsdump, but in xml format.
- */
-static void
-parser_statsxmldump(cmd_t *cmd)
-{
- char *string;
-
- if (cmd->cmd_param_list == NULL)
- return;
-
- string = parser_list2string(cmd->cmd_param_list);
-
- if (string == NULL)
- return;
-
- filebench_log(LOG_VERBOSE,
- "Stats dump to file '%s'", string);
-
- stats_xmldump(string);
-
- free(string);
-}
-
-/*
- * Kills off background statistics collection processes, then takes a snapshot
- * of the filebench run's collected statistics using stats_snap() from
- * stats.c.
- */
-static void
-parser_statssnap(cmd_t *cmd)
-{
- pidlist_t *pidlistent;
- int stat;
- pid_t pid;
-
- for (pidlistent = pidlist; pidlistent != NULL;
- pidlistent = pidlistent->pl_next) {
- filebench_log(LOG_VERBOSE, "Killing session %d for pid %d",
- getsid(pidlistent->pl_pid),
- pidlistent->pl_pid);
- if (pidlistent->pl_fd)
- (void) close(pidlistent->pl_fd);
-#ifdef HAVE_SIGSEND
- sigsend(P_SID, getsid(pidlistent->pl_pid), SIGTERM);
-#else
- (void) kill(-1, SIGTERM);
-#endif
-
- /* Close pipe */
- if (pidlistent->pl_fd)
- (void) close(pidlistent->pl_fd);
-
- /* Wait for cmd and all its children */
- while ((pid = waitpid(pidlistent->pl_pid * -1, &stat, 0)) > 0)
- filebench_log(LOG_DEBUG_IMPL,
- "Waited for pid %d", (int)pid);
- }
-
- for (pidlistent = pidlist; pidlistent != NULL;
- pidlistent = pidlistent->pl_next) {
- free(pidlistent);
- }
-
- pidlist = NULL;
- stats_snap();
-}
-
-/*
- * Shutdown filebench.
- */
-static void
-parser_abort(int arg)
-{
- (void) sigignore(SIGINT);
- filebench_log(LOG_INFO, "Aborting...");
- filebench_shutdown(1);
-}
-
-/*
- * define a random variable and initialize the distribution parameters
- */
-static void
-parser_randvar_define(cmd_t *cmd)
-{
- var_t *var;
- randdist_t *rndp;
- attr_t *attr;
- char *name;
-
- /* Get the name for the random variable */
- if (attr = get_attr(cmd, FSA_NAME)) {
- name = avd_get_str(attr->attr_avd);
- } else {
- filebench_log(LOG_ERROR,
- "define randvar: no name specified");
- return;
- }
-
- if ((var = var_define_randvar(name)) == NULL) {
- filebench_log(LOG_ERROR,
- "define randvar: failed for random variable %s",
- name);
- return;
- }
-
- rndp = var->var_val.randptr;
- rndp->rnd_type = 0;
-
- /* Get the source of the random numbers */
- if (attr = get_attr_integer(cmd, FSA_RANDSRC)) {
- int randsrc = (int)avd_get_int(attr->attr_avd);
-
- switch (randsrc) {
- case FSV_URAND:
- rndp->rnd_type |= RAND_SRC_URANDOM;
- break;
- case FSV_RAND48:
- rndp->rnd_type |= RAND_SRC_GENERATOR;
- break;
- }
- } else {
- /* default to rand48 random number generator */
- rndp->rnd_type |= RAND_SRC_GENERATOR;
- }
-
- /* Get the min value of the random distribution */
- if (attr = get_attr_integer(cmd, FSA_RANDMIN))
- rndp->rnd_min = attr->attr_avd;
- else
- rndp->rnd_min = avd_int_alloc(0);
-
- /* Get the roundoff value for the random distribution */
- if (attr = get_attr_integer(cmd, FSA_RANDROUND))
- rndp->rnd_round = attr->attr_avd;
- else
- rndp->rnd_round = avd_int_alloc(0);
-
- /* Get a tablular probablility distribution if there is one */
- if (attr = get_attr(cmd, FSA_RANDTABLE)) {
- rndp->rnd_probtabs = (probtabent_t *)(attr->attr_obj);
- rndp->rnd_type |= RAND_TYPE_TABLE;
-
- /* no need for the rest of the attributes */
- return;
- } else {
- rndp->rnd_probtabs = NULL;
- }
-
- /* Get the type for the random variable */
- if (attr = get_attr(cmd, FSA_TYPE)) {
- int disttype = (int)avd_get_int(attr->attr_avd);
-
- switch (disttype) {
- case FSV_RANDUNI:
- rndp->rnd_type |= RAND_TYPE_UNIFORM;
- break;
- case FSA_RANDGAMMA:
- rndp->rnd_type |= RAND_TYPE_GAMMA;
- break;
- case FSV_RANDTAB:
- filebench_log(LOG_ERROR,
- "Table distribution type without prob table");
- break;
- }
- } else {
- /* default to gamma distribution type */
- rndp->rnd_type |= RAND_TYPE_GAMMA;
- }
-
- /* Get the seed for the random variable */
- if (attr = get_attr_integer(cmd, FSA_RANDSEED))
- rndp->rnd_seed = attr->attr_avd;
- else
- rndp->rnd_seed = avd_int_alloc(0);
-
- /* Get the gamma value of the random distribution */
- if (attr = get_attr_integer(cmd, FSA_RANDGAMMA))
- rndp->rnd_gamma = attr->attr_avd;
- else
- rndp->rnd_gamma = avd_int_alloc(1500);
-
- /* Get the mean value of the random distribution */
- if (attr = get_attr_integer(cmd, FSA_RANDMEAN)) {
- rndp->rnd_mean = attr->attr_avd;
- } else if ((rndp->rnd_type & RAND_TYPE_MASK) == RAND_TYPE_GAMMA) {
- rndp->rnd_mean = NULL;
- } else {
- rndp->rnd_mean = avd_int_alloc(0);
- }
-}
-
-/*
- * Set a specified random distribution parameter in a random variable.
- */
-static void
-parser_randvar_set(cmd_t *cmd)
-{
- var_t *src_var, *randvar;
- randdist_t *rndp;
- avd_t value;
-
- if ((randvar = var_find_randvar(cmd->cmd_tgt1)) == NULL) {
- filebench_log(LOG_ERROR,
- "set randvar: failed",
- cmd->cmd_tgt1);
- return;
- }
-
- rndp = randvar->var_val.randptr;
- value = cmd->cmd_attr_list->attr_avd;
-
- switch (cmd->cmd_qty) {
- case FSS_TYPE:
- {
- int disttype = (int)avd_get_int(value);
-
- rndp->rnd_type &= (~RAND_TYPE_MASK);
-
- switch (disttype) {
- case FSV_RANDUNI:
- rndp->rnd_type |= RAND_TYPE_UNIFORM;
- break;
- case FSA_RANDGAMMA:
- rndp->rnd_type |= RAND_TYPE_GAMMA;
- break;
- case FSV_RANDTAB:
- rndp->rnd_type |= RAND_TYPE_TABLE;
- break;
- }
- break;
- }
-
- case FSS_SRC:
- {
- int randsrc = (int)avd_get_int(value);
-
- rndp->rnd_type &=
- (~(RAND_SRC_URANDOM | RAND_SRC_GENERATOR));
-
- switch (randsrc) {
- case FSV_URAND:
- rndp->rnd_type |= RAND_SRC_URANDOM;
- break;
- case FSV_RAND48:
- rndp->rnd_type |= RAND_SRC_GENERATOR;
- break;
- }
- break;
- }
-
- case FSS_SEED:
- rndp->rnd_seed = value;
- break;
-
- case FSS_GAMMA:
- rndp->rnd_gamma = value;
- break;
-
- case FSS_MEAN:
- rndp->rnd_mean = value;
- break;
-
- case FSS_MIN:
- rndp->rnd_min = value;
- break;
-
- case FSS_ROUND:
- rndp->rnd_round = value;
- break;
-
- default:
- filebench_log(LOG_ERROR, "setrandvar: undefined attribute");
- }
-}
-
-/*
- * alloc_cmd() allocates the required resources for a cmd_t. On failure, a
- * filebench_log is issued and NULL is returned.
- */
-static cmd_t *
-alloc_cmd(void)
-{
- cmd_t *cmd;
-
- if ((cmd = malloc(sizeof (cmd_t))) == NULL) {
- filebench_log(LOG_ERROR, "Alloc cmd failed");
- return (NULL);
- }
-
- (void) memset(cmd, 0, sizeof (cmd_t));
-
- return (cmd);
-}
-
-/*
- * Frees the resources of a cmd_t and then the cmd_t "cmd" itself.
- */
-static void
-free_cmd(cmd_t *cmd)
-{
- free((void *)cmd->cmd_tgt1);
- free((void *)cmd->cmd_tgt2);
- free(cmd);
-}
-
-/*
- * Allocates an attr_t structure and zeros it. Returns NULL on failure, or
- * a pointer to the attr_t.
- */
-static attr_t *
-alloc_attr(void)
-{
- attr_t *attr;
-
- if ((attr = malloc(sizeof (attr_t))) == NULL) {
- return (NULL);
- }
-
- (void) memset(attr, 0, sizeof (attr_t));
- return (attr);
-}
-
-/*
- * Allocates a probtabent_t structure and zeros it. Returns NULL on failure, or
- * a pointer to the probtabent_t.
- */
-static probtabent_t *
-alloc_probtabent(void)
-{
- probtabent_t *rte;
-
- if ((rte = malloc(sizeof (probtabent_t))) == NULL) {
- return (NULL);
- }
-
- (void) memset(rte, 0, sizeof (probtabent_t));
- return (rte);
-}
-
-/*
- * Allocates an attr_t structure and puts the supplied var_t into
- * its attr_avd location, and sets its name to FSA_LVAR_ASSIGN
- */
-static attr_t *
-alloc_lvar_attr(var_t *var)
-{
- attr_t *attr;
-
- if ((attr = alloc_attr()) == NULL)
- return (NULL);
-
- attr->attr_name = FSA_LVAR_ASSIGN;
- attr->attr_avd = (avd_t)var;
-
- return (attr);
-}
-
-
-/*
- * Searches the attribute list for the command for the named attribute type.
- * The attribute list is created by the parser from the list of attributes
- * supplied with certain commands, such as the define and flowop commands.
- * Returns a pointer to the attribute structure if the named attribute is
- * found, otherwise returns NULL. If the attribute includes a parameter list,
- * the list is converted to a string and stored in the attr_avd field of
- * the returned attr_t struct.
- */
-static attr_t *
-get_attr_fileset(cmd_t *cmd, int64_t name)
-{
- attr_t *attr;
- attr_t *rtn = NULL;
- char *string;
-
- for (attr = cmd->cmd_attr_list; attr != NULL;
- attr = attr->attr_next) {
- filebench_log(LOG_DEBUG_IMPL,
- "attr %d = %d %llx?",
- attr->attr_name,
- name,
- attr->attr_avd);
-
- if (attr->attr_name == name)
- rtn = attr;
- }
-
- if (rtn == NULL)
- return (NULL);
-
- if (rtn->attr_param_list) {
- filebench_log(LOG_DEBUG_SCRIPT, "attr is param list");
- rtn->attr_avd = parser_list2varstring(rtn->attr_param_list);
- }
-
- return (rtn);
-}
-
-
-/*
- * Searches the attribute list for the command for the named attribute type.
- * The attribute list is created by the parser from the list of attributes
- * supplied with certain commands, such as the define and flowop commands.
- * Returns a pointer to the attribute structure if the named attribute is
- * found, otherwise returns NULL. If the attribute includes a parameter list,
- * the list is converted to a string and stored in the attr_avd field of
- * the returned attr_t struct.
- */
-static attr_t *
-get_attr(cmd_t *cmd, int64_t name)
-{
- attr_t *attr;
- attr_t *rtn = NULL;
- char *string;
-
- for (attr = cmd->cmd_attr_list; attr != NULL;
- attr = attr->attr_next) {
- filebench_log(LOG_DEBUG_IMPL,
- "attr %d = %d %llx?",
- attr->attr_name,
- name,
- attr->attr_avd);
-
- if (attr->attr_name == name)
- rtn = attr;
- }
-
- if (rtn == NULL)
- return (NULL);
-
- if (rtn->attr_param_list) {
- filebench_log(LOG_DEBUG_SCRIPT, "attr is param list");
- string = parser_list2string(rtn->attr_param_list);
- if (string != NULL) {
- rtn->attr_avd = avd_str_alloc(string);
- filebench_log(LOG_DEBUG_SCRIPT,
- "attr string %s", string);
- }
- }
-
- return (rtn);
-}
-
-/*
- * Similar to get_attr, but converts the parameter string supplied with the
- * named attribute to an integer and stores the integer in the attr_avd
- * portion of the returned attr_t struct.
- */
-static attr_t *
-get_attr_integer(cmd_t *cmd, int64_t name)
-{
- attr_t *attr;
- attr_t *rtn = NULL;
-
- for (attr = cmd->cmd_attr_list; attr != NULL;
- attr = attr->attr_next) {
- if (attr->attr_name == name)
- rtn = attr;
- }
-
- if (rtn == NULL)
- return (NULL);
-
- if (rtn->attr_param_list)
- rtn->attr_avd = parser_list2avd(rtn->attr_param_list);
-
- return (rtn);
-}
-
-/*
- * Similar to get_attr, but converts the parameter string supplied with the
- * named attribute to an integer and stores the integer in the attr_avd
- * portion of the returned attr_t struct. If no parameter string is supplied
- * then it defaults to TRUE (1).
- */
-static attr_t *
-get_attr_bool(cmd_t *cmd, int64_t name)
-{
- attr_t *attr;
- attr_t *rtn = NULL;
-
- for (attr = cmd->cmd_attr_list; attr != NULL;
- attr = attr->attr_next) {
- if (attr->attr_name == name)
- rtn = attr;
- }
-
- if (rtn == NULL)
- return (NULL);
-
- if (rtn->attr_param_list) {
- rtn->attr_avd = parser_list2avd(rtn->attr_param_list);
-
- } else if (rtn->attr_avd == NULL) {
- rtn->attr_avd = avd_bool_alloc(TRUE);
- }
-
- /* boolean attributes cannot point to random variables */
- if (AVD_IS_RANDOM(rtn->attr_avd)) {
- filebench_log(LOG_ERROR,
- "define flowop: Boolean attr %s cannot be random", name);
- filebench_shutdown(1);
- return (NULL);
- }
-
- return (rtn);
-}
-
-/*
- * removes the newly allocated local var from the shared local var
- * list, then puts it at the head of the private local var list
- * supplied as the second argument.
- */
-static void
-add_lvar_to_list(var_t *newlvar, var_t **lvar_list)
-{
- var_t *prev;
-
- /* remove from shared local list, if there */
- if (newlvar == filebench_shm->shm_var_loc_list) {
- /* on top of list, just grap */
- filebench_shm->shm_var_loc_list = newlvar->var_next;
- } else {
- /* find newvar on list and remove */
- for (prev = filebench_shm->shm_var_loc_list; prev;
- prev = prev->var_next) {
- if (prev->var_next == newlvar)
- prev->var_next = newlvar->var_next;
- }
- }
- newlvar->var_next = NULL;
-
- /* add to flowop private local list at head */
- newlvar->var_next = *lvar_list;
- *lvar_list = newlvar;
-}
-
-/*
- * Searches the attribute list for the command for any allocated local
- * variables. The attribute list is created by the parser from the list of
- * attributes supplied with certain commands, such as the define and flowop
- * commands. Places all found local vars onto the flowop's local variable
- * list.
- */
-static void
-get_attr_lvars(cmd_t *cmd, flowop_t *flowop)
-{
- attr_t *attr;
- var_t *list_tail, *orig_lvar_list;
-
- /* save the local var list */
- orig_lvar_list = flowop->fo_lvar_list;
-
- for (attr = cmd->cmd_attr_list; attr != NULL;
- attr = attr->attr_next) {
-
- if (attr->attr_name == FSA_LVAR_ASSIGN) {
- var_t *newvar, *prev;
-
- if ((newvar = (var_t *)attr->attr_avd) == NULL)
- continue;
-
- add_lvar_to_list(newvar, &flowop->fo_lvar_list);
- var_update_comp_lvars(newvar, orig_lvar_list, NULL);
- }
- }
-}
-
-/*
- * Allocates memory for a list_t structure, initializes it to zero, and
- * returns a pointer to it. On failure, returns NULL.
- */
-static list_t *
-alloc_list()
-{
- list_t *list;
-
- if ((list = malloc(sizeof (list_t))) == NULL) {
- return (NULL);
- }
-
- (void) memset(list, 0, sizeof (list_t));
- return (list);
-}
-
-
-#define USAGE1 \
-"Usage:\n" \
-"go_filebench: interpret f script and generate file workload\n" \
-"Options:\n" \
-" [-h] Display verbose help\n" \
-" [-p] Disable opening /proc to set uacct to enable truss\n"
-
-#define PARSER_CMDS \
-"create [files|filesets|processes]\n" \
-"stats [clear|snap]\n" \
-"stats command \"shell command $var1,$var2...\"\n" \
-"stats directory <directory>\n" \
-"sleep <sleep-value>\n" \
-"quit\n\n" \
-"Variables:\n" \
-"set $var = value\n" \
-" $var - regular variables\n" \
-" ${var} - internal special variables\n" \
-" $(var) - environment variables\n\n"
-
-#define PARSER_EXAMPLE \
-"Example:\n\n" \
-"#!" FILEBENCHDIR "/bin/go_filebench -f\n" \
-"\n" \
-"define file name=bigfile,path=bigfile,size=1g,prealloc,reuse\n" \
-"define process name=randomizer\n" \
-"{\n" \
-" thread random-thread procname=randomizer\n" \
-" {\n" \
-" flowop read name=random-read,filename=bigfile,iosize=16k,random\n" \
-" }\n" \
-"}\n" \
-"create files\n" \
-"create processes\n" \
-"stats clear\n" \
-"sleep 30\n" \
-"stats snap\n"
-
-/*
- * usage() display brief or verbose help for the filebench(1) command.
- */
-static void
-usage(int help)
-{
- if (help >= 1)
- (void) fprintf(stderr, USAGE1, cmdname);
- if (help >= 2) {
-
- (void) fprintf(stderr,
- "\n'f' language definition:\n\n");
- fileset_usage();
- procflow_usage();
- threadflow_usage();
- flowoplib_usage();
- eventgen_usage();
- (void) fprintf(stderr, PARSER_CMDS);
- (void) fprintf(stderr, PARSER_EXAMPLE);
- }
- exit(E_USAGE);
-}
-
-int
-yywrap()
-{
- char buf[1024];
-
- if (parentscript) {
- yyin = parentscript;
- yy_switchfilescript(yyin);
- parentscript = NULL;
- return (0);
- } else
- return (1);
-}
diff --git a/usr/src/cmd/filebench/common/parser_lex.l b/usr/src/cmd/filebench/common/parser_lex.l
deleted file mode 100644
index 4a65a77a7f..0000000000
--- a/usr/src/cmd/filebench/common/parser_lex.l
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-%{
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#include "filebench.h"
-#include "parsertypes.h"
-#include "utils.h"
-#include "parser_gram.h"
-
-int lex_lineno = 1; /* line-number for error reporting */
-extern void yyerror(char *s);
-extern int dofile; /* are we processing a file? */
-%}
-
-%s WHITESTRINGSTATE
-
-%a 50000
-%p 50000
-%o 50000
-%n 5000
-
-%%
-
-\n { lex_lineno++; }
-
-<INITIAL>[ \t]+ ;
-
-<INITIAL>#.* ;
-
-create { return FSC_CREATE; }
-define { return FSC_DEFINE; }
-debug { return FSC_DEBUG; }
-domultisync { return FSC_DOMULTISYNC; }
-echo { return FSC_ECHO; }
-enable { return FSC_ENABLE; }
-eventgen { return FSC_EVENTGEN; }
-exit { return FSC_QUIT; }
-foreach { return FSC_FOREACH; }
-flowop { return FSC_FLOWOP; }
-fscheck { return FSC_FSCHECK; }
-fsflush { return FSC_FSFLUSH; }
-help { return FSC_HELP; }
-list { return FSC_LIST; }
-load { return FSC_LOAD; }
-log { return FSC_LOG; }
-nousestats { return FSC_NOUSESTATS; }
-run { return FSC_RUN; }
-set { return FSC_SET; }
-shutdown { return FSC_SHUTDOWN; }
-sleep { return FSC_SLEEP; }
-stats { return FSC_STATS; }
-system { return FSC_SYSTEM; }
-usage { return FSC_USAGE; }
-vars { return FSC_VARS; }
-version { return FSC_VERSION; }
-warmup { return FSC_WARMUP; }
-quit { return FSC_QUIT; }
-
-file[s]* { return FSE_FILE; }
-fileset[s]* { return FSE_FILESET; }
-directory { return FSE_DIRECTORY; }
-command { return FSE_COMMAND; }
-process[es]* { return FSE_PROC; }
-thread { return FSE_THREAD; }
-randvar { return FSE_RAND; }
-clear { return FSE_CLEAR; }
-snap { return FSE_SNAP; }
-dump { return FSE_DUMP; }
-xmldump { return FSE_XMLDUMP; }
-multidump { return FSE_MULTIDUMP; }
-all { return FSE_ALL; }
-mode { return FSE_MODE; }
-multi { return FSE_MULTI; }
-
-alldone { return FSA_ALLDONE; }
-blocking { return FSA_BLOCKING; }
-cached { return FSA_CACHED; }
-client { return FSA_CLIENT; }
-dirwidth { return FSA_DIRWIDTH; }
-dirdepthrv { return FSA_DIRDEPTHRV; }
-directio { return FSA_DIRECTIO; }
-dirgamma { return FSA_DIRGAMMA; }
-dsync { return FSA_DSYNC; }
-entries { return FSA_ENTRIES;}
-fd { return FSA_FD; }
-filename { return FSA_FILE; }
-filesetname { return FSA_FILE; }
-filesize { return FSA_SIZE; }
-filesizegamma { return FSA_FILESIZEGAMMA; }
-firstdone { return FSA_FIRSTDONE; }
-fstype { return FSA_FSTYPE; }
-gamma { return FSA_RANDGAMMA; }
-highwater { return FSA_HIGHWATER; }
-indexed { return FSA_INDEXED; }
-instances { return FSA_INSTANCES;}
-iosize { return FSA_IOSIZE; }
-iters { return FSA_ITERS;}
-leafdirs { return FSA_LEAFDIRS;}
-master { return FSA_MASTER; }
-mean { return FSA_RANDMEAN; }
-memsize { return FSA_MEMSIZE; }
-min { return FSA_RANDMIN; }
-name { return FSA_NAME;}
-namelength { return FSA_NAMELENGTH; }
-nice { return FSA_NICE;}
-opennext { return FSA_ROTATEFD; }
-paralloc { return FSA_PARALLOC; }
-path { return FSA_PATH; }
-prealloc { return FSA_PREALLOC; }
-procname { return FSA_PROCESS; }
-random { return FSA_RANDOM;}
-randsrc { return FSA_RANDSRC; }
-randtable { return FSA_RANDTABLE; }
-rate { return FSA_RATE;}
-readonly { return FSA_READONLY; }
-reuse { return FSA_REUSE; }
-round { return FSA_RANDROUND; }
-seed { return FSA_RANDSEED; }
-size { return FSA_SIZE; }
-srcfd { return FSA_SRCFD; }
-target { return FSA_TARGET;}
-timeout { return FSA_TIMEOUT; }
-trusttree { return FSA_TRUSTTREE; }
-type { return FSA_TYPE; }
-useism { return FSA_USEISM;}
-value { return FSA_VALUE;}
-workingset { return FSA_WSS; }
-
-uniform { return FSV_RANDUNI; }
-tabular { return FSV_RANDTAB; }
-"."type { return FSS_TYPE; }
-"."seed { return FSS_SEED; }
-"."gamma { return FSS_GAMMA; }
-"."mean { return FSS_MEAN; }
-"."min { return FSS_MIN; }
-"."round { return FSS_ROUND; }
-"."randsrc { return FSS_SRC; }
-urandom { return FSV_URAND; }
-rand48 { return FSV_RAND48; }
-
-
-<INITIAL>\" {
- BEGIN WHITESTRINGSTATE;
- return FSK_QUOTE;
- }
-
-<WHITESTRINGSTATE>\" {
- BEGIN INITIAL;
- return FSK_QUOTE;
- }
-
-<WHITESTRINGSTATE>[^$^\\^"][^$^"]*[^\\^$^"] {
- if ((yylval.sval = strdup(yytext)) == NULL) {
- yyerror("Out of memory");
- filebench_shutdown(E_ERROR);
- }
- return FSV_WHITESTRING;
- }
-
-<WHITESTRINGSTATE>\\n {
- yylval.sval = "\n";
- return FSV_WHITESTRING;
- }
-
-
-<WHITESTRINGSTATE>\\$[^"^$^\\]+ {
- if ((yylval.sval = strdup(yytext + 1)) == NULL) {
- yyerror("Out of memory");
- filebench_shutdown(E_ERROR);
- }
- return FSV_WHITESTRING;
- }
-
-<WHITESTRINGSTATE>[^$^\\^"] {
- if ((yylval.sval = strdup(yytext)) == NULL) {
- yyerror("Out of memory");
- filebench_shutdown(E_ERROR);
- }
- return FSV_WHITESTRING;
- }
-
-
-<INITIAL>\{ { return FSK_OPENLST; }
-<INITIAL>\} { return FSK_CLOSELST; }
-<INITIAL>= { return FSK_ASSIGN; }
-<INITIAL>\, { return FSK_SEPLST; }
-<INITIAL>in { return FSK_IN; }
-<INITIAL>\+ { return FSK_PLUS; }
-<INITIAL>\- { return FSK_MINUS; }
-<INITIAL>\* { return FSK_MULTIPLY; }
-<INITIAL>\/ { return FSK_DIVIDE; }
-
-<INITIAL>[0-9]+ {
- errno = 0;
- yylval.ival = strtoll(yytext, NULL, 10);
- if (errno == EINVAL || errno == ERANGE) {
- (void) filebench_log(LOG_ERROR,
- "Invalid I value '%s':%s", yytext,
- strerror(errno));
- }
- return FSV_VAL_INT;
-}
-
-<INITIAL>[0-9]+k {
- errno = 0;
- yylval.ival = KB * strtoll(yytext, NULL, 10);
- if (errno == EINVAL || errno == ERANGE) {
- (void) filebench_log(LOG_ERROR,
- "Invalid I value '%s':%s", yytext,
- strerror(errno));
- }
- return FSV_VAL_INT;
-}
-
-<INITIAL>[0-9]+m {
- errno = 0;
- yylval.ival = MB * strtoll(yytext, NULL, 10);
- if (errno == EINVAL || errno == ERANGE) {
- (void) filebench_log(LOG_ERROR,
- "Invalid I value '%s':%s", yytext,
- strerror(errno));
- }
- return FSV_VAL_INT;
-}
-
-<INITIAL>[0-9]+g {
- errno = 0;
- yylval.ival = GB * strtoll(yytext, NULL, 10);
- if (errno == EINVAL || errno == ERANGE) {
- (void) filebench_log(LOG_ERROR,
- "Invalid I value '%s':%s", yytext,
- strerror(errno));
- }
- return FSV_VAL_INT;
-}
-
-<INITIAL>true {
- yylval.bval = TRUE;
- return FSV_VAL_BOOLEAN;
- }
-
-<INITIAL>false {
- yylval.bval = FALSE;
- return FSV_VAL_BOOLEAN;
- }
-
-$[({A-Za-z][A-Za-z0-9_]*[A-Za-z0-9][)}]* {
- if ((yylval.sval = strdup(yytext)) == NULL) {
- yyerror("Out of memory");
- filebench_shutdown(E_ERROR);
- }
-
- return FSV_VARIABLE;
- }
-
-
-$[({A-Za-z][A-Za-z0-9_]*"."[A-Za-z0-9][)}]* {
- int backtrack;
-
- if ((backtrack =
- var_is_set4_randvar(yytext)) != 0)
- yyless(yyleng - backtrack);
-
- if ((yylval.sval = strdup(yytext)) == NULL) {
- yyerror("Out of memory");
- filebench_shutdown(E_ERROR);
- }
-
- return FSV_RANDVAR;
- }
-
-
-<INITIAL>[/A-Za-z-][/A-Za-z0-9._-]* {
- if ((yylval.sval = strdup(yytext)) == NULL) {
- yyerror("Out of memory");
- filebench_shutdown(E_ERROR);
- }
- return FSV_STRING;
- }
-
-
-. {
- yyerror("Illegal character");
- }
-
-%%
-
-void
-yyerror(char *s)
-{
- if (dofile == FS_TRUE) {
- if (yytext[0] == '\0') {
- filebench_log(LOG_ERROR,
- "%s, token expected",
- s);
- return;
- }
- (void) filebench_log(LOG_ERROR,
- "%s at '%s'",
- s,
- yytext);
- } else {
- if (yytext[0] == '\0') {
- (void) filebench_log(LOG_ERROR,
- "%s, token expected", s);
- return;
- }
- (void) filebench_log(LOG_ERROR, "%s at '%s'", s, yytext);
- }
-}
-
-struct yy_buffer_state *parent;
-struct yy_buffer_state *script;
-
-int
-yy_switchfileparent(FILE *file)
-{
- script = YY_CURRENT_BUFFER;
- parent = (struct yy_buffer_state *)yy_create_buffer(yyin, 128);
- yy_switch_to_buffer(parent);
- return (0);
-}
-
-int
-yy_switchfilescript(FILE *file)
-{
- yy_switch_to_buffer(script);
- return (0);
-}
-
diff --git a/usr/src/cmd/filebench/common/parsertypes.h b/usr/src/cmd/filebench/common/parsertypes.h
deleted file mode 100644
index f66e647b20..0000000000
--- a/usr/src/cmd/filebench/common/parsertypes.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_PARSERTYPES_H
-#define _FB_PARSERTYPES_H
-
-#include "config.h"
-
-#include "filebench.h"
-#include "vars.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef sun
-typedef unsigned char uchar_t;
-#endif
-
-#define E_ERROR 1
-#define E_USAGE 2
-#define FS_FALSE 0
-#define FS_TRUE 1
-
-#define FSE_SYSTEM 1
-
-typedef struct list {
- struct list *list_next;
- avd_t list_string;
- avd_t list_integer;
-} list_t;
-
-typedef struct attr {
- int attr_name;
- struct attr *attr_next;
- avd_t attr_avd;
- list_t *attr_param_list;
- void *attr_obj;
-} attr_t;
-
-typedef struct cmd {
- void (*cmd)(struct cmd *);
- char *cmd_name;
- char *cmd_tgt1;
- char *cmd_tgt2;
- char *cmd_tgt3;
- char *thread_name;
- int cmd_subtype;
- uint64_t cmd_qty;
- struct cmd *cmd_list;
- struct cmd *cmd_next;
- attr_t *cmd_attr_list;
- list_t *cmd_param_list;
- list_t *cmd_param_list2;
-} cmd_t;
-
-typedef union {
- int64_t i;
- uchar_t b;
- char *s;
-} fs_u;
-
-typedef struct pidlist {
- struct pidlist *pl_next;
- int pl_fd;
- pid_t pl_pid;
-} pidlist_t;
-
-typedef void (*cmdfunc)(cmd_t *);
-int yy_switchfileparent(FILE *file);
-int yy_switchfilescript(FILE *file);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_PARSERTYPES_H */
diff --git a/usr/src/cmd/filebench/common/procflow.c b/usr/src/cmd/filebench/common/procflow.c
deleted file mode 100644
index 654329b5ee..0000000000
--- a/usr/src/cmd/filebench/common/procflow.c
+++ /dev/null
@@ -1,784 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#include <signal.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include "filebench.h"
-#include "procflow.h"
-#include "flowop.h"
-#include "ipc.h"
-
-/* pid and procflow pointer for this process */
-pid_t my_pid;
-procflow_t *my_procflow = NULL;
-
-static procflow_t *procflow_define_common(procflow_t **list, char *name,
- procflow_t *inherit, int instance);
-static void procflow_sleep(procflow_t *procflow, int wait_cnt);
-
-#ifdef USE_PROCESS_MODEL
-
-static enum create_n_wait {
- CNW_DONE,
- CNW_ERROR
-} cnw_wait;
-
-#endif /* USE_PROCESS_MODEL */
-
-
-/*
- * Procflows are filebench entities which manage processes. Each
- * worker procflow spawns a separate filebench process, with attributes
- * inherited from a FLOW_MASTER procflow created during f model language
- * parsing. This section contains routines to define, create, control,
- * and delete procflows.
- *
- * Each process defined in the f model creates a FLOW_MASTER
- * procflow which encapsulates the defined attributes, and threads of
- * the f process, including the number of instances to create. At
- * runtime, a worker procflow instance with an associated filebench
- * process is created, which runs until told to quite by the original
- * filebench process or is specifically deleted.
- */
-
-
-/*
- * Prints a summary of the syntax for setting procflow parameters.
- */
-void
-procflow_usage(void)
-{
- (void) fprintf(stderr,
- "define process name=<name>[,instances=<count>]\n");
- (void) fprintf(stderr, "{\n");
- (void) fprintf(stderr, " thread ...\n");
- (void) fprintf(stderr, " thread ...\n");
- (void) fprintf(stderr, " thread ...\n");
- (void) fprintf(stderr, "}\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, "\n");
-}
-
-/*
- * If filebench has been compiled to support multiple processes
- * (USE_PROCESS_MODEL defined), this routine forks a child
- * process and uses either system() or exec() to start up a new
- * instance of filebench, passing it the procflow name, instance
- * number and shared memory region address.
- * If USE_PROCESS_MODEL is NOT defined, then the routine
- * just creates a child thread which begins executing
- * threadflow_init() for the specified procflow.
- */
-static int
-procflow_createproc(procflow_t *procflow)
-{
- char instance[128];
- char shmaddr[128];
- char procname[128];
- pid_t pid;
-
-#ifdef USE_PROCESS_MODEL
-
- (void) snprintf(instance, sizeof (instance), "%d",
- procflow->pf_instance);
- (void) snprintf(procname, sizeof (procname), "%s", procflow->pf_name);
-#if defined(_LP64) || (__WORDSIZE == 64)
- (void) snprintf(shmaddr, sizeof (shmaddr), "%llx", filebench_shm);
-#else
- (void) snprintf(shmaddr, sizeof (shmaddr), "%x", filebench_shm);
-#endif
- filebench_log(LOG_DEBUG_IMPL, "creating process %s",
- procflow->pf_name);
-
- procflow->pf_running = 0;
-
-#ifdef HAVE_FORK1
- if ((pid = fork1()) < 0) {
- filebench_log(LOG_ERROR,
- "procflow_createproc fork failed: %s",
- strerror(errno));
- return (-1);
- }
-#else
- if ((pid = fork()) < 0) {
- filebench_log(LOG_ERROR,
- "procflow_createproc fork failed: %s",
- strerror(errno));
- return (-1);
- }
-#endif /* HAVE_FORK1 */
-
- /* if child, start up new copy of filebench */
- if (pid == 0) {
-#ifdef USE_SYSTEM
- char syscmd[1024];
-#endif
-
- (void) sigignore(SIGINT);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Starting %s-%d", procflow->pf_name,
- procflow->pf_instance);
- /* Child */
-
-#ifdef USE_SYSTEM
- (void) snprintf(syscmd, sizeof (syscmd), "%s -a %s -i %s -s %s",
- execname,
- procname,
- instance,
- shmaddr);
- if (system(syscmd) < 0) {
- filebench_log(LOG_ERROR,
- "procflow exec proc failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
-
-#else
- if (execlp(execname, procname, "-a", procname, "-i",
- instance, "-s", shmaddr, "-m", shmpath, NULL) < 0) {
- filebench_log(LOG_ERROR,
- "procflow exec proc failed: %s",
- strerror(errno));
- filebench_shutdown(1);
- }
-#endif
- exit(1);
- } else {
- /* if parent, save pid and return */
- procflow->pf_pid = pid;
- }
-#else
- procflow->pf_running = 1;
- if (pthread_create(&procflow->pf_tid, NULL,
- (void *(*)(void*))threadflow_init, procflow) != 0) {
- filebench_log(LOG_ERROR, "proc-thread create failed");
- procflow->pf_running = 0;
- }
-#endif
- filebench_log(LOG_DEBUG_IMPL, "procflow_createproc created pid %d",
- pid);
-
- return (0);
-}
-
-/*
- * Find a procflow of name "name" and instance "instance" on the
- * master procflow list, filebench_shm->shm_proclist. Locks the list
- * and scans through it searching for a procflow with matching
- * name and instance number. If found returns a pointer to the
- * procflow, otherwise returns NULL.
- */
-static procflow_t *
-procflow_find(char *name, int instance)
-{
- procflow_t *procflow = filebench_shm->shm_proclist;
-
- filebench_log(LOG_DEBUG_IMPL, "Find: (%s-%d) proclist = %zx",
- name, instance, procflow);
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
-
- while (procflow) {
- filebench_log(LOG_DEBUG_IMPL, "Find: (%s-%d) == (%s-%d)",
- name, instance,
- procflow->pf_name,
- procflow->pf_instance);
- if ((strcmp(name, procflow->pf_name) == 0) &&
- (instance == procflow->pf_instance)) {
-
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_procflow_lock);
-
- return (procflow);
- }
- procflow = procflow->pf_next;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
-
- return (NULL);
-}
-
-static int
-procflow_create_all_procs(void)
-{
- procflow_t *procflow = filebench_shm->shm_proclist;
- int ret = 0;
-
- while (procflow) {
- int i, instances;
-
- instances = (int)avd_get_int(procflow->pf_instances);
- filebench_log(LOG_INFO, "Starting %d %s instances",
- instances, procflow->pf_name);
-
- /* Create instances of procflow */
- for (i = 0; (i < instances) && (ret == 0); i++) {
- procflow_t *newproc;
-
- /* Create processes */
- newproc =
- procflow_define_common(&filebench_shm->shm_proclist,
- procflow->pf_name, procflow, i + 1);
- if (newproc == NULL)
- ret = -1;
- else
- ret = procflow_createproc(newproc);
- }
-
- if (ret != 0)
- break;
-
- procflow = procflow->pf_next;
- }
-
- return (ret);
-}
-
-#ifdef USE_PROCESS_MODEL
-/*
- * Used to start up threads on a child process, when filebench is
- * compiled to support multiple processes. Uses the name string
- * and instance number passed to the child to find the previously
- * created procflow entity. Then uses nice() to reduce the
- * process' priority by at least 10. A call is then made to
- * threadflow_init() which creates and runs the process' threads
- * and flowops to completion. When threadflow_init() returns,
- * a call to exit() terminates the child process.
- */
-int
-procflow_exec(char *name, int instance)
-{
- procflow_t *procflow;
- int proc_nice;
-#ifdef HAVE_SETRLIMIT
- struct rlimit rlp;
-#endif
- int ret;
-
- filebench_log(LOG_DEBUG_IMPL,
- "procflow_execproc %s-%d",
- name, instance);
-
- if ((procflow = procflow_find(name, instance)) == NULL) {
- filebench_log(LOG_ERROR,
- "procflow_exec could not find %s-%d",
- name, instance);
- return (-1);
- }
-
- /* set the slave process' procflow pointer */
- my_procflow = procflow;
-
- /* set its pid from value stored by main() */
- procflow->pf_pid = my_pid;
-
- filebench_log(LOG_DEBUG_IMPL,
- "Started up %s pid %d", procflow->pf_name, my_pid);
-
- filebench_log(LOG_DEBUG_IMPL,
- "nice = %llx", procflow->pf_nice);
-
- proc_nice = avd_get_int(procflow->pf_nice);
- filebench_log(LOG_DEBUG_IMPL, "Setting pri of %s-%d to %d",
- name, instance, nice(proc_nice + 10));
-
- procflow->pf_running = 1;
-
-#ifdef HAVE_SETRLIMIT
- /* Get resource limits */
- (void) getrlimit(RLIMIT_NOFILE, &rlp);
- filebench_log(LOG_DEBUG_SCRIPT, "%d file descriptors", rlp.rlim_cur);
-#endif
-
- if ((ret = threadflow_init(procflow)) != FILEBENCH_OK) {
- if (ret < 0) {
- filebench_log(LOG_ERROR,
- "Failed to start threads for %s pid %d",
- procflow->pf_name, my_pid);
- }
- } else {
- filebench_log(LOG_DEBUG_IMPL,
- "procflow_createproc exiting...");
- }
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procs_running_lock);
- filebench_shm->shm_procs_running --;
- (void) ipc_mutex_unlock(&filebench_shm->shm_procs_running_lock);
- procflow->pf_running = 0;
-
- return (ret);
-}
-
-
-/*
- * A special thread from which worker (child) processes are created, and
- * which then waits for worker processes to die. If they die unexpectedly,
- * that is not a simple exit(0), then report an error and terminate the
- * run.
- */
-/* ARGSUSED */
-static void *
-procflow_createnwait(void *nothing)
-{
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
-
- if (procflow_create_all_procs() == 0)
- cnw_wait = CNW_DONE;
- else
- cnw_wait = CNW_ERROR;
-
- if (pthread_cond_signal(&filebench_shm->shm_procflow_procs_cv) != 0)
- exit(1);
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
-
- /* CONSTCOND */
- while (1) {
- siginfo_t status;
-
- /* wait for any child process to exit */
- if (waitid(P_ALL, 0, &status, WEXITED) != 0)
- pthread_exit(0);
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
- /* if normal shutdown in progress, just quit */
- if (filebench_shm->shm_f_abort) {
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_procflow_lock);
- pthread_exit(0);
- }
-
- /* if nothing running, exit */
- if (filebench_shm->shm_procs_running == 0) {
- filebench_shm->shm_f_abort = FILEBENCH_ABORT_RSRC;
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_procflow_lock);
- pthread_exit(0);
- }
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
-
- if (status.si_code == CLD_EXITED) {
- /* A process called exit(); check returned status */
- if (status.si_status != 0) {
- filebench_log(LOG_ERROR,
- "Unexpected Process termination; exiting",
- status.si_status);
- filebench_shutdown(1);
- }
- } else {
- /* A process quit because of some fatal error */
- filebench_log(LOG_ERROR,
- "Unexpected Process termination Code %d, Errno %d",
- status.si_code, status.si_errno);
- filebench_shutdown(1);
- }
-
- }
- /* NOTREACHED */
- return (NULL);
-}
-
-/*
- * Cancel all threads within a processes, as well as the process itself.
- * Called by ^c or by sig_kill
- */
-/* ARGSUSED */
-static void
-procflow_cancel(int arg1)
-{
- filebench_log(LOG_DEBUG_IMPL, "Process signal handler on pid %",
- my_procflow->pf_pid);
-
- procflow_sleep(my_procflow, SHUTDOWN_WAIT_SECONDS);
-
- threadflow_delete_all(&my_procflow->pf_threads);
-
- /* quit the main procflow thread and hence the process */
- exit(0);
-}
-
-#endif /* USE_PROCESS_MODEL */
-
-/*
- * Iterates through proclist, the master list of procflows,
- * creating the number of instances of each procflow specified
- * by its pf_instance attribute. Returns 0 on success, or -1
- * times the number of procflow instances that were not
- * successfully created.
- */
-int
-procflow_init(void)
-{
- procflow_t *procflow = filebench_shm->shm_proclist;
- pthread_t tid;
- int ret = 0;
-
- if (procflow == NULL) {
- filebench_log(LOG_ERROR, "Workload has no processes");
- return (FILEBENCH_ERROR);
- }
-
- filebench_log(LOG_DEBUG_IMPL,
- "procflow_init %s, %llu",
- procflow->pf_name,
- (u_longlong_t)avd_get_int(procflow->pf_instances));
-
-#ifdef USE_PROCESS_MODEL
- if ((pthread_create(&tid, NULL, procflow_createnwait, NULL)) != 0)
- return (ret);
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
-
- (void) signal(SIGUSR1, procflow_cancel);
-
- if ((ret = pthread_cond_wait(&filebench_shm->shm_procflow_procs_cv,
- &filebench_shm->shm_procflow_lock)) != 0)
- return (ret);
-
- if (cnw_wait == CNW_ERROR)
- ret = -1;
-
-#else /* USE_PROCESS_MODEL */
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
-
- ret = procflow_create_all_procs();
-#endif /* USE_PROCESS_MODEL */
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
-
- return (ret);
-}
-
-#ifdef USE_PROCESS_MODEL
-/*
- * Waits for child processes to finish and returns their exit
- * status. Used by procflow_delete() when the process model is
- * enabled to wait for a deleted process to exit.
- */
-static void
-procflow_wait(pid_t pid)
-{
- pid_t wpid;
- int stat;
-
- (void) waitpid(pid, &stat, 0);
- while ((wpid = waitpid(getpid() * -1, &stat, WNOHANG)) > 0)
- filebench_log(LOG_DEBUG_IMPL, "Waited for pid %d", (int)wpid);
-}
-#endif
-
-/*
- * Common routine to sleep for wait_cnt seconds or for pf_running to
- * go false. Checks once a second to see if pf_running has gone false.
- */
-static void
-procflow_sleep(procflow_t *procflow, int wait_cnt)
-{
- while (procflow->pf_running & wait_cnt) {
- (void) sleep(1);
- wait_cnt--;
- }
-}
-
-/*
- * Deletes the designated procflow. Finally it frees the
- * procflow entity. filebench_shm->shm_procflow_lock must be held on entry.
- *
- * If the designated procflow is not found on the list it returns -1 and
- * the procflow is not deleted. Otherwise it returns 0.
- */
-static int
-procflow_cleanup(procflow_t *procflow)
-{
- procflow_t *entry;
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "Deleted proc: (%s-%d) pid %d",
- procflow->pf_name,
- procflow->pf_instance,
- procflow->pf_pid);
-
- procflow->pf_running = 0;
-
- /* remove entry from proclist */
- entry = filebench_shm->shm_proclist;
-
- /* unlink procflow entity from proclist */
- if (entry == procflow) {
- /* at head of list */
- filebench_shm->shm_proclist = procflow->pf_next;
- } else {
- /* search list for procflow */
- while (entry && entry->pf_next != procflow)
- entry = entry->pf_next;
-
- /* if entity found, unlink it */
- if (entry == NULL)
- return (-1);
- else
- entry->pf_next = procflow->pf_next;
- }
-
- /* free up the procflow entity */
- ipc_free(FILEBENCH_PROCFLOW, (char *)procflow);
- return (0);
-}
-
-
-/*
- * Waits till all threadflows are started, or a timeout occurs.
- * Checks through the list of procflows, waiting up to 30
- * seconds for each one to set its pf_running flag to 1. If not
- * set after 30 seconds, continues on to the next procflow
- * anyway after logging the fact. Once pf_running is set
- * to 1 for a given procflow or the timeout is reached,
- * threadflow_allstarted() is called to start the threads.
- * Returns 0 (OK), unless filebench_shm->shm_f_abort is signaled,
- * in which case it returns -1.
- */
-int
-procflow_allstarted()
-{
- procflow_t *procflow = filebench_shm->shm_proclist;
- int running_procs = 0;
- int ret = 0;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
-
- (void) sleep(1);
-
- while (procflow) {
- int waits;
-
- if (procflow->pf_instance &&
- (procflow->pf_instance == FLOW_MASTER)) {
- procflow = procflow->pf_next;
- continue;
- }
-
- waits = 10;
- while (waits && procflow->pf_running == 0) {
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_procflow_lock);
- if (filebench_shm->shm_f_abort == 1)
- return (-1);
-
- if (waits < 3)
- filebench_log(LOG_INFO,
- "Waiting for process %s-%d %d",
- procflow->pf_name,
- procflow->pf_instance,
- procflow->pf_pid);
-
- (void) sleep(3);
- waits--;
- (void) ipc_mutex_lock(
- &filebench_shm->shm_procflow_lock);
- }
-
- if (waits == 0)
- filebench_log(LOG_INFO,
- "Failed to start process %s-%d",
- procflow->pf_name,
- procflow->pf_instance);
-
- running_procs++;
- threadflow_allstarted(procflow->pf_pid, procflow->pf_threads);
-
- procflow = procflow->pf_next;
- }
- (void) ipc_mutex_lock(&filebench_shm->shm_procs_running_lock);
- filebench_shm->shm_procs_running = running_procs;
- (void) ipc_mutex_unlock(&filebench_shm->shm_procs_running_lock);
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
-
-
- return (ret);
-}
-
-
-/*
- * Sets the f_abort flag and clears the running count to stop
- * all the flowop execution threads from running. Iterates
- * through the procflow list and deletes all procflows except
- * for the FLOW_MASTER procflow. Resets the f_abort flag when
- * finished.
- *
- */
-void
-procflow_shutdown(void)
-{
- procflow_t *procflow, *next_procflow;
- int wait_cnt = SHUTDOWN_WAIT_SECONDS;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procs_running_lock);
- if (filebench_shm->shm_procs_running <= 0) {
- /* No processes running, so no need to do anything */
- (void) ipc_mutex_unlock(&filebench_shm->shm_procs_running_lock);
- return;
- }
- (void) ipc_mutex_unlock(&filebench_shm->shm_procs_running_lock);
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
- if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_FINI) {
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_procflow_lock);
- return;
- }
-
- procflow = filebench_shm->shm_proclist;
- if (filebench_shm->shm_f_abort == FILEBENCH_OK)
- filebench_shm->shm_f_abort = FILEBENCH_ABORT_DONE;
-
- while (procflow) {
- if (procflow->pf_instance &&
- (procflow->pf_instance == FLOW_MASTER)) {
- procflow = procflow->pf_next;
- continue;
- }
- filebench_log(LOG_DEBUG_IMPL, "Deleting process %s-%d %d",
- procflow->pf_name,
- procflow->pf_instance,
- procflow->pf_pid);
-
- next_procflow = procflow->pf_next;
-
- /*
- * Signalling the process with SIGUSR1 will result in it
- * gracefully shutting down and exiting
- */
- procflow_sleep(procflow, wait_cnt);
- if (procflow->pf_running) {
-#ifdef USE_PROCESS_MODEL
- pid_t pid;
-
- pid = procflow->pf_pid;
-#ifdef HAVE_SIGSEND
- (void) sigsend(P_PID, pid, SIGUSR1);
-#else
- (void) kill(pid, SIGUSR1);
-#endif
- procflow_wait(pid);
-
-#else /* USE_PROCESS_MODEL */
- threadflow_delete_all(&procflow->pf_threads);
-#endif /* USE_PROCESS_MODEL */
- }
- (void) procflow_cleanup(procflow);
- procflow = next_procflow;
- if (wait_cnt > 0)
- wait_cnt--;
- }
-
- filebench_shm->shm_f_abort = FILEBENCH_ABORT_FINI;
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
-
- /* indicate all processes are stopped, even if some are "stuck" */
- (void) ipc_mutex_lock(&filebench_shm->shm_procs_running_lock);
- filebench_shm->shm_procs_running = 0;
- (void) ipc_mutex_unlock(&filebench_shm->shm_procs_running_lock);
-}
-
-
-/*
- * Create an in-memory process object. Allocates a procflow
- * entity, initialized from the "inherit" procflow if supplied.
- * The name and instance number are set from the supplied name
- * and instance number and the procflow is added to the head of
- * the master procflow list. Returns pointer to the allocated
- * procflow, or NULL if a name isn't supplied or the procflow
- * entity cannot be allocated.
- *
- * The calling routine must hold the filebench_shm->shm_procflow_lock.
- */
-static procflow_t *
-procflow_define_common(procflow_t **list, char *name,
- procflow_t *inherit, int instance)
-{
- procflow_t *procflow;
-
- if (name == NULL)
- return (NULL);
-
- procflow = (procflow_t *)ipc_malloc(FILEBENCH_PROCFLOW);
-
- if (procflow == NULL)
- return (NULL);
-
- if (inherit)
- (void) memcpy(procflow, inherit, sizeof (procflow_t));
- else
- (void) memset(procflow, 0, sizeof (procflow_t));
-
- procflow->pf_instance = instance;
- (void) strcpy(procflow->pf_name, name);
-
- filebench_log(LOG_DEBUG_IMPL, "defining process %s-%d", name, instance);
-
- /* Add procflow to list, lock is being held already */
- if (*list == NULL) {
- *list = procflow;
- procflow->pf_next = NULL;
- } else {
- procflow->pf_next = *list;
- *list = procflow;
- }
- filebench_log(LOG_DEBUG_IMPL, "process %s-%d proclist %zx",
- name, instance, filebench_shm->shm_proclist);
-
- return (procflow);
-}
-
-/*
- * Create an in-memory process object as described by the syntax.
- * Acquires the filebench_shm->shm_procflow_lock and calls
- * procflow_define_common() to create and initialize a
- * FLOW_MASTER procflow entity from the optional "inherit"
- * procflow with the given name and configured for "instances"
- * number of worker procflows. Currently only called from
- * parser_proc_define().
- */
-procflow_t *
-procflow_define(char *name, procflow_t *inherit, avd_t instances)
-{
- procflow_t *procflow;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
-
- procflow = procflow_define_common(&filebench_shm->shm_proclist,
- name, inherit, FLOW_MASTER);
- procflow->pf_instances = instances;
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
-
- return (procflow);
-}
diff --git a/usr/src/cmd/filebench/common/procflow.h b/usr/src/cmd/filebench/common/procflow.h
deleted file mode 100644
index f60450a626..0000000000
--- a/usr/src/cmd/filebench/common/procflow.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_PROCFLOW_H
-#define _FB_PROCFLOW_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "config.h"
-
-#include "vars.h"
-#include "stats.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct procflow {
- char pf_name[128];
- int pf_instance;
- avd_t pf_instances;
- int pf_running;
- struct procflow *pf_next;
- pid_t pf_pid;
- pthread_t pf_tid;
- struct threadflow *pf_threads;
- int pf_attrs;
- avd_t pf_nice;
- flowstat_t pf_stats;
-} procflow_t;
-
-procflow_t *procflow_define(char *name, procflow_t *inherit, avd_t instances);
-int procflow_init(void);
-void procflow_shutdown(void);
-int procflow_exec(char *name, int instance);
-void procflow_usage(void);
-int procflow_allstarted(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_PROCFLOW_H */
diff --git a/usr/src/cmd/filebench/common/stats.c b/usr/src/cmd/filebench/common/stats.c
deleted file mode 100644
index 49ef7a73ae..0000000000
--- a/usr/src/cmd/filebench/common/stats.c
+++ /dev/null
@@ -1,905 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
-
-#ifdef HAVE_SYSINFO
-#include <sys/sysinfo.h>
-#endif
-
-#ifdef HAVE_LIBKSTAT
-#include <kstat.h>
-#include <sys/cpuvar.h>
-#endif /* HAVE_LIBKSTAT */
-
-#include <stdarg.h>
-
-#include "filebench.h"
-#include "flowop.h"
-#include "vars.h"
-#include "stats.h"
-
-/*
- * A set of routines for collecting and dumping various filebench
- * run statistics.
- */
-
-/* Global statistics */
-static flowstat_t *globalstats = NULL;
-
-static hrtime_t stats_cputime = 0;
-
-#ifdef HAVE_LIBKSTAT
-static kstat_ctl_t *kstatp = NULL;
-static kstat_t *sysinfo_ksp = NULL;
-static kstat_t **cpu_kstat_list = NULL;
-static int kstat_ncpus = 0;
-
-static int
-stats_build_kstat_list(void)
-{
- kstat_t *ksp;
-
- kstat_ncpus = 0;
- for (ksp = kstatp->kc_chain; ksp; ksp = ksp->ks_next)
- if (strncmp(ksp->ks_name, "cpu_stat", 8) == 0)
- kstat_ncpus++;
-
- if ((cpu_kstat_list = (kstat_t **)
- malloc(kstat_ncpus * sizeof (kstat_t *))) == NULL) {
- filebench_log(LOG_ERROR, "malloc failed");
- return (FILEBENCH_ERROR);
- }
-
- kstat_ncpus = 0;
- for (ksp = kstatp->kc_chain; ksp; ksp = ksp->ks_next)
- if (strncmp(ksp->ks_name, "cpu_stat", 8) == 0 &&
- kstat_read(kstatp, ksp, NULL) != -1)
- cpu_kstat_list[kstat_ncpus++] = ksp;
-
- if (kstat_ncpus == 0) {
- filebench_log(LOG_ERROR,
- "kstats can't find any cpu statistics");
- return (FILEBENCH_ERROR);
- }
-
- return (FILEBENCH_OK);
-}
-
-static int
-stats_kstat_update(void)
-{
- if (kstatp == NULL) {
- if ((kstatp = kstat_open()) == (kstat_ctl_t *)NULL) {
- filebench_log(LOG_ERROR, "Cannot read kstats");
- return (FILEBENCH_ERROR);
- }
- }
-
- /* get the sysinfo kstat */
- if (sysinfo_ksp == NULL)
- sysinfo_ksp = kstat_lookup(kstatp, "unix", 0, "sysinfo");
-
- /* get per cpu kstats, if necessary */
- if (cpu_kstat_list == NULL) {
-
- /* Initialize the array of cpu kstat pointers */
- if (stats_build_kstat_list() == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
-
- } else if (kstat_chain_update(kstatp) != 0) {
-
- /* free up current array of kstat ptrs and get new one */
- free((void *)cpu_kstat_list);
- if (stats_build_kstat_list() == FILEBENCH_ERROR)
- return (FILEBENCH_ERROR);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Uses the kstat library or, if it is not available, the /proc/stat file
- * to obtain cpu statistics. Collects statistics for each cpu, initializes
- * a local pointer to the sysinfo kstat, and returns the sum of user and
- * kernel time for all the cpus.
- */
-static fbint_t
-kstats_read_cpu(void)
-{
- u_longlong_t cputime_states[CPU_STATES];
- hrtime_t cputime;
- int i;
-
- /*
- * Per-CPU statistics
- */
-
- if (stats_kstat_update() == FILEBENCH_ERROR)
- return (0);
-
- /* Sum across all CPUs */
- (void) memset(&cputime_states, 0, sizeof (cputime_states));
- for (i = 0; i < kstat_ncpus; i++) {
- cpu_stat_t cpu_stats;
- int j;
-
- (void) kstat_read(kstatp, cpu_kstat_list[i],
- (void *) &cpu_stats);
- for (j = 0; j < CPU_STATES; j++)
- cputime_states[j] += cpu_stats.cpu_sysinfo.cpu[j];
- }
-
- cputime = cputime_states[CPU_KERNEL] + cputime_states[CPU_USER];
-
- return (10000000LL * cputime);
-}
-#else /* HAVE_LIBKSTAT */
-#ifdef HAVE_PROC_STAT
-static FILE *statfd = 0;
-fbint_t
-kstats_read_cpu(void)
-{
- /*
- * Linux provides system wide statistics in /proc/stat
- * The entry for cpu is
- * cpu 1636 67 1392 208671 5407 20 12
- * cpu0 626 8 997 104476 2499 7 7
- * cpu1 1010 58 395 104195 2907 13 5
- *
- * The number of jiffies (1/100ths of a second) that the
- * system spent in user mode, user mode with low priority
- * (nice), system mode, and the idle task, respectively.
- */
- unsigned int user, nice, system;
- char cpu[128]; /* placeholder to read "cpu" */
- if (statfd == 0) {
- statfd = fopen("/proc/stat", "r");
- if (statfd < 0) {
- filebench_log(LOG_ERROR, "Cannot open /proc/stat");
- return (-1);
- }
- }
- if (fscanf(statfd, "%s %u %u %u", cpu, &user, &nice, &system) < 0) {
- filebench_log(LOG_ERROR, "Cannot read /proc/stat");
- return (-1);
- }
- /* convert jiffies to nanosecs */
- return ((user+nice+system)*1000000);
-}
-
-#else /* HAVE_PROC_STAT */
-fbint_t
-kstats_read_cpu(void)
-{
- return (0);
-}
-#endif
-#endif /* HAVE_LIBKSTAT */
-
-/*
- * Returns the net cpu time used since the beginning of the run.
- * Just calls kstat_read_cpu() and subtracts stats_cputime which
- * is set at the beginning of the filebench run.
- */
-static hrtime_t
-kstats_read_cpu_relative(void)
-{
- hrtime_t cputime;
-
- cputime = kstats_read_cpu();
- return (cputime - stats_cputime);
-}
-
-/*
- * IO Overhead CPU is the amount of CPU that is incurred running
- * the benchmark infrastructure.
- *
- * It is computed as the sum of micro-state cpu time for each
- * thread around the op being tested.
- *
- * Overhead time is computed for each flow.
- *
- * System overhead is computed as the overhead for I/O flows
- * plus all other time running non-io related flowops
- *
- */
-
-/*
- * Computes and returns the overhead CPU time attibutable to
- * IO type flowops.
- */
-static hrtime_t
-io_stats_ohead(void)
-{
- flowstat_t *iostat = &globalstats[FLOW_TYPE_IO];
- flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO];
- flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL];
-
- filebench_log(LOG_DEBUG_NEVER,
- "Computing overhead as %llu + %llu - %llu - %llu",
- (u_longlong_t)glstat->fs_mstate[FLOW_MSTATE_OHEAD],
- (u_longlong_t)glstat->fs_mstate[FLOW_MSTATE_CPU],
- (u_longlong_t)iostat->fs_mstate[FLOW_MSTATE_CPU],
- (u_longlong_t)aiostat->fs_mstate[FLOW_MSTATE_CPU]);
-
- return ((glstat->fs_mstate[FLOW_MSTATE_OHEAD] +
- glstat->fs_mstate[FLOW_MSTATE_CPU] -
- iostat->fs_mstate[FLOW_MSTATE_CPU] -
- aiostat->fs_mstate[FLOW_MSTATE_CPU]));
-}
-
-/*
- * Returns the total overhead CPU time.
- */
-static hrtime_t
-gl_stats_ohead(void)
-{
- flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL];
-
- return (glstat->fs_mstate[FLOW_MSTATE_OHEAD]);
-}
-
-/*
- * Places the value represented by "name" into the var_val.integer field of the
- * supplied var_t. Compares the supplied "name" with a set of predefined
- * names and calculates the value from the appropriate globalstats field(s).
- */
-var_t *
-stats_findvar(var_t *var, char *name)
-{
- flowstat_t *iostat = &globalstats[FLOW_TYPE_IO];
- flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO];
- flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL];
-
- filebench_log(LOG_DEBUG_IMPL, "reading stats %s", name);
-
- if (globalstats == NULL)
- globalstats = malloc(FLOW_TYPES * sizeof (flowstat_t));
-
- if (strcmp(name, "iocount") == 0) {
- fbint_t stat;
-
- stat = iostat->fs_count + aiostat->fs_count;
- VAR_SET_INT(var, stat);
- filebench_log(LOG_DEBUG_IMPL, "reading stats %s = %llu",
- name, (u_longlong_t)stat);
- return (var);
- }
-
- if (strcmp(name, "iorate") == 0) {
- fbint_t stat;
-
- /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
- stat = (iostat->fs_count + aiostat->fs_count) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS);
- VAR_SET_INT(var, stat);
- return (var);
- }
-
-
- if (strcmp(name, "ioreadrate") == 0) {
- fbint_t stat;
-
- /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
- stat = (iostat->fs_rcount + aiostat->fs_rcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS);
- VAR_SET_INT(var, stat);
- return (var);
- }
-
-
- if (strcmp(name, "iowriterate") == 0) {
- fbint_t stat;
-
- /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
- stat = (iostat->fs_wcount + aiostat->fs_wcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS);
- VAR_SET_INT(var, stat);
- return (var);
- }
-
-
- if (strcmp(name, "iobandwidth") == 0) {
- fbint_t stat;
-
- /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
- stat =
- ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS);
- VAR_SET_INT(var, stat);
- return (var);
- }
-
- if (strcmp(name, "iolatency") == 0) {
- fbint_t stat;
-
- stat = iostat->fs_count ? iostat->fs_mstate[FLOW_MSTATE_LAT] /
- (iostat->fs_count * 1000UL) : 0;
- VAR_SET_INT(var, stat);
- return (var);
- }
-
- if (strcmp(name, "iocpu") == 0) {
- fbint_t stat;
-
- stat = (iostat->fs_count + aiostat->fs_count) ?
- (iostat->fs_mstate[FLOW_MSTATE_CPU] +
- aiostat->fs_mstate[FLOW_MSTATE_CPU]) / ((iostat->fs_count +
- aiostat->fs_count) * 1000UL) : 0;
- VAR_SET_INT(var, stat);
- return (var);
- }
-
-
- if (strcmp(name, "oheadcpu") == 0) {
- fbint_t stat;
-
- stat = (iostat->fs_count + aiostat->fs_count) ?
- io_stats_ohead() / ((iostat->fs_count +
- aiostat->fs_count) * 1000UL) : 0;
- VAR_SET_INT(var, stat);
- return (var);
- }
-
- if (strcmp(name, "iowait") == 0) {
- fbint_t stat;
-
- stat = iostat->fs_count ?
- iostat->fs_mstate[FLOW_MSTATE_WAIT] /
- (iostat->fs_count * 1000UL) : 0;
- VAR_SET_INT(var, stat);
- return (var);
- }
-
- if (strcmp(name, "syscpu") == 0) {
- fbint_t stat;
-
- /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
- stat = glstat->fs_syscpu / 1000.0;
- VAR_SET_INT(var, stat);
- return (var);
- }
-
- if (strcmp(name, "iocpusys") == 0) {
- fbint_t stat;
-
- stat = (iostat->fs_count + aiostat->fs_count) ?
- iostat->fs_syscpu / ((iostat->fs_count +
- aiostat->fs_count) * 1000UL) : 0;
-
- VAR_SET_INT(var, stat);
- return (var);
- }
-
- filebench_log(LOG_DEBUG_IMPL,
- "error reading stats %s", name);
-
- return (NULL);
-}
-
-/*
- * Initializes the static variable "stats_cputime" with the
- * current cpu time, for use by kstats_read_cpu_relative.
- */
-void
-stats_init(void)
-{
-#if defined(HAVE_LIBKSTAT) || defined(LINUX_PORT)
- stats_cputime = kstats_read_cpu();
-#else
- stats_cputime = 0;
-#endif /* HAVE_LIBKSTAT */
-}
-
-/*
- * Add a flowstat b to a, leave sum in a.
- */
-static void
-stats_add(flowstat_t *a, flowstat_t *b)
-{
- int i;
-
- a->fs_count += b->fs_count;
- a->fs_rcount += b->fs_rcount;
- a->fs_wcount += b->fs_wcount;
- a->fs_bytes += b->fs_bytes;
- a->fs_rbytes += b->fs_rbytes;
- a->fs_wbytes += b->fs_wbytes;
-
- for (i = 0; i < FLOW_MSTATES; i++)
- a->fs_mstate[i] += b->fs_mstate[i];
-}
-
-/*
- * Takes a "snapshot" of the global statistics. Actually, it calculates
- * them from the local statistics maintained by each flowop.
- * First the routine pauses filebench, then rolls the statistics for
- * each flowop into its associated FLOW_MASTER flowop.
- * Next all the FLOW_MASTER flowops' statistics are written
- * to the log file followed by the global totals. Then filebench
- * operation is allowed to resume.
- */
-void
-stats_snap(void)
-{
- flowstat_t *iostat = &globalstats[FLOW_TYPE_IO];
- flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO];
- flowstat_t *glstat = &globalstats[FLOW_TYPE_GLOBAL];
- hrtime_t cputime;
- flowop_t *flowop;
- char *str;
-
- if (globalstats == NULL) {
- filebench_log(LOG_ERROR,
- "'stats snap' called before 'stats clear'");
- return;
- }
-
- /* don't print out if run ended in error */
- if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR) {
- filebench_log(LOG_ERROR,
- "NO VALID RESULTS! FileBench run terminated prematurely");
- return;
- }
-
- globalstats->fs_etime = gethrtime();
-
- filebench_log(LOG_DEBUG_SCRIPT, "Stats period = %ds",
- (globalstats->fs_etime - globalstats->fs_stime) / 1000000000);
-
- /* Freeze statistics during update */
- filebench_shm->shm_bequiet = 1;
-
- flowop = filebench_shm->shm_flowoplist;
- while (flowop) {
- flowop_t *flowop_master;
-
- if (flowop->fo_instance <= FLOW_DEFINITION) {
- flowop = flowop->fo_next;
- continue;
- }
-
- flowop_master = flowop_find_one(flowop->fo_name, FLOW_MASTER);
-
- /* Roll up per-flowop into global stats */
- stats_add(&globalstats[flowop->fo_type],
- &flowop->fo_stats);
- stats_add(&globalstats[FLOW_TYPE_GLOBAL],
- &flowop->fo_stats);
-
- if (flowop_master && IS_FLOW_ACTIVE(flowop)) {
- flowop_master->fo_stats.fs_active++;
- }
-
- if (flowop_master) {
- /* Roll up per-flow stats into master */
- flowop_master->fo_stats.fs_children++;
- stats_add(&flowop_master->fo_stats, &flowop->fo_stats);
- } else {
- filebench_log(LOG_DEBUG_NEVER,
- "flowop_stats could not find %s",
- flowop->fo_name);
- }
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "flowop %-20s-%4d - %5d ops, %5.1lf, ops/s %5.1lfmb/s "
- "%8.3fms/op",
- flowop->fo_name,
- flowop->fo_instance,
- flowop->fo_stats.fs_count,
- flowop->fo_stats.fs_count /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- (flowop->fo_stats.fs_bytes / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] /
- (flowop->fo_stats.fs_count * 1000000.0) : 0);
-
- flowop = flowop->fo_next;
-
- }
-
-#if defined(HAVE_LIBKSTAT) || defined(LINUX_PORT)
- cputime = kstats_read_cpu_relative();
-#endif /* HAVE_LIBKSTAT */
-
- filebench_log(LOG_DEBUG_IMPL,
- "cputime = %llu, ohead = %llu",
- (u_longlong_t)(cputime / 1000000000),
- (u_longlong_t)(io_stats_ohead() / 1000000000));
- iostat->fs_syscpu =
- (cputime > io_stats_ohead()) ?
- (cputime - io_stats_ohead()) : 0;
- glstat->fs_syscpu =
- (cputime > gl_stats_ohead()) ?
- (cputime - gl_stats_ohead()) : 0;
-
-
- flowop = filebench_shm->shm_flowoplist;
- str = malloc(1048576);
- *str = '\0';
- (void) strcpy(str, "Per-Operation Breakdown\n");
- while (flowop) {
- char line[1024];
-
- if (flowop->fo_instance != FLOW_MASTER) {
- flowop = flowop->fo_next;
- continue;
- }
-
- (void) snprintf(line, sizeof (line), "%-20s %8.0lfops/s "
- "%5.1lfmb/s %8.1fms/op %8.0fus/op-cpu\n",
- flowop->fo_name,
- flowop->fo_stats.fs_count /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- (flowop->fo_stats.fs_bytes / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] /
- (flowop->fo_stats.fs_count * 1000000.0) : 0,
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] /
- (flowop->fo_stats.fs_count * 1000.0) : 0);
- (void) strcat(str, line);
-
- flowop = flowop->fo_next;
- }
-
- filebench_log(LOG_INFO, "%s", str);
- free(str);
-
- filebench_log(LOG_INFO,
- "\nIO Summary: %5d ops, %5.1lf ops/s, (%0.0lf/%0.0lf r/w) "
- "%5.1lfmb/s, %6.0fus cpu/op, %5.1fms latency",
- iostat->fs_count + aiostat->fs_count,
- (iostat->fs_count + aiostat->fs_count) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- (iostat->fs_rcount + aiostat->fs_rcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- (iostat->fs_wcount + aiostat->fs_wcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- (iostat->fs_rcount + iostat->fs_wcount +
- aiostat->fs_rcount + aiostat->fs_wcount) ?
- (iostat->fs_syscpu / 1000.0) /
- (iostat->fs_rcount + iostat->fs_wcount +
- aiostat->fs_rcount + aiostat->fs_wcount) : 0,
- (iostat->fs_rcount + iostat->fs_wcount) ?
- iostat->fs_mstate[FLOW_MSTATE_LAT] /
- ((iostat->fs_rcount + iostat->fs_wcount) * 1000000.0) : 0);
-
-
- filebench_shm->shm_bequiet = 0;
-}
-
-/*
- * Dumps the per-operation statistics and global statistics to the dump file.
- */
-void
-stats_dump(char *filename)
-{
- flowstat_t *iostat = &globalstats[FLOW_TYPE_IO];
- flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO];
- flowop_t *flowop;
-
- /* don't dump stats if run ended in error */
- if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR)
- return;
-
- (void) strcpy(filebench_shm->shm_dump_filename, filename);
-
- filebench_log(LOG_INFO, "in statsdump %s", filename);
-
- if (filebench_shm->shm_dump_fd > 0) {
- (void) close(filebench_shm->shm_dump_fd);
- filebench_shm->shm_dump_fd = -1;
- }
-
- filebench_log(LOG_DUMP, "Flowop totals:");
-
- flowop = filebench_shm->shm_flowoplist;
- while (flowop) {
-
- if (flowop->fo_instance != FLOW_MASTER) {
- flowop = flowop->fo_next;
- continue;
- }
-
- filebench_log(LOG_DUMP,
- "%-20s %8.0lfops/s %5.1lfmb/s "
- "%8.1fms/op %8.0fus/op-cpu",
- flowop->fo_name,
- flowop->fo_stats.fs_count /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- (flowop->fo_stats.fs_bytes / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] /
- (flowop->fo_stats.fs_count * 1000000.0) : 0,
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] /
- (flowop->fo_stats.fs_count * 1000.0) : 0);
-
- flowop = flowop->fo_next;
- }
-
- filebench_log(LOG_DUMP, "");
- filebench_log(LOG_DUMP,
- "IO Summary: %8d ops %8.1lf ops/s, %8.0lf/%0.0lf r/w"
- "%8.1lfmb/s, %8.0fuscpu/op",
-
- iostat->fs_count + aiostat->fs_count,
- (iostat->fs_count + aiostat->fs_count) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- (iostat->fs_rcount + aiostat->fs_rcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- (iostat->fs_wcount + aiostat->fs_wcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- (iostat->fs_rcount + iostat->fs_wcount +
- aiostat->fs_rcount + aiostat->fs_wcount) ?
- (iostat->fs_syscpu / 1000.0) /
- (iostat->fs_rcount + iostat->fs_wcount +
- aiostat->fs_rcount + aiostat->fs_wcount) : 0);
-}
-
-/*
- * Same as stats_dump, but in xml format.
- */
-void
-stats_xmldump(char *filename)
-{
- flowstat_t *iostat = &globalstats[FLOW_TYPE_IO];
- flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO];
- flowop_t *flowop;
-
- /* don't dump stats if run ended in error */
- if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR)
- return;
-
- (void) strcpy(filebench_shm->shm_dump_filename, filename);
-
- if (filebench_shm->shm_dump_fd > 0) {
- (void) close(filebench_shm->shm_dump_fd);
- filebench_shm->shm_dump_fd = -1;
- }
-
- filebench_log(LOG_DUMP, "<stat_doc name=\"Filebench Workload\">");
- filebench_log(LOG_DUMP, "<stat_group name=\"Flowop totals\">");
- filebench_log(LOG_DUMP, "<cell_list>");
-
- flowop = filebench_shm->shm_flowoplist;
- while (flowop) {
- if (flowop->fo_instance != FLOW_MASTER) {
- flowop = flowop->fo_next;
- continue;
- }
-
- filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>",
- flowop->fo_stats.fs_count /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS));
- filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>",
- (flowop->fo_stats.fs_bytes / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS));
- filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>",
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] /
- (flowop->fo_stats.fs_count * 1000000.0) : 0);
- filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>",
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] /
- (flowop->fo_stats.fs_count * 1000.0) : 0);
-
- flowop = flowop->fo_next;
- }
- filebench_log(LOG_DUMP, "</cell_list>");
-
- filebench_log(LOG_DUMP, "<dim_list>");
- filebench_log(LOG_DUMP, "<dim>");
- filebench_log(LOG_DUMP, "<dimval>Operations/sec</dimval>");
- filebench_log(LOG_DUMP, "<dimval>MB/sec</dimval>");
- filebench_log(LOG_DUMP, "<dimval>Latency (ms per operation)</dimval>");
- filebench_log(LOG_DUMP, "<dimval>CPU (us per operation)</dimval>");
- filebench_log(LOG_DUMP, "</dim>");
-
- filebench_log(LOG_DUMP, "<dim>");
- flowop = filebench_shm->shm_flowoplist;
- while (flowop) {
- if (flowop->fo_instance != FLOW_MASTER) {
- flowop = flowop->fo_next;
- continue;
- }
- filebench_log(LOG_DUMP, "<dimval>%s</dimval>", flowop->fo_name);
- flowop = flowop->fo_next;
- }
- filebench_log(LOG_DUMP, "</dim>");
- filebench_log(LOG_DUMP, "</dim_list>");
- filebench_log(LOG_DUMP, "</stat_group>");
-
- filebench_log(LOG_DUMP, "<stat_group name=\"IO Summary\">");
- filebench_log(LOG_DUMP, "<cell_list>");
- filebench_log(LOG_DUMP, "<cell>%0d</cell>",
- iostat->fs_count + aiostat->fs_count);
- filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>",
- (iostat->fs_count + aiostat->fs_count) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS));
- filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>",
- (iostat->fs_rcount + aiostat->fs_rcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS));
- filebench_log(LOG_DUMP, "<cell>%0.0lf</cell>",
- (iostat->fs_wcount + aiostat->fs_wcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS));
- filebench_log(LOG_DUMP, "<cell>%0.1lf</cell>",
- ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS));
- filebench_log(LOG_DUMP, "<cell>%0.0f</cell>",
- (iostat->fs_rcount + iostat->fs_wcount + aiostat->fs_rcount +
- aiostat->fs_wcount) ? (iostat->fs_syscpu / 1000.0) /
- (iostat->fs_rcount + iostat->fs_wcount + aiostat->fs_rcount +
- aiostat->fs_wcount) : 0);
- filebench_log(LOG_DUMP, "</cell_list>");
-
- filebench_log(LOG_DUMP, "<dim_list>");
- filebench_log(LOG_DUMP, "<dim>");
- filebench_log(LOG_DUMP, "<dimval>Operations</dimval>");
- filebench_log(LOG_DUMP, "<dimval>Operations/sec</dimval>");
- filebench_log(LOG_DUMP, "<dimval>Reads</dimval>");
- filebench_log(LOG_DUMP, "<dimval>Writes</dimval>");
- filebench_log(LOG_DUMP, "<dimval>MB/sec</dimval>");
- filebench_log(LOG_DUMP, "<dimval>CPU (us per operation)</dimval>");
- filebench_log(LOG_DUMP, "</dim>");
-
- filebench_log(LOG_DUMP, "<dim>");
- filebench_log(LOG_DUMP, "<dimval>IO Summary</dimval>");
- filebench_log(LOG_DUMP, "</dim>");
- filebench_log(LOG_DUMP, "</dim_list>");
- filebench_log(LOG_DUMP, "</stat_group>");
- filebench_log(LOG_DUMP, "</stat_doc>");
-}
-
-/*
- * same as stats_dump, but in computer friendly format
- */
-void
-stats_multidump(char *filename)
-{
- flowstat_t *iostat = &globalstats[FLOW_TYPE_IO];
- flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO];
- flowop_t *flowop;
-
- /* don't dump stats if run ended in error */
- if (filebench_shm->shm_f_abort == FILEBENCH_ABORT_ERROR)
- return;
-
- (void) strcpy(filebench_shm->shm_dump_filename, filename);
-
- filebench_log(LOG_INFO, "in statsmultidump %s", filename);
-
- if (filebench_shm->shm_dump_fd > 0) {
- (void) close(filebench_shm->shm_dump_fd);
- filebench_shm->shm_dump_fd = -1;
- }
-
- filebench_log(LOG_DUMP, "Flowop totals:");
-
- flowop = filebench_shm->shm_flowoplist;
- while (flowop) {
-
- if (flowop->fo_instance != FLOW_MASTER) {
- flowop = flowop->fo_next;
- continue;
- }
-
- filebench_log(LOG_DUMP,
- "%s\t%1.0lf\t%1.1lf\t%1.1f\t%1.0f",
- flowop->fo_name,
- flowop->fo_stats.fs_count /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- (flowop->fo_stats.fs_bytes / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_LAT] /
- (flowop->fo_stats.fs_count * 1000000.0) : 0,
- flowop->fo_stats.fs_count ?
- flowop->fo_stats.fs_mstate[FLOW_MSTATE_CPU] /
- (flowop->fo_stats.fs_count * 1000.0) : 0);
-
- flowop = flowop->fo_next;
- }
-
- filebench_log(LOG_DUMP, "");
- filebench_log(LOG_DUMP,
- "IO Summary:\n%d\t%1.1lf\t%1.0lf\t%1.0lf\t%1.1lf\t%1.0f\t%1.1f\n",
-
- iostat->fs_count + aiostat->fs_count,
-
- (iostat->fs_count + aiostat->fs_count) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- (iostat->fs_rcount + aiostat->fs_rcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- (iostat->fs_wcount + aiostat->fs_wcount) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- ((iostat->fs_bytes + aiostat->fs_bytes) / (1024 * 1024)) /
- ((globalstats->fs_etime - globalstats->fs_stime) / FSECS),
-
- (iostat->fs_rcount + iostat->fs_wcount +
- aiostat->fs_rcount + aiostat->fs_wcount) ?
- (iostat->fs_syscpu / 1000.0) /
- (iostat->fs_rcount + iostat->fs_wcount +
- aiostat->fs_rcount + aiostat->fs_wcount) : 0,
-
- (iostat->fs_rcount + iostat->fs_wcount) ?
- iostat->fs_mstate[FLOW_MSTATE_LAT] /
- ((iostat->fs_rcount + iostat->fs_wcount) * 1000000.0) : 0);
-}
-
-/*
- * Clears all the statistics variables (fo_stats) for every defined flowop.
- * It also creates a global flowstat table if one doesn't already exist and
- * clears it.
- */
-void
-stats_clear(void)
-{
- flowop_t *flowop;
-
-#ifdef HAVE_LIBKSTAT
- stats_cputime = kstats_read_cpu();
-#else
- stats_cputime = 0;
-#endif /* HAVE_LIBKSTAT */
-
- if (globalstats == NULL)
- globalstats = malloc(FLOW_TYPES * sizeof (flowstat_t));
-
- (void) memset(globalstats, 0, FLOW_TYPES * sizeof (flowstat_t));
-
- flowop = filebench_shm->shm_flowoplist;
-
- while (flowop) {
- filebench_log(LOG_DEBUG_IMPL, "Clearing stats for %s-%d",
- flowop->fo_name,
- flowop->fo_instance);
- (void) memset(&flowop->fo_stats, 0, sizeof (flowstat_t));
- flowop = flowop->fo_next;
- }
-
- (void) memset(globalstats, 0, sizeof (flowstat_t));
- globalstats->fs_stime = gethrtime();
-}
diff --git a/usr/src/cmd/filebench/common/stats.h b/usr/src/cmd/filebench/common/stats.h
deleted file mode 100644
index 346a4c05a3..0000000000
--- a/usr/src/cmd/filebench/common/stats.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_STATS_H
-#define _FB_STATS_H
-
-#include "config.h"
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-var_t *stats_findvar(var_t *var, char *name);
-void stats_init(void);
-void stats_clear(void);
-void stats_snap(void);
-void stats_dump(char *filename);
-void stats_xmldump(char *filename);
-void stats_multidump(char *filename);
-
-#ifndef HAVE_HRTIME
-/* typedef uint64_t hrtime_t; */
-#define hrtime_t uint64_t
-#endif
-
-#define STATS_VAR "stats."
-
-#define FLOW_MSTATES 4
-#define FLOW_MSTATE_LAT 0 /* Total service time of op */
-#define FLOW_MSTATE_CPU 1 /* On-cpu time of op */
-#define FLOW_MSTATE_WAIT 2 /* Wait-time, excluding waiting for CPU */
-#define FLOW_MSTATE_OHEAD 3 /* overhead time, around op */
-
-typedef struct flowstats {
- int fs_children; /* Number of contributors */
- int fs_active; /* Number of active contributors */
- int fs_count; /* Number of ops */
- uint64_t fs_rbytes; /* Number of bytes */
- uint64_t fs_wbytes; /* Number of bytes */
- uint64_t fs_bytes; /* Number of bytes */
- uint64_t fs_rcount; /* Number of ops */
- uint64_t fs_wcount; /* Number of ops */
- hrtime_t fs_stime; /* Time stats for flow started */
- hrtime_t fs_etime; /* Time stats for flow ended */
- hrtime_t fs_mstate[FLOW_MSTATES]; /* Microstate breakdown */
- hrtime_t fs_syscpu; /* System wide cpu, global only */
-} flowstat_t;
-
-
-#define IS_FLOW_IOP(x) (x->fo_stats.fs_rcount + x->fo_stats.fs_wcount)
-#define STAT_IOPS(x) ((x->fs_rcount) + (x->fs_wcount))
-#define IS_FLOW_ACTIVE(x) (x->fo_stats.fs_count)
-#define STAT_CPUTIME(x) (x->fs_cpu_op)
-#define STAT_OHEADTIME(x) (x->fs_cpu_ohead)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_STATS_H */
diff --git a/usr/src/cmd/filebench/common/threadflow.c b/usr/src/cmd/filebench/common/threadflow.c
deleted file mode 100644
index 9a6d96aceb..0000000000
--- a/usr/src/cmd/filebench/common/threadflow.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#include "config.h"
-#include <pthread.h>
-#ifdef HAVE_LWPS
-#include <sys/lwp.h>
-#endif
-#include <signal.h>
-
-#include "filebench.h"
-#include "threadflow.h"
-#include "flowop.h"
-#include "ipc.h"
-
-static threadflow_t *threadflow_define_common(procflow_t *procflow,
- char *name, threadflow_t *inherit, int instance);
-
-/*
- * Threadflows are filebench entities which manage operating system
- * threads. Each worker threadflow spawns a separate filebench thread,
- * with attributes inherited from a FLOW_MASTER threadflow created during
- * f model language parsing. This section contains routines to define,
- * create, control, and delete threadflows.
- *
- * Each thread defined in the f model creates a FLOW_MASTER
- * threadflow which encapsulates the defined attributes and flowops of
- * the f language thread, including the number of instances to create.
- * At runtime, a worker threadflow instance with an associated filebench
- * thread is created, which runs until told to quit or is specifically
- * deleted.
- */
-
-
-/*
- * Prints information about threadflow syntax.
- */
-void
-threadflow_usage(void)
-{
- (void) fprintf(stderr, " thread name=<name>[,instances=<count>]\n");
- (void) fprintf(stderr, "\n");
- (void) fprintf(stderr, " {\n");
- (void) fprintf(stderr, " flowop ...\n");
- (void) fprintf(stderr, " flowop ...\n");
- (void) fprintf(stderr, " flowop ...\n");
- (void) fprintf(stderr, " }\n");
- (void) fprintf(stderr, "\n");
-}
-
-/*
- * Creates a thread for the supplied threadflow. If interprocess
- * shared memory is desired, then increments the amount of shared
- * memory needed by the amount specified in the threadflow's
- * tf_memsize parameter. The thread starts in routine
- * flowop_start() with a poineter to the threadflow supplied
- * as the argument.
- */
-static int
-threadflow_createthread(threadflow_t *threadflow)
-{
- fbint_t memsize;
- memsize = avd_get_int(threadflow->tf_memsize);
- threadflow->tf_constmemsize = memsize;
-
- filebench_log(LOG_DEBUG_SCRIPT, "Creating thread %s, memory = %ld",
- threadflow->tf_name, memsize);
-
- if (threadflow->tf_attrs & THREADFLOW_USEISM)
- filebench_shm->shm_required += memsize;
-
- if (pthread_create(&threadflow->tf_tid, NULL,
- (void *(*)(void*))flowop_start, threadflow) != 0) {
- filebench_log(LOG_ERROR, "thread create failed");
- filebench_shutdown(1);
- return (FILEBENCH_ERROR);
- }
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Creates threads for the threadflows associated with a procflow.
- * The routine iterates through the list of threadflows in the
- * supplied procflow's pf_threads list. For each threadflow on
- * the list, it defines tf_instances number of cloned
- * threadflows, and then calls threadflow_createthread() for
- * each to create and start the actual operating system thread.
- * Note that each of the newly defined threadflows will be linked
- * into the procflows threadflow list, but at the head of the
- * list, so they will not become part of the supplied set. After
- * all the threads have been created, threadflow_init enters
- * a join loop for all the threads in the newly defined
- * threadflows. Once all the created threads have exited,
- * threadflow_init will return 0. If errors are encountered, it
- * will return a non zero value.
- */
-int
-threadflow_init(procflow_t *procflow)
-{
- threadflow_t *threadflow = procflow->pf_threads;
- int ret = 0;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_threadflow_lock);
-
- while (threadflow) {
- threadflow_t *newthread;
- int instances;
- int i;
-
- instances = avd_get_int(threadflow->tf_instances);
- filebench_log(LOG_VERBOSE,
- "Starting %d %s threads",
- instances, threadflow->tf_name);
-
- for (i = 1; i < instances; i++) {
- /* Create threads */
- newthread =
- threadflow_define_common(procflow,
- threadflow->tf_name, threadflow, i + 1);
- if (newthread == NULL)
- return (-1);
- ret |= threadflow_createthread(newthread);
- }
-
- newthread = threadflow_define_common(procflow,
- threadflow->tf_name,
- threadflow, 1);
-
- if (newthread == NULL)
- return (-1);
-
- /* Create each thread */
- ret |= threadflow_createthread(newthread);
-
- threadflow = threadflow->tf_next;
- }
-
- threadflow = procflow->pf_threads;
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_threadflow_lock);
-
- while (threadflow) {
- /* wait for all threads to finish */
- if (threadflow->tf_tid) {
- void *status;
-
- if (pthread_join(threadflow->tf_tid, &status) == 0)
- ret += *(int *)status;
- }
- threadflow = threadflow->tf_next;
- }
-
- procflow->pf_running = 0;
-
- return (ret);
-}
-
-/*
- * Tells the threadflow's thread to stop and optionally signals
- * its associated process to end the thread.
- */
-static void
-threadflow_kill(threadflow_t *threadflow)
-{
- int wait_cnt = 2;
-
- /* Tell thread to finish */
- threadflow->tf_abort = 1;
-
- /* wait a bit for threadflow to stop */
- while (wait_cnt && threadflow->tf_running) {
- (void) sleep(1);
- wait_cnt--;
- }
-
- if (threadflow->tf_running) {
- threadflow->tf_running = FALSE;
- (void) pthread_kill(threadflow->tf_tid, SIGKILL);
- }
-}
-
-/*
- * Deletes the specified threadflow from the specified threadflow
- * list after first terminating the threadflow's thread, deleting
- * the threadflow's flowops, and finally freeing the threadflow
- * entity. It also subtracts the threadflow's shared memory
- * requirements from the total amount required, shm_required. If
- * the specified threadflow is found, returns 0, otherwise
- * returns -1.
- */
-static int
-threadflow_delete(threadflow_t **threadlist, threadflow_t *threadflow)
-{
- threadflow_t *entry = *threadlist;
-
- filebench_log(LOG_DEBUG_IMPL, "Deleting thread: (%s-%d)",
- threadflow->tf_name,
- threadflow->tf_instance);
-
- if (threadflow->tf_attrs & THREADFLOW_USEISM)
- filebench_shm->shm_required -= threadflow->tf_constmemsize;
-
- if (threadflow == *threadlist) {
- /* First on list */
- filebench_log(LOG_DEBUG_IMPL, "Deleted thread: (%s-%d)",
- threadflow->tf_name,
- threadflow->tf_instance);
-
- threadflow_kill(threadflow);
- flowop_delete_all(&threadflow->tf_thrd_fops);
- *threadlist = threadflow->tf_next;
- (void) pthread_mutex_destroy(&threadflow->tf_lock);
- ipc_free(FILEBENCH_THREADFLOW, (char *)threadflow);
- return (0);
- }
-
- while (entry->tf_next) {
- filebench_log(LOG_DEBUG_IMPL,
- "Delete thread: (%s-%d) == (%s-%d)",
- entry->tf_next->tf_name,
- entry->tf_next->tf_instance,
- threadflow->tf_name,
- threadflow->tf_instance);
-
- if (threadflow == entry->tf_next) {
- /* Delete */
- filebench_log(LOG_DEBUG_IMPL,
- "Deleted thread: (%s-%d)",
- entry->tf_next->tf_name,
- entry->tf_next->tf_instance);
- threadflow_kill(entry->tf_next);
- flowop_delete_all(&entry->tf_next->tf_thrd_fops);
- (void) pthread_mutex_destroy(&threadflow->tf_lock);
- ipc_free(FILEBENCH_THREADFLOW, (char *)threadflow);
- entry->tf_next = entry->tf_next->tf_next;
- return (0);
- }
- entry = entry->tf_next;
- }
-
- return (-1);
-}
-
-/*
- * Given a pointer to the thread list of a procflow, cycles
- * through all the threadflows on the list, deleting each one
- * except the FLOW_MASTER.
- */
-void
-threadflow_delete_all(threadflow_t **threadlist)
-{
- threadflow_t *threadflow;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_threadflow_lock);
-
- threadflow = *threadlist;
- filebench_log(LOG_DEBUG_IMPL, "Deleting all threads");
-
- while (threadflow) {
- if (threadflow->tf_instance &&
- (threadflow->tf_instance == FLOW_MASTER)) {
- threadflow = threadflow->tf_next;
- continue;
- }
- (void) threadflow_delete(threadlist, threadflow);
- threadflow = threadflow->tf_next;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_threadflow_lock);
-}
-
-/*
- * Waits till all threadflows are started, or a timeout occurs.
- * Checks through the list of threadflows, waiting up to 10
- * seconds for each one to set its tf_running flag to 1. If not
- * set after 10 seconds, continues on to the next threadflow
- * anyway.
- */
-void
-threadflow_allstarted(pid_t pid, threadflow_t *threadflow)
-{
- (void) ipc_mutex_lock(&filebench_shm->shm_threadflow_lock);
-
- while (threadflow) {
- int waits;
-
- if ((threadflow->tf_instance == 0) ||
- (threadflow->tf_instance == FLOW_MASTER)) {
- threadflow = threadflow->tf_next;
- continue;
- }
-
- filebench_log(LOG_DEBUG_IMPL, "Checking pid %d thread %s-%d",
- pid,
- threadflow->tf_name,
- threadflow->tf_instance);
-
- waits = 10;
- while (waits && (threadflow->tf_running == 0) &&
- (filebench_shm->shm_f_abort == 0)) {
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_threadflow_lock);
- if (waits < 3)
- filebench_log(LOG_INFO,
- "Waiting for pid %d thread %s-%d",
- pid,
- threadflow->tf_name,
- threadflow->tf_instance);
-
- (void) sleep(1);
- (void) ipc_mutex_lock(
- &filebench_shm->shm_threadflow_lock);
- waits--;
- }
-
- threadflow = threadflow->tf_next;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_threadflow_lock);
-}
-
-/*
- * Create an in-memory thread object linked to a parent procflow.
- * A threadflow entity is allocated from shared memory and
- * initialized from the "inherit" threadflow if supplied,
- * otherwise to zeros. The threadflow is assigned a unique
- * thread id, the supplied instance number, the supplied name
- * and added to the procflow's pf_thread list. If no name is
- * supplied or the threadflow can't be allocated, NULL is
- * returned Otherwise a pointer to the newly allocated threadflow
- * is returned.
- *
- * The filebench_shm->shm_threadflow_lock must be held by the caller.
- */
-static threadflow_t *
-threadflow_define_common(procflow_t *procflow, char *name,
- threadflow_t *inherit, int instance)
-{
- threadflow_t *threadflow;
- threadflow_t **threadlistp = &procflow->pf_threads;
-
- if (name == NULL)
- return (NULL);
-
- threadflow = (threadflow_t *)ipc_malloc(FILEBENCH_THREADFLOW);
-
- if (threadflow == NULL)
- return (NULL);
-
- if (inherit)
- (void) memcpy(threadflow, inherit, sizeof (threadflow_t));
- else
- (void) memset(threadflow, 0, sizeof (threadflow_t));
-
- threadflow->tf_utid = ++filebench_shm->shm_utid;
-
- threadflow->tf_instance = instance;
- (void) strcpy(threadflow->tf_name, name);
- threadflow->tf_process = procflow;
- (void) pthread_mutex_init(&threadflow->tf_lock,
- ipc_mutexattr(IPC_MUTEX_NORMAL));
-
- filebench_log(LOG_DEBUG_IMPL, "Defining thread %s-%d",
- name, instance);
-
- /* Add threadflow to list */
- if (*threadlistp == NULL) {
- *threadlistp = threadflow;
- threadflow->tf_next = NULL;
- } else {
- threadflow->tf_next = *threadlistp;
- *threadlistp = threadflow;
- }
-
- return (threadflow);
-}
-
-/*
- * Create an in memory FLOW_MASTER thread object as described
- * by the syntax. Acquire the filebench_shm->shm_threadflow_lock and
- * call threadflow_define_common() to create a threadflow entity.
- * Set the number of instances to create at runtime,
- * tf_instances, to "instances". Return the threadflow pointer
- * returned by the threadflow_define_common call.
- */
-threadflow_t *
-threadflow_define(procflow_t *procflow, char *name,
- threadflow_t *inherit, avd_t instances)
-{
- threadflow_t *threadflow;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_threadflow_lock);
-
- if ((threadflow = threadflow_define_common(procflow, name,
- inherit, FLOW_MASTER)) == NULL)
- return (NULL);
-
- threadflow->tf_instances = instances;
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_threadflow_lock);
-
- return (threadflow);
-}
-
-
-/*
- * Searches the provided threadflow list for the named threadflow.
- * A pointer to the threadflow is returned, or NULL if threadflow
- * is not found.
- */
-threadflow_t *
-threadflow_find(threadflow_t *threadlist, char *name)
-{
- threadflow_t *threadflow = threadlist;
-
- (void) ipc_mutex_lock(&filebench_shm->shm_threadflow_lock);
-
- while (threadflow) {
- if (strcmp(name, threadflow->tf_name) == 0) {
-
- (void) ipc_mutex_unlock(
- &filebench_shm->shm_threadflow_lock);
-
- return (threadflow);
- }
- threadflow = threadflow->tf_next;
- }
-
- (void) ipc_mutex_unlock(&filebench_shm->shm_threadflow_lock);
-
-
- return (NULL);
-}
diff --git a/usr/src/cmd/filebench/common/threadflow.h b/usr/src/cmd/filebench/common/threadflow.h
deleted file mode 100644
index cb36a6bdcb..0000000000
--- a/usr/src/cmd/filebench/common/threadflow.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_THREADFLOW_H
-#define _FB_THREADFLOW_H
-
-#include "config.h"
-#include "fsplug.h"
-#include <pthread.h>
-
-#ifndef HAVE_CADDR_T1
-/* typedef char *caddr_t; */
-#endif
-
-#ifdef LINUX_PORT
-#include <linux/types.h> /* for "caddr_t" */
-#endif
-
-
-#ifdef HAVE_AIO
-#include <aio.h>
-#endif
-#ifdef HAVE_PROCFS
-#include <procfs.h>
-#endif
-#include "vars.h"
-#include "procflow.h"
-#include "fileset.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define AL_READ 1
-#define AL_WRITE 2
-
-
-#ifdef HAVE_AIO
-typedef struct aiolist {
- int al_type;
- struct aiolist *al_next;
- struct aiolist *al_worknext;
- struct aiocb64 al_aiocb;
-} aiolist_t;
-#endif
-
-#define THREADFLOW_MAXFD 128
-#define THREADFLOW_USEISM 0x1
-
-typedef struct threadflow {
- char tf_name[128]; /* Name */
- int tf_attrs; /* Attributes */
- int tf_instance; /* Instance number */
- int tf_running; /* Thread running indicator */
- int tf_abort; /* Shutdown thread */
- int tf_utid; /* Unique id for thread */
- struct procflow *tf_process; /* Back pointer to process */
- pthread_t tf_tid; /* Thread id */
- pthread_mutex_t tf_lock; /* Mutex around threadflow */
- avd_t tf_instances; /* Number of instances for this flow */
- struct threadflow *tf_next; /* Next on proc list */
- struct flowop *tf_thrd_fops; /* Flowop list */
- caddr_t tf_mem; /* Private Memory */
- avd_t tf_memsize; /* Private Memory size attribute */
- fbint_t tf_constmemsize; /* constant copy of memory size */
- fb_fdesc_t tf_fd[THREADFLOW_MAXFD + 1]; /* Thread local fd's */
- filesetentry_t *tf_fse[THREADFLOW_MAXFD + 1]; /* Thread local files */
- int tf_fdrotor; /* Rotating fd within set */
- flowstat_t tf_stats; /* Thread statistics */
- hrtime_t tf_stime; /* Start time of op */
-#ifdef HAVE_PROCFS
- struct prusage tf_susage; /* Resource usage snapshot, start */
- struct prusage tf_eusage; /* Resource usage snapshot, end */
-#endif
- int tf_lwpusagefd; /* /proc lwp usage fd */
-#ifdef HAVE_AIO
- aiolist_t *tf_aiolist; /* List of async I/Os */
-#endif
-
-} threadflow_t;
-
-/* Thread attrs */
-#define THREADFLOW_DEFAULTMEM 1024*1024LL;
-
-threadflow_t *threadflow_define(procflow_t *, char *name,
- threadflow_t *inherit, avd_t instances);
-threadflow_t *threadflow_find(threadflow_t *, char *);
-int threadflow_init(procflow_t *);
-void flowop_start(threadflow_t *threadflow);
-void threadflow_usage(void);
-void threadflow_allstarted(pid_t pid, threadflow_t *threadflow);
-void threadflow_delete_all(threadflow_t **threadlist);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_THREADFLOW_H */
diff --git a/usr/src/cmd/filebench/common/utils.c b/usr/src/cmd/filebench/common/utils.c
deleted file mode 100644
index a68f72446d..0000000000
--- a/usr/src/cmd/filebench/common/utils.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <errno.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#include "filebench.h"
-#include "utils.h"
-#include "parsertypes.h"
-
-/*
- * For now, just three routines: one to allocate a string in shared
- * memory, one to emulate a strlcpy() function and one to emulate a
- * strlcat() function, both the second and third only used in non
- * Solaris environments,
- *
- */
-
-
-/*
- * Allocates space for a new string of the same length as
- * the supplied string "str". Copies the old string into
- * the new string and returns a pointer to the new string.
- * Returns NULL if memory allocation for the new string fails.
- */
-char *
-fb_stralloc(char *str)
-{
- char *newstr;
-
- if ((newstr = malloc(strlen(str) + 1)) == NULL)
- return (NULL);
- (void) strcpy(newstr, str);
- return (newstr);
-}
-
-#ifndef sun
-
-/*
- * Implements the strlcpy function when compilied for non Solaris
- * operating systems. On solaris the strlcpy() function is used
- * directly.
- */
-size_t
-fb_strlcpy(char *dst, const char *src, size_t dstsize)
-{
- uint_t i;
-
- for (i = 0; i < (dstsize - 1); i++) {
-
- /* quit if at end of source string */
- if (src[i] == '\0')
- break;
-
- dst[i] = src[i];
- }
-
- /* set end of dst string to \0 */
- dst[i] = '\0';
- i++;
-
- return (i);
-}
-
-/*
- * Implements the strlcat function when compilied for non Solaris
- * operating systems. On solaris the strlcat() function is used
- * directly.
- */
-size_t
-fb_strlcat(char *dst, const char *src, size_t dstsize)
-{
- uint_t i, j;
-
- /* find the end of the current destination string */
- for (i = 0; i < (dstsize - 1); i++) {
- if (dst[i] == '\0')
- break;
- }
-
- /* append the source string to the destination string */
- for (j = 0; i < (dstsize - 1); i++) {
- if (src[j] == '\0')
- break;
-
- dst[i] = src[j];
- j++;
- }
-
- /* set end of dst string to \0 */
- dst[i] = '\0';
- i++;
-
- return (i);
-}
-
-#endif /* !sun */
diff --git a/usr/src/cmd/filebench/common/utils.h b/usr/src/cmd/filebench/common/utils.h
deleted file mode 100644
index cb9e39a9fc..0000000000
--- a/usr/src/cmd/filebench/common/utils.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_UTILS_H
-#define _FB_UTILS_H
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define E_ERROR 1 /* Exit status for error */
-#define E_USAGE 2 /* Exit status for usage error */
-
-extern char *fb_stralloc(char *str);
-
-#ifdef sun
-#define fb_strlcat strlcat
-#define fb_strlcpy strlcpy
-#else
-extern size_t fb_strlcat(char *dst, const char *src, size_t dstsize);
-extern size_t fb_strlcpy(char *dst, const char *src, size_t dstsize);
-#endif /* sun */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_UTILS_H */
diff --git a/usr/src/cmd/filebench/common/vars.c b/usr/src/cmd/filebench/common/vars.c
deleted file mode 100644
index 3be0891bd2..0000000000
--- a/usr/src/cmd/filebench/common/vars.c
+++ /dev/null
@@ -1,1887 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2008 Denis Cheng
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "filebench.h"
-#include "vars.h"
-#include "misc.h"
-#include "utils.h"
-#include "stats.h"
-#include "eventgen.h"
-#include "fb_random.h"
-
-static var_t *var_find_dynamic(char *name);
-static boolean_t var_get_bool(var_t *var);
-static fbint_t var_get_int(var_t *var);
-static double var_get_dbl(var_t *var);
-
-/*
- * The filebench variables system has attribute value descriptors (avd_t)
- * where an avd contains a boolean, integer, double, string, random
- * distribution object ptr, boolean ptr, integer ptr, double ptr,
- * string ptr, or variable ptr. The system also has the variables
- * themselves, (var_t), which are named, typed entities which can be
- * allocated, selected and changed using the "set" command and used in
- * attribute assignments. The variables contain either a boolean, an
- * integer, a double, a string or pointer to an associated random
- * distribution object. Both avd_t and var_t entities are allocated
- * from interprocess shared memory space.
- *
- * The attribute descriptors implement delayed binding to variable values,
- * which is necessary because the values of variables may be changed
- * between the time the workload file is loaded and it is actually run,
- * either by further "set" commands in the file or from the command line
- * interface. For random variables, they actually point to the random
- * distribution object, allowing FileBench to invoke the appropriate
- * random distribution function on each access to the attribute. However,
- * for static attributes, the value is just loaded in the descriptor
- * directly, avoiding the need to allocate a variable to hold the static
- * value.
- *
- * The routines in this module are used to allocate, locate, and
- * manipulate the attribute descriptors, and vars. Routines are
- * also included to convert between the component strings, doubles
- * and integers of vars, and said components of avd_t.
- */
-
-
-/*
- * returns a pointer to a string indicating the type of data contained
- * in the supplied attribute variable descriptor.
- */
-static char *
-avd_get_type_string(avd_t avd)
-{
- switch (avd->avd_type) {
- case AVD_INVALID:
- return ("uninitialized");
-
- case AVD_VAL_BOOL:
- return ("boolean value");
-
- case AVD_VARVAL_BOOL:
- return ("points to boolean in var_t");
-
- case AVD_VAL_INT:
- return ("integer value");
-
- case AVD_VARVAL_INT:
- return ("points to integer in var_t");
-
- case AVD_VAL_STR:
- return ("string");
-
- case AVD_VARVAL_STR:
- return ("points to string in var_t");
-
- case AVD_VAL_DBL:
- return ("double float value");
-
- case AVD_VARVAL_DBL:
- return ("points to double float in var_t");
-
- case AVD_IND_VAR:
- return ("points to a var_t");
-
- case AVD_IND_RANDVAR:
- return ("points to var_t's random distribution object");
-
- default:
- return ("illegal avd type");
- }
-}
-
-/*
- * returns a pointer to a string indicating the type of data contained
- * in the supplied variable.
- */
-static char *
-var_get_type_string(var_t *ivp)
-{
- switch (ivp->var_type & VAR_TYPE_SET_MASK) {
- case VAR_TYPE_BOOL_SET:
- return ("boolean");
-
- case VAR_TYPE_INT_SET:
- return ("integer");
-
- case VAR_TYPE_STR_SET:
- return ("string");
-
- case VAR_TYPE_DBL_SET:
- return ("double float");
-
- case VAR_TYPE_RAND_SET:
- return ("random");
-
- default:
- return ("empty");
- }
-}
-
-/*
- * Returns the fbint_t pointed to by the supplied avd_t "avd".
- */
-fbint_t
-avd_get_int(avd_t avd)
-{
- randdist_t *rndp;
-
- if (avd == NULL)
- return (0);
-
- switch (avd->avd_type) {
- case AVD_VAL_INT:
- return (avd->avd_val.intval);
-
- case AVD_VARVAL_INT:
- if (avd->avd_val.intptr)
- return (*(avd->avd_val.intptr));
- else
- return (0);
-
- case AVD_IND_VAR:
- return (var_get_int(avd->avd_val.varptr));
-
- case AVD_IND_RANDVAR:
- if ((rndp = avd->avd_val.randptr) == NULL)
- return (0);
- else
- return ((fbint_t)rndp->rnd_get(rndp));
-
- default:
- filebench_log(LOG_ERROR,
- "Attempt to get integer from %s avd",
- avd_get_type_string(avd));
- return (0);
- }
-}
-
-/*
- * Returns the floating point value of a variable pointed to by the
- * supplied avd_t "avd". Intended to get the actual (double) value
- * supplied by the random variable.
- */
-double
-avd_get_dbl(avd_t avd)
-{
- randdist_t *rndp;
-
- if (avd == NULL)
- return (0.0);
-
- switch (avd->avd_type) {
- case AVD_VAL_INT:
- return ((double)avd->avd_val.intval);
-
- case AVD_VAL_DBL:
- return (avd->avd_val.dblval);
-
- case AVD_VARVAL_INT:
- if (avd->avd_val.intptr)
- return ((double)(*(avd->avd_val.intptr)));
- else
- return (0.0);
-
- case AVD_VARVAL_DBL:
- if (avd->avd_val.dblptr)
- return (*(avd->avd_val.dblptr));
- else
- return (0.0);
-
- case AVD_IND_VAR:
- return (var_get_dbl(avd->avd_val.varptr));
-
- case AVD_IND_RANDVAR:
- if ((rndp = avd->avd_val.randptr) == NULL) {
- return (0.0);
- } else
- return (rndp->rnd_get(rndp));
-
- default:
- filebench_log(LOG_ERROR,
- "Attempt to get floating point from %s avd",
- avd_get_type_string(avd));
- return (0.0);
- }
-}
-
-/*
- * Returns the boolean pointed to by the supplied avd_t "avd".
- */
-boolean_t
-avd_get_bool(avd_t avd)
-{
- if (avd == NULL)
- return (0);
-
- switch (avd->avd_type) {
- case AVD_VAL_BOOL:
- return (avd->avd_val.boolval);
-
- case AVD_VARVAL_BOOL:
- if (avd->avd_val.boolptr)
- return (*(avd->avd_val.boolptr));
- else
- return (FALSE);
-
- /* for backwards compatibility with old workloads */
- case AVD_VAL_INT:
- if (avd->avd_val.intval != 0)
- return (TRUE);
- else
- return (FALSE);
-
- case AVD_VARVAL_INT:
- if (avd->avd_val.intptr)
- if (*(avd->avd_val.intptr) != 0)
- return (TRUE);
-
- return (FALSE);
-
- case AVD_IND_VAR:
- return (var_get_bool(avd->avd_val.varptr));
-
- default:
- filebench_log(LOG_ERROR,
- "Attempt to get boolean from %s avd",
- avd_get_type_string(avd));
- return (FALSE);
- }
-}
-
-/*
- * Returns the string pointed to by the supplied avd_t "avd".
- */
-char *
-avd_get_str(avd_t avd)
-{
- var_t *ivp;
-
- if (avd == NULL)
- return (NULL);
-
- switch (avd->avd_type) {
- case AVD_VAL_STR:
- return (avd->avd_val.strval);
-
- case AVD_VARVAL_STR:
- if (avd->avd_val.strptr)
- return (*avd->avd_val.strptr);
- else
- return (NULL);
-
- case AVD_IND_VAR:
- ivp = avd->avd_val.varptr;
-
- if (ivp && VAR_HAS_STRING(ivp))
- return (ivp->var_val.string);
-
- filebench_log(LOG_ERROR,
- "Attempt to get string from %s var $%s",
- var_get_type_string(ivp), ivp->var_name);
- return (NULL);
-
- default:
- filebench_log(LOG_ERROR,
- "Attempt to get string from %s avd",
- avd_get_type_string(avd));
- return (NULL);
- }
-}
-
-/*
- * Allocates a avd_t from ipc memory space.
- * logs an error and returns NULL on failure.
- */
-static avd_t
-avd_alloc_cmn(void)
-{
- avd_t rtn;
-
- if ((rtn = (avd_t)ipc_malloc(FILEBENCH_AVD)) == NULL)
- filebench_log(LOG_ERROR, "Avd alloc failed");
-
- return (rtn);
-}
-
-/*
- * pre-loads the allocated avd_t with the boolean_t "bool".
- * Returns the avd_t on success, NULL on failure.
- */
-avd_t
-avd_bool_alloc(boolean_t bool)
-{
- avd_t avd;
-
- if ((avd = avd_alloc_cmn()) == NULL)
- return (NULL);
-
- avd->avd_type = AVD_VAL_BOOL;
- avd->avd_val.boolval = bool;
-
- filebench_log(LOG_DEBUG_IMPL, "Alloc boolean %d", bool);
-
- return (avd);
-}
-
-/*
- * pre-loads the allocated avd_t with the fbint_t "integer".
- * Returns the avd_t on success, NULL on failure.
- */
-avd_t
-avd_int_alloc(fbint_t integer)
-{
- avd_t avd;
-
- if ((avd = avd_alloc_cmn()) == NULL)
- return (NULL);
-
- avd->avd_type = AVD_VAL_INT;
- avd->avd_val.intval = integer;
-
- filebench_log(LOG_DEBUG_IMPL, "Alloc integer %llu",
- (u_longlong_t)integer);
-
- return (avd);
-}
-
-/*
- * Gets a avd_t and points it to the var that
- * it will eventually be filled from
- */
-static avd_t
-avd_alloc_var_ptr(var_t *var)
-{
- avd_t avd;
-
- if (var == NULL)
- return (NULL);
-
- if ((avd = avd_alloc_cmn()) == NULL)
- return (NULL);
-
- switch (var->var_type & VAR_TYPE_SET_MASK) {
- case VAR_TYPE_BOOL_SET:
- avd->avd_type = AVD_VARVAL_BOOL;
- avd->avd_val.boolptr = (&var->var_val.boolean);
- break;
-
- case VAR_TYPE_INT_SET:
- avd->avd_type = AVD_VARVAL_INT;
- avd->avd_val.intptr = (&var->var_val.integer);
- break;
-
- case VAR_TYPE_STR_SET:
- avd->avd_type = AVD_VARVAL_STR;
- avd->avd_val.strptr = &(var->var_val.string);
- break;
-
- case VAR_TYPE_DBL_SET:
- avd->avd_type = AVD_VARVAL_DBL;
- avd->avd_val.dblptr = &(var->var_val.dbl_flt);
- break;
-
- case VAR_TYPE_RAND_SET:
- avd->avd_type = AVD_IND_RANDVAR;
- avd->avd_val.randptr = var->var_val.randptr;
- break;
-
- case VAR_TYPE_INDVAR_SET:
- avd->avd_type = AVD_IND_VAR;
- if ((var->var_type & VAR_INDVAR_MASK) == VAR_IND_ASSIGN)
- avd->avd_val.varptr = var->var_varptr1;
- else
- avd->avd_val.varptr = var;
-
- break;
-
- default:
- avd->avd_type = AVD_IND_VAR;
- avd->avd_val.varptr = var;
- break;
- }
- return (avd);
-}
-
-/*
- * Gets a avd_t, then allocates and initializes a piece of
- * shared string memory, putting the pointer to it into the just
- * allocated string pointer location. The routine returns a pointer
- * to the string pointer location or returns NULL on error.
- */
-avd_t
-avd_str_alloc(char *string)
-{
- avd_t avd;
-
- if (string == NULL) {
- filebench_log(LOG_ERROR, "No string supplied\n");
- return (NULL);
- }
-
- if ((avd = avd_alloc_cmn()) == NULL)
- return (NULL);
-
- avd->avd_type = AVD_VAL_STR;
- avd->avd_val.strval = ipc_stralloc(string);
-
- filebench_log(LOG_DEBUG_IMPL,
- "Alloc string %s ptr %zx",
- string, avd);
-
- return (avd);
-}
-
-/*
- * Allocates a var (var_t) from interprocess shared memory.
- * Places the allocated var on the end of the globally shared
- * shm_var_list. Finally, the routine allocates a string containing
- * a copy of the supplied "name" string. If any allocations
- * fails, returns NULL, otherwise it returns a pointer to the
- * newly allocated var.
- */
-static var_t *
-var_alloc_cmn(char *name, int var_type)
-{
- var_t **var_listp;
- var_t *var = NULL;
- var_t *prev = NULL;
- var_t *newvar;
-
- if ((newvar = (var_t *)ipc_malloc(FILEBENCH_VARIABLE)) == NULL) {
- filebench_log(LOG_ERROR, "Out of memory for variables");
- return (NULL);
- }
- (void) memset(newvar, 0, sizeof (newvar));
- newvar->var_type = var_type;
-
- if ((newvar->var_name = ipc_stralloc(name)) == NULL) {
- filebench_log(LOG_ERROR, "Out of memory for variables");
- return (NULL);
- }
-
- switch (var_type & VAR_TYPE_MASK) {
- case VAR_TYPE_RANDOM:
- case VAR_TYPE_GLOBAL:
- var_listp = &filebench_shm->shm_var_list;
- break;
-
- case VAR_TYPE_DYNAMIC:
- var_listp = &filebench_shm->shm_var_dyn_list;
- break;
-
- case VAR_TYPE_LOCAL:
- /* place on head of shared local list */
- newvar->var_next = filebench_shm->shm_var_loc_list;
- filebench_shm->shm_var_loc_list = newvar;
- return (newvar);
-
- default:
- var_listp = &filebench_shm->shm_var_list;
- break;
- }
-
- /* add to the end of list */
- for (var = *var_listp; var != NULL; var = var->var_next)
- prev = var; /* Find end of list */
- if (prev != NULL)
- prev->var_next = newvar;
- else
- *var_listp = newvar;
-
- return (newvar);
-}
-
-/*
- * Allocates a var (var_t) from interprocess shared memory after
- * first adjusting the name to elminate the leading $. Places the
- * allocated var temporarily on the end of the globally
- * shared var_loc_list. If the allocation fails, returns NULL,
- * otherwise it returns a pointer to the newly allocated var.
- */
-var_t *
-var_lvar_alloc_local(char *name)
-{
- if (name[0] == '$')
- name += 1;
-
- return (var_alloc_cmn(name, VAR_TYPE_LOCAL));
-}
-
-/*
- * Allocates a var (var_t) from interprocess shared memory and
- * places the allocated var on the end of the globally shared
- * shm_var_list. If the allocation fails, returns NULL, otherwise
- * it returns a pointer to the newly allocated var.
- */
-static var_t *
-var_alloc(char *name)
-{
- return (var_alloc_cmn(name, VAR_TYPE_GLOBAL));
-}
-
-/*
- * Allocates a var (var_t) from interprocess shared memory.
- * Places the allocated var on the end of the globally shared
- * shm_var_dyn_list. If the allocation fails, returns NULL, otherwise
- * it returns a pointer to the newly allocated var.
- */
-static var_t *
-var_alloc_dynamic(char *name)
-{
- return (var_alloc_cmn(name, VAR_TYPE_DYNAMIC));
-}
-
-/*
- * Searches for var_t with name "name" in the shm_var_loc_list,
- * then, if not found, in the global shm_var_list. If a matching
- * local or global var is found, returns a pointer to the var_t,
- * otherwise returns NULL.
- */
-static var_t *
-var_find(char *name)
-{
- var_t *var;
-
- for (var = filebench_shm->shm_var_loc_list; var != NULL;
- var = var->var_next) {
- if (strcmp(var->var_name, name) == 0)
- return (var);
- }
-
- for (var = filebench_shm->shm_var_list; var != NULL;
- var = var->var_next) {
- if (strcmp(var->var_name, name) == 0)
- return (var);
- }
-
- return (NULL);
-}
-
-/*
- * Searches for var_t with name "name" in the supplied shm_var_list.
- * If not found there, checks the global list. If still
- * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t.
- */
-static var_t *
-var_find_list_only(char *name, var_t *var_list)
-{
- var_t *var;
-
- for (var = var_list; var != NULL; var = var->var_next) {
- if (strcmp(var->var_name, name) == 0)
- return (var);
- }
-
- return (NULL);
-}
-
-/*
- * Searches for var_t with name "name" in the supplied shm_var_list.
- * If not found there, checks the global list. If still
- * unsuccessful, returns NULL. Otherwise returns a pointer to the var_t.
- */
-static var_t *
-var_find_list(char *name, var_t *var_list)
-{
- var_t *var;
-
- if ((var = var_find_list_only(name, var_list)) != NULL)
- return (var);
- else
- return (var_find(name));
-}
-
-/*
- * Searches for the named var and returns it if found. If not
- * found it allocates a new variable
- */
-static var_t *
-var_find_alloc(char *name)
-{
- var_t *var;
-
- if (name == NULL) {
- filebench_log(LOG_ERROR,
- "var_find_alloc: Var name not supplied");
- return (NULL);
- }
-
- name += 1;
-
- if ((var = var_find(name)) == NULL) {
- var = var_alloc(name);
- }
- return (var);
-}
-
-/*
- * Searches for the named var, and, if found, sets its
- * var_val.boolean's value to that of the supplied boolean.
- * If not found, the routine allocates a new var and sets
- * its var_val.boolean's value to that of the supplied
- * boolean. If the named var cannot be found or allocated
- * the routine returns -1, otherwise it returns 0.
- */
-int
-var_assign_boolean(char *name, boolean_t bool)
-{
- var_t *var;
-
- if ((var = var_find_alloc(name)) == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (-1);
- }
-
- if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
- filebench_log(LOG_ERROR,
- "Cannot assign integer to random variable %s", name);
- return (-1);
- }
-
- VAR_SET_BOOL(var, bool);
-
- filebench_log(LOG_DEBUG_SCRIPT, "Assign boolean %s=%d",
- name, bool);
-
- return (0);
-}
-
-/*
- * Searches for the named var, and, if found, sets its
- * var_integer's value to that of the supplied integer.
- * If not found, the routine allocates a new var and sets
- * its var_integers's value to that of the supplied
- * integer. If the named var cannot be found or allocated
- * the routine returns -1, otherwise it returns 0.
- */
-int
-var_assign_integer(char *name, fbint_t integer)
-{
- var_t *var;
-
- if ((var = var_find_alloc(name)) == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (-1);
- }
-
- if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
- filebench_log(LOG_ERROR,
- "Cannot assign integer to random variable %s", name);
- return (-1);
- }
-
- VAR_SET_INT(var, integer);
-
- filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu",
- name, (u_longlong_t)integer);
-
- return (0);
-}
-
-/*
- * Add, subtract, multiply or divide two integers based on optype
- * passed from caller.
- */
-static fbint_t
-var_binary_integer_op(var_t *var)
-{
- fbint_t result;
- fbint_t src1, src2;
-
- if (var == NULL)
- return (0);
-
- switch (var->var_type & VAR_INDBINOP_MASK) {
- case VAR_IND_BINOP_INT:
- src2 = var->var_val.integer;
- break;
-
- case VAR_IND_BINOP_DBL:
- src2 = (fbint_t)var->var_val.dbl_flt;
- break;
-
- case VAR_IND_BINOP_VAR:
- if (var->var_val.varptr2 != NULL)
- src2 = var_get_int(var->var_val.varptr2);
- else
- src2 = 0;
- break;
- }
-
- if (var->var_varptr1 != NULL)
- src1 = var_get_int(var->var_varptr1);
- else
- src1 = 0;
-
- switch (var->var_type & VAR_INDVAR_MASK) {
- case VAR_IND_VAR_SUM_VC:
- result = src1 + src2;
- break;
-
- case VAR_IND_VAR_DIF_VC:
- result = src1 - src2;
- break;
-
- case VAR_IND_C_DIF_VAR:
- result = src2 - src1;
- break;
-
- case VAR_IND_VAR_MUL_VC:
- result = src1 * src2;
- break;
-
- case VAR_IND_VAR_DIV_VC:
- result = src1 / src2;
- break;
-
- case VAR_IND_C_DIV_VAR:
- result = src2 / src1;
- break;
-
- default:
- filebench_log(LOG_DEBUG_IMPL,
- "var_binary_integer_op: Called with unknown IND_TYPE");
- result = 0;
- break;
- }
- return (result);
-}
-
-/*
- * Add, subtract, multiply or divide two double precision floating point
- * numbers based on optype passed from caller.
- */
-static double
-var_binary_dbl_flt_op(var_t *var)
-{
- double result;
- double src1, src2;
-
- if (var == NULL)
- return (0.0);
-
- switch (var->var_type & VAR_INDBINOP_MASK) {
- case VAR_IND_BINOP_INT:
- src2 = (double)var->var_val.integer;
- break;
-
- case VAR_IND_BINOP_DBL:
- src2 = var->var_val.dbl_flt;
- break;
-
- case VAR_IND_BINOP_VAR:
- if (var->var_val.varptr2 != NULL)
- src2 = var_get_dbl(var->var_val.varptr2);
- else
- src2 = 0;
- break;
- }
-
- if (var->var_varptr1 != NULL)
- src1 = var_get_dbl(var->var_varptr1);
- else
- src1 = 0;
-
- switch (var->var_type & VAR_INDVAR_MASK) {
- case VAR_IND_VAR_SUM_VC:
- result = src1 + src2;
- break;
-
- case VAR_IND_VAR_DIF_VC:
- result = src1 - src2;
- break;
-
- case VAR_IND_C_DIF_VAR:
- result = src2 - src1;
- break;
-
- case VAR_IND_VAR_MUL_VC:
- result = src1 * src2;
- break;
-
- case VAR_IND_C_DIV_VAR:
- result = src2 / src1;
- break;
-
- case VAR_IND_VAR_DIV_VC:
- result = src1 / src2;
- break;
-
- default:
- filebench_log(LOG_DEBUG_IMPL,
- "var_binary_dbl_flt_op: Called with unknown IND_TYPE");
- result = 0;
- break;
- }
- return (result);
-}
-
-/*
- * Perform a binary operation on a variable and an integer
- */
-int
-var_assign_op_var_int(char *name, int optype, char *src1, fbint_t src2)
-{
- var_t *var;
- var_t *var_src1;
-
- if ((var_src1 = var_find(src1+1)) == NULL)
- return (FILEBENCH_ERROR);
-
- if ((var = var_find_alloc(name)) == NULL)
- return (FILEBENCH_ERROR);
-
- if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
- filebench_log(LOG_ERROR,
- "Cannot assign integer to random variable %s", name);
- return (FILEBENCH_ERROR);
- }
-
- VAR_SET_BINOP_INDVAR(var, var_src1, optype);
-
- var->var_val.integer = src2;
-
- return (FILEBENCH_OK);
-}
-
-int
-var_assign_op_var_var(char *name, int optype, char *src1, char *src2)
-{
- var_t *var;
- var_t *var_src1;
- var_t *var_src2;
-
- if ((var_src1 = var_find(src1+1)) == NULL)
- return (FILEBENCH_ERROR);
-
- if ((var_src2 = var_find(src2+1)) == NULL)
- return (FILEBENCH_ERROR);
-
- if ((var = var_find_alloc(name)) == NULL)
- return (FILEBENCH_ERROR);
-
- if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
- filebench_log(LOG_ERROR,
- "Cannot assign integer to random variable %s", name);
- return (FILEBENCH_ERROR);
- }
-
- VAR_SET_BINOP_INDVAR(var, var_src1, optype);
-
- var->var_val.varptr2 = var_src2;
-
- return (FILEBENCH_OK);
-}
-
-/*
- * Find a variable, and set it to random type.
- * If it does not have a random extension, allocate one
- */
-var_t *
-var_find_randvar(char *name)
-{
- var_t *newvar;
-
- name += 1;
-
- if ((newvar = var_find(name)) == NULL) {
- filebench_log(LOG_ERROR,
- "failed to locate random variable $%s\n", name);
- return (NULL);
- }
-
- /* set randdist pointer unless it is already set */
- if (((newvar->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) ||
- !VAR_HAS_RANDDIST(newvar)) {
- filebench_log(LOG_ERROR,
- "Found variable $%s not random\n", name);
- return (NULL);
- }
-
- return (newvar);
-}
-
-/*
- * Allocate a variable, and set it to random type. Then
- * allocate a random extension.
- */
-var_t *
-var_define_randvar(char *name)
-{
- var_t *newvar;
- randdist_t *rndp = NULL;
-
- name += 1;
-
- /* make sure variable doesn't already exist */
- if (var_find(name) != NULL) {
- filebench_log(LOG_ERROR,
- "variable name already in use\n");
- return (NULL);
- }
-
- /* allocate a random variable */
- if ((newvar = var_alloc_cmn(name, VAR_TYPE_RANDOM)) == NULL) {
- filebench_log(LOG_ERROR,
- "failed to alloc random variable\n");
- return (NULL);
- }
-
- /* set randdist pointer */
- if ((rndp = randdist_alloc()) == NULL) {
- filebench_log(LOG_ERROR,
- "failed to alloc random distribution object\n");
- return (NULL);
- }
-
- rndp->rnd_var = newvar;
- VAR_SET_RAND(newvar, rndp);
-
- return (newvar);
-}
-
-/*
- * Searches for the named var, and if found returns an avd_t
- * pointing to the var's var_integer, var_string or var_double
- * as appropriate. If not found, attempts to allocate
- * a var named "name" and returns an avd_t to it with
- * no value set. If the var cannot be found or allocated, an
- * error is logged and the run is terminated.
- */
-avd_t
-var_ref_attr(char *name)
-{
- var_t *var;
-
- name += 1;
-
- if ((var = var_find(name)) == NULL)
- var = var_find_dynamic(name);
-
- if (var == NULL)
- var = var_alloc(name);
-
- if (var == NULL) {
- filebench_log(LOG_ERROR, "Invalid variable $%s",
- name);
- filebench_shutdown(1);
- }
-
- /* allocate pointer to var and return */
- return (avd_alloc_var_ptr(var));
-}
-
-/*
- * Converts the contents of a var to a string
- */
-static char *
-var_get_string(var_t *var)
-{
-
- if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
- switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) {
- case RAND_TYPE_UNIFORM:
- return (fb_stralloc("uniform random var"));
- case RAND_TYPE_GAMMA:
- return (fb_stralloc("gamma random var"));
- case RAND_TYPE_TABLE:
- return (fb_stralloc("tabular random var"));
- default:
- return (fb_stralloc("unitialized random var"));
- }
- }
-
- if (VAR_HAS_STRING(var) && var->var_val.string)
- return (fb_stralloc(var->var_val.string));
-
- if (VAR_HAS_BOOLEAN(var)) {
- if (var->var_val.boolean)
- return (fb_stralloc("true"));
- else
- return (fb_stralloc("false"));
- }
-
- if (VAR_HAS_INTEGER(var)) {
- char tmp[128];
-
- (void) snprintf(tmp, sizeof (tmp), "%llu",
- (u_longlong_t)var->var_val.integer);
- return (fb_stralloc(tmp));
- }
-
- if (VAR_HAS_INDVAR(var)) {
- var_t *ivp;
-
- if ((ivp = var->var_varptr1) != NULL) {
- return (var_get_string(ivp));
- }
- }
-
- if (VAR_HAS_BINOP(var)) {
- char tmp[128];
-
- (void) snprintf(tmp, sizeof (tmp), "%llu",
- var_binary_integer_op(var));
- return (fb_stralloc(tmp));
- }
-
- return (fb_stralloc("No default"));
-}
-
-/*
- * Searches for the named var, and if found copies the var_val.string,
- * if it exists, a decimal number string representation of
- * var_val.integer, the state of var_val.boolean, or the type of random
- * distribution employed, into a malloc'd bit of memory using fb_stralloc().
- * Returns a pointer to the created string, or NULL on failure.
- */
-char *
-var_to_string(char *name)
-{
- var_t *var;
-
- name += 1;
-
- if ((var = var_find(name)) == NULL)
- var = var_find_dynamic(name);
-
- if (var == NULL)
- return (NULL);
-
- return (var_get_string(var));
-}
-
-/*
- * Returns the boolean from the supplied var_t "var".
- */
-static boolean_t
-var_get_bool(var_t *var)
-{
- if (var == NULL)
- return (0);
-
- if (VAR_HAS_BOOLEAN(var))
- return (var->var_val.boolean);
-
- if (VAR_HAS_INTEGER(var)) {
- if (var->var_val.integer == 0)
- return (FALSE);
- else
- return (TRUE);
- }
-
- filebench_log(LOG_ERROR,
- "Attempt to get boolean from %s var $%s",
- var_get_type_string(var), var->var_name);
- return (FALSE);
-}
-
-/*
- * Returns the fbint_t from the supplied var_t "var".
- */
-static fbint_t
-var_get_int(var_t *var)
-{
- randdist_t *rndp;
-
- if (var == NULL)
- return (0);
-
- if (VAR_HAS_INTEGER(var))
- return (var->var_val.integer);
-
- if (VAR_HAS_RANDDIST(var)) {
- if ((rndp = var->var_val.randptr) != NULL)
- return ((fbint_t)rndp->rnd_get(rndp));
- }
-
- if (VAR_HAS_BINOP(var))
- return (var_binary_integer_op(var));
-
- filebench_log(LOG_ERROR,
- "Attempt to get integer from %s var $%s",
- var_get_type_string(var), var->var_name);
- return (0);
-}
-
-/*
- * Returns the floating point value of a variable pointed to by the
- * supplied var_t "var". Intended to get the actual (double) value
- * supplied by the random variable.
- */
-static double
-var_get_dbl(var_t *var)
-{
- randdist_t *rndp;
-
- if (var == NULL)
- return (0.0);
-
- if (VAR_HAS_INTEGER(var))
- return ((double)var->var_val.integer);
-
- if (VAR_HAS_DOUBLE(var))
- return (var->var_val.dbl_flt);
-
- if (VAR_HAS_RANDDIST(var)) {
- if ((rndp = var->var_val.randptr) != NULL)
- return (rndp->rnd_get(rndp));
- }
-
- if (VAR_HAS_BINOP(var))
- return (var_binary_dbl_flt_op(var));
-
- filebench_log(LOG_ERROR,
- "Attempt to get double float from %s var $%s",
- var_get_type_string(var), var->var_name);
- return (0.0);
-}
-
-/*
- * Searches for the named var, and if found returns the value,
- * of var_val.boolean. If the var is not found, or a boolean
- * value has not been set, logs an error and returns 0.
- */
-boolean_t
-var_to_boolean(char *name)
-{
- var_t *var;
-
- name += 1;
-
- if ((var = var_find(name)) == NULL)
- var = var_find_dynamic(name);
-
- if (var != NULL)
- return (var_get_bool(var));
-
- filebench_log(LOG_ERROR,
- "Variable %s referenced before set", name);
-
- return (FALSE);
-}
-
-/*
- * Searches for the named var, and if found returns the value,
- * of var_val.integer. If the var is not found, or the an
- * integer value has not been set, logs an error and returns 0.
- */
-fbint_t
-var_to_integer(char *name)
-{
- var_t *var;
-
- name += 1;
-
- if ((var = var_find(name)) == NULL)
- var = var_find_dynamic(name);
-
- if (var != NULL)
- return (var_get_int(var));
-
- filebench_log(LOG_ERROR,
- "Variable %s referenced before set", name);
-
- return (0);
-}
-
-/*
- * Searches for the named var, and if found returns the value,
- * of var_val.dbl_flt. If the var is not found, or the
- * floating value has not been set, logs an error and returns 0.0.
- */
-double
-var_to_double(char *name)
-{
- var_t *var;
-
- name += 1;
-
- if ((var = var_find(name)) == NULL)
- var = var_find_dynamic(name);
-
- if (var != NULL)
- return (var_get_dbl(var));
-
- filebench_log(LOG_ERROR,
- "Variable %s referenced before set", name);
-
- return (0.0);
-}
-
-/*
- * Searches for the named random var, and if found, converts the
- * requested parameter into a string or a decimal number string
- * representation, into a malloc'd bit of memory using fb_stralloc().
- * Returns a pointer to the created string, or calls var_to_string()
- * if a random variable isn't found.
- */
-char *
-var_randvar_to_string(char *name, int param_name)
-{
- var_t *var;
- fbint_t value;
-
- if ((var = var_find(name + 1)) == NULL)
- return (var_to_string(name));
-
- if (((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM) ||
- !VAR_HAS_RANDDIST(var))
- return (var_to_string(name));
-
- switch (param_name) {
- case RAND_PARAM_TYPE:
- switch (var->var_val.randptr->rnd_type & RAND_TYPE_MASK) {
- case RAND_TYPE_UNIFORM:
- return (fb_stralloc("uniform"));
- case RAND_TYPE_GAMMA:
- return (fb_stralloc("gamma"));
- case RAND_TYPE_TABLE:
- return (fb_stralloc("tabular"));
- default:
- return (fb_stralloc("uninitialized"));
- }
-
- case RAND_PARAM_SRC:
- if (var->var_val.randptr->rnd_type & RAND_SRC_GENERATOR)
- return (fb_stralloc("rand48"));
- else
- return (fb_stralloc("urandom"));
-
- case RAND_PARAM_SEED:
- value = avd_get_int(var->var_val.randptr->rnd_seed);
- break;
-
- case RAND_PARAM_MIN:
- value = avd_get_int(var->var_val.randptr->rnd_min);
- break;
-
- case RAND_PARAM_MEAN:
- value = avd_get_int(var->var_val.randptr->rnd_mean);
- break;
-
- case RAND_PARAM_GAMMA:
- value = avd_get_int(var->var_val.randptr->rnd_gamma);
- break;
-
- case RAND_PARAM_ROUND:
- value = avd_get_int(var->var_val.randptr->rnd_round);
- break;
-
- default:
- return (NULL);
-
- }
-
- /* just an integer value if we got here */
- {
- char tmp[128];
-
- (void) snprintf(tmp, sizeof (tmp), "%llu",
- (u_longlong_t)value);
- return (fb_stralloc(tmp));
- }
-}
-
-/*
- * Copies the value stored in the source string into the destination
- * string. Returns -1 if any problems encountered, 0 otherwise.
- */
-static int
-var_copy(var_t *dst_var, var_t *src_var) {
-
- if (VAR_HAS_BOOLEAN(src_var)) {
- VAR_SET_BOOL(dst_var, src_var->var_val.boolean);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var %s=%s", dst_var->var_name,
- dst_var->var_val.boolean?"true":"false");
- }
-
- if (VAR_HAS_INTEGER(src_var)) {
- VAR_SET_INT(dst_var, src_var->var_val.integer);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var %s=%llu", dst_var->var_name,
- (u_longlong_t)dst_var->var_val.integer);
- }
-
- if (VAR_HAS_DOUBLE(src_var)) {
- VAR_SET_DBL(dst_var, src_var->var_val.dbl_flt);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var %s=%lf", dst_var->var_name,
- dst_var->var_val.dbl_flt);
- }
-
- if (VAR_HAS_STRING(src_var)) {
- char *strptr;
-
- if ((strptr =
- ipc_stralloc(src_var->var_val.string)) == NULL) {
- filebench_log(LOG_ERROR,
- "Cannot assign string for variable %s",
- dst_var->var_name);
- return (-1);
- }
- VAR_SET_STR(dst_var, strptr);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var %s=%s", dst_var->var_name,
- dst_var->var_val.string);
- }
-
- if (VAR_HAS_INDVAR(src_var)) {
- VAR_SET_INDVAR(dst_var, src_var->var_varptr1);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var %s to var %s", dst_var->var_name,
- src_var->var_name);
- }
- return (0);
-}
-
-/*
- * Searches for the var named "name", and if not found
- * allocates it. The then copies the value from
- * the src_var into the destination var "name"
- * If the var "name" cannot be found or allocated, or the var "src_name"
- * cannot be found, the routine returns -1, otherwise it returns 0.
- */
-int
-var_assign_var(char *name, char *src_name)
-{
- var_t *dst_var, *src_var;
-
- name += 1;
- src_name += 1;
-
- if ((src_var = var_find(src_name)) == NULL) {
- filebench_log(LOG_ERROR,
- "Cannot find source variable %s", src_name);
- return (-1);
- }
-
- if ((dst_var = var_find(name)) == NULL)
- dst_var = var_alloc(name);
-
- if (dst_var == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (-1);
- }
-
- if ((dst_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
- filebench_log(LOG_ERROR,
- "Cannot assign var to Random variable %s", name);
- return (-1);
- }
-
- return (var_copy(dst_var, src_var));
-}
-
-/*
- * Like var_assign_integer, only this routine copies the
- * supplied "string" into the var named "name". If the var
- * named "name" cannot be found then it is first allocated
- * before the copy. Space for the string in the var comes
- * from interprocess shared memory. If the var "name"
- * cannot be found or allocated, or the memory for the
- * var_val.string copy of "string" cannot be allocated, the
- * routine returns -1, otherwise it returns 0.
- */
-int
-var_assign_string(char *name, char *string)
-{
- var_t *var;
- char *strptr;
-
- name += 1;
-
- if ((var = var_find(name)) == NULL)
- var = var_alloc(name);
-
- if (var == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (-1);
- }
-
- if ((var->var_type & VAR_TYPE_MASK) == VAR_TYPE_RANDOM) {
- filebench_log(LOG_ERROR,
- "Cannot assign string to random variable %s", name);
- return (-1);
- }
-
- if ((strptr = ipc_stralloc(string)) == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (-1);
- }
- VAR_SET_STR(var, strptr);
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "Var assign string $%s=%s", name, string);
-
- return (0);
-}
-
-/*
- * Allocates a local var. The then extracts the var_string from
- * the var named "string" and copies it into the var_string
- * of the var "name", after first allocating a piece of
- * interprocess shared string memory. Returns a pointer to the
- * newly allocated local var or NULL on error.
- */
-var_t *
-var_lvar_assign_var(char *name, char *src_name)
-{
- var_t *dst_var, *src_var;
-
- src_name += 1;
-
- if ((src_var = var_find(src_name)) == NULL) {
- filebench_log(LOG_ERROR,
- "Cannot find source variable %s", src_name);
- return (NULL);
- }
-
- dst_var = var_lvar_alloc_local(name);
-
- if (dst_var == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (NULL);
- }
-
- /*
- * if referencing another local var which is currently
- * empty, indirect to it
- */
- if ((src_var->var_type & VAR_TYPE_MASK) == VAR_TYPE_LOCAL) {
- VAR_SET_INDVAR(dst_var, src_var);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign local var %s to %s", name, src_name);
- return (dst_var);
- }
-
- if (VAR_HAS_BOOLEAN(src_var)) {
- VAR_SET_BOOL(dst_var, src_var->var_val.boolean);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var (%s, %p)=%s", name,
- dst_var, src_var->var_val.boolean?"true":"false");
- } else if (VAR_HAS_INTEGER(src_var)) {
- VAR_SET_INT(dst_var, src_var->var_val.integer);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var (%s, %p)=%llu", name,
- dst_var, (u_longlong_t)src_var->var_val.integer);
- } else if (VAR_HAS_STRING(src_var)) {
- char *strptr;
-
- if ((strptr = ipc_stralloc(src_var->var_val.string)) == NULL) {
- filebench_log(LOG_ERROR,
- "Cannot assign variable %s",
- name);
- return (NULL);
- }
- VAR_SET_STR(dst_var, strptr);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var (%s, %p)=%s", name,
- dst_var, src_var->var_val.string);
- } else if (VAR_HAS_DOUBLE(src_var)) {
- /* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
- VAR_SET_INT(dst_var, src_var->var_val.dbl_flt);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var (%s, %p)=%8.2f", name,
- dst_var, src_var->var_val.dbl_flt);
- } else if (VAR_HAS_RANDDIST(src_var)) {
- VAR_SET_RAND(dst_var, src_var->var_val.randptr);
- filebench_log(LOG_DEBUG_SCRIPT,
- "Assign var (%s, %p)=%llu", name,
- dst_var, (u_longlong_t)src_var->var_val.integer);
- }
-
- return (dst_var);
-}
-
-/*
- * the routine allocates a new local var and sets
- * its var_boolean's value to that of the supplied
- * boolean. It returns a pointer to the new local var
- */
-var_t *
-var_lvar_assign_boolean(char *name, boolean_t bool)
-{
- var_t *var;
-
- var = var_lvar_alloc_local(name);
-
- if (var == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (NULL);
- }
-
- VAR_SET_BOOL(var, bool);
-
- filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%s",
- name, bool ? "true" : "false");
-
- return (var);
-}
-
-/*
- * the routine allocates a new local var and sets
- * its var_integers's value to that of the supplied
- * integer. It returns a pointer to the new local var
- */
-var_t *
-var_lvar_assign_integer(char *name, fbint_t integer)
-{
- var_t *var;
-
- var = var_lvar_alloc_local(name);
-
- if (var == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (NULL);
- }
-
- VAR_SET_INT(var, integer);
-
- filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%llu",
- name, (u_longlong_t)integer);
-
- return (var);
-}
-
-/*
- * the routine allocates a new local var and sets
- * its var_dbl_flt value to that of the supplied
- * double precission floating point number. It returns
- * a pointer to the new local var
- */
-var_t *
-var_lvar_assign_double(char *name, double dbl)
-{
- var_t *var;
-
- var = var_lvar_alloc_local(name);
-
- if (var == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (NULL);
- }
-
- VAR_SET_DBL(var, dbl);
-
- filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%8.2f", name, dbl);
-
- return (var);
-}
-
-/*
- * Like var_lvar_assign_integer, only this routine copies the
- * supplied "string" into the var named "name". If the var
- * named "name" cannot be found then it is first allocated
- * before the copy. Space for the string in the var comes
- * from interprocess shared memory. The allocated local var
- * is returned at as a char *, or NULL on error.
- */
-var_t *
-var_lvar_assign_string(char *name, char *string)
-{
- var_t *var;
- char *strptr;
-
- var = var_lvar_alloc_local(name);
-
- if (var == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (NULL);
- }
-
- if ((strptr = ipc_stralloc(string)) == NULL) {
- filebench_log(LOG_ERROR, "Cannot assign variable %s",
- name);
- return (NULL);
- }
- VAR_SET_STR(var, strptr);
-
- filebench_log(LOG_DEBUG_SCRIPT,
- "Lvar_assign_string (%s, %p)=%s", name, var, string);
-
- return (var);
-}
-
-/*
- * Tests to see if the supplied variable name without the portion after
- * the last period is that of a random variable. If it is, it returns
- * the number of characters to backspace to skip the period and field
- * name. Otherwise it returns 0.
- */
-int
-var_is_set4_randvar(char *name)
-{
- var_t *var;
- char varname[128];
- int namelength;
- char *sp;
-
- (void) strncpy(varname, name, 128);
- namelength = strlen(varname);
- sp = varname + namelength;
-
- while (sp != varname) {
- int c = *sp;
-
- *sp = 0;
- if (c == '.')
- break;
-
- sp--;
- }
-
- /* not a variable name + field? */
- if (sp == varname)
- return (0);
-
- /* first part not a variable name? */
- if ((var = var_find(varname+1)) == NULL)
- return (0);
-
- /* Make sure it is a random variable */
- if ((var->var_type & VAR_TYPE_MASK) != VAR_TYPE_RANDOM)
- return (0);
-
- /* calculate offset from end of random variable name */
- return (namelength - (sp - varname));
-}
-
-/*
- * Implements a simple path name like scheme for finding values
- * to place in certain specially named vars. The first part of
- * the name is interpreted as a category of either: stats,
- * eventgen, date, script, or host var. If a match is found,
- * the appropriate routine is called to fill in the requested
- * value in the provided var_t, and a pointer to the supplied
- * var_t is returned. If the requested value is not found, NULL
- * is returned.
- */
-static var_t *
-var_find_internal(var_t *var)
-{
- char *n = fb_stralloc(var->var_name);
- char *name = n;
- var_t *rtn = NULL;
-
- name++;
- if (name[strlen(name) - 1] != '}')
- return (NULL);
- name[strlen(name) - 1] = 0;
-
- if (strncmp(name, STATS_VAR, strlen(STATS_VAR)) == 0)
- rtn = stats_findvar(var, name + strlen(STATS_VAR));
-
- if (strcmp(name, EVENTGEN_VAR) == 0)
- rtn = eventgen_ratevar(var);
-
- if (strcmp(name, DATE_VAR) == 0)
- rtn = date_var(var);
-
- if (strcmp(name, SCRIPT_VAR) == 0)
- rtn = script_var(var);
-
- if (strcmp(name, HOST_VAR) == 0)
- rtn = host_var(var);
-
- free(n);
-
- return (rtn);
-}
-
-/*
- * Calls the C library routine getenv() to obtain the value
- * for the environment variable specified by var->var_name.
- * If found, the value string is returned in var->var_val.string.
- * If the requested value is not found, NULL is returned.
- */
-static var_t *
-var_find_environment(var_t *var)
-{
- char *n = fb_stralloc(var->var_name);
- char *name = n;
- char *strptr;
-
- name++;
- if (name[strlen(name) - 1] != ')') {
- free(n);
- return (NULL);
- }
- name[strlen(name) - 1] = 0;
-
- if ((strptr = getenv(name)) != NULL) {
- free(n);
- VAR_SET_STR(var, strptr);
- return (var);
- } else {
- free(n);
- return (NULL);
- }
-}
-
-/*
- * Look up special variables. The "name" argument is used to find
- * the desired special var and fill it with an appropriate string
- * value. Looks for an already allocated var of the same name on
- * the shm_var_dyn_list. If not found a new dynamic var is allocated.
- * if the name begins with '{', it is an internal variable, and
- * var_find_internal() is called. If the name begins with '(' it
- * is an environment varable, and var_find_environment() is
- * called. On success, a pointer to the var_t is returned,
- * otherwise, NULL is returned.
- */
-static var_t *
-var_find_dynamic(char *name)
-{
- var_t *var = NULL;
- var_t *v = filebench_shm->shm_var_dyn_list;
- var_t *rtn;
-
- /*
- * Lookup a reference to the var handle for this
- * special var
- */
- for (v = filebench_shm->shm_var_dyn_list; v != NULL; v = v->var_next) {
- if (strcmp(v->var_name, name) == 0) {
- var = v;
- break;
- }
- }
-
- if (var == NULL)
- var = var_alloc_dynamic(name);
-
- /* Internal system control variable */
- if (*name == '{') {
- rtn = var_find_internal(var);
- if (rtn == NULL)
- filebench_log(LOG_ERROR,
- "Cannot find internal variable %s",
- var->var_name);
- return (rtn);
- }
-
- /* Lookup variable in environment */
- if (*name == '(') {
- rtn = var_find_environment(var);
- if (rtn == NULL)
- filebench_log(LOG_ERROR,
- "Cannot find environment variable %s",
- var->var_name);
- return (rtn);
- }
-
- return (NULL);
-}
-
-/*
- * replace the avd_t attribute value descriptor in the new FLOW_MASTER flowop
- * that points to a local variable with a new avd_t containing
- * the actual value from the local variable.
- */
-void
-avd_update(avd_t *avdp, var_t *lvar_list)
-{
- var_t *old_lvar, *new_lvar;
-
- if ((*avdp)->avd_type == AVD_IND_VAR) {
-
- /* Make sure there is a local var */
- if ((old_lvar = (*avdp)->avd_val.varptr) == NULL) {
- filebench_log(LOG_ERROR,
- "avd_update: local var not found");
- return;
- }
- } else {
- /* Empty or not indirect, so no update needed */
- return;
- }
-
- /* allocate a new avd using the new or old lvar contents */
- if ((new_lvar =
- var_find_list(old_lvar->var_name, lvar_list)) != NULL)
- (*avdp) = avd_alloc_var_ptr(new_lvar);
- else
- (*avdp) = avd_alloc_var_ptr(old_lvar);
-}
-
-void
-var_update_comp_lvars(var_t *newlvar, var_t *proto_comp_vars,
- var_t *mstr_lvars)
-{
- var_t *proto_lvar;
-
- /* find the prototype lvar from the inherited list */
- proto_lvar = var_find_list_only(newlvar->var_name, proto_comp_vars);
-
- if (proto_lvar == NULL)
- return;
-
- /*
- * if the new local variable has not already been assigned
- * a value, try to copy a value from the prototype local variable
- */
- if ((newlvar->var_type & VAR_TYPE_SET_MASK) == 0) {
-
- /* copy value from prototype lvar to new lvar */
- (void) var_copy(newlvar, proto_lvar);
- }
-
- /* If proto lvar is indirect, see if we can colapse indirection */
- if (VAR_HAS_INDVAR(proto_lvar)) {
- var_t *uplvp;
-
- uplvp = (var_t *)proto_lvar->var_varptr1;
-
- /* search for more current uplvar on comp master list */
- if (mstr_lvars) {
- uplvp = var_find_list_only(
- uplvp->var_name, mstr_lvars);
- VAR_SET_INDVAR(newlvar, uplvp);
- }
-
- if (VAR_HAS_INDVAR(uplvp))
- VAR_SET_INDVAR(newlvar, uplvp->var_varptr1);
- }
-}
diff --git a/usr/src/cmd/filebench/common/vars.h b/usr/src/cmd/filebench/common/vars.h
deleted file mode 100644
index 7cbad71945..0000000000
--- a/usr/src/cmd/filebench/common/vars.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _FB_VARS_H
-#define _FB_VARS_H
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Attribute Value Descriptor types */
-typedef enum avd_type {
- AVD_INVALID = 0, /* avd is empty */
- AVD_VAL_BOOL, /* avd contains a boolean_t */
- AVD_VARVAL_BOOL, /* avd points to the boolean_t in a var_t */
- AVD_VAL_INT, /* avd contains an fbint_t */
- AVD_VARVAL_INT, /* avd points to the fbint_t in a var_t */
- AVD_VAL_STR, /* avd contains a sting (*char) */
- AVD_VARVAL_STR, /* avd points to a string in a var_t */
- AVD_VAL_DBL, /* avd contains a double float */
- AVD_VARVAL_DBL, /* avd points to the double in a var_t */
- AVD_IND_VAR, /* avd points a var_t */
- AVD_IND_RANDVAR /* avd points to the randdist_t associated */
- /* with a random type var_t */
-} avd_type_t;
-
-typedef uint64_t fbint_t;
-
-/* Attribute Value Descriptor */
-typedef struct avd {
- avd_type_t avd_type;
- union {
- boolean_t boolval;
- boolean_t *boolptr;
- fbint_t intval;
- fbint_t *intptr;
- double dblval;
- double *dblptr;
- char *strval;
- char **strptr;
- struct randdist *randptr;
- struct var *varptr;
- } avd_val;
-} *avd_t;
-
-#define AVD_IS_RANDOM(vp) ((vp) && ((vp)->avd_type == AVD_IND_RANDVAR))
-#define AVD_IS_STRING(vp) ((vp) && (((vp)->avd_type == AVD_VAL_STR) || \
- ((vp)->avd_type == AVD_VARVAL_STR)))
-#define AVD_IS_VAR(vp) ((vp) && (((vp)->avd_type == AVD_IND_VAR) || \
- ((vp)->avd_type == AVD_VARVAL_INT) || \
- ((vp)->avd_type == AVD_VARVAL_DBL)))
-
-typedef struct var {
- char *var_name;
- int var_type;
- struct var *var_next;
- union {
- boolean_t boolean;
- fbint_t integer;
- double dbl_flt;
- char *string;
- struct randdist *randptr;
- struct var *varptr2;
- } var_val;
- struct var *var_varptr1;
-} var_t;
-
-/* basic var types */
-#define VAR_TYPE_GLOBAL 0x0000 /* global variable */
-#define VAR_TYPE_DYNAMIC 0x1000 /* Dynamic variable */
-#define VAR_TYPE_RANDOM 0x2000 /* random variable */
-#define VAR_TYPE_LOCAL 0x3000 /* Local variable */
-#define VAR_TYPE_MASK 0xf000
-
-/* various var subtypes that a var can be set to */
-#define VAR_TYPE_BOOL_SET 0x0100 /* var contains a boolean */
-#define VAR_TYPE_INT_SET 0x0200 /* var contains an integer */
-#define VAR_TYPE_STR_SET 0x0300 /* var contains a string */
-#define VAR_TYPE_DBL_SET 0x0400 /* var contains a double */
-#define VAR_TYPE_RAND_SET 0x0500 /* var contains a randdist pointer */
-#define VAR_TYPE_INDVAR_SET 0x0700 /* var points to another variable(s) */
-#define VAR_TYPE_SET_MASK 0x0f00
-
-/* indirection to another variable or variables with binary op */
-#define VAR_IND_ASSIGN 0x0000 /* just assignment to another var */
-#define VAR_IND_BINOP_INT 0x0010 /* binary op with an integer */
-#define VAR_IND_BINOP_DBL 0x0020 /* binary op with a double float */
-#define VAR_IND_BINOP_VAR 0x0030 /* binary op with another var */
-#define VAR_INDBINOP_MASK 0x00f0
-
-
-#define VAR_IND_VAR_SUM_VC 0x0001 /* var sums var | cnst and *varptr1 */
-#define VAR_IND_VAR_DIF_VC 0x0002 /* var subs var | cnst and *varptr1 */
-#define VAR_IND_C_DIF_VAR 0x0003 /* var subs *varptr1 and constant */
-#define VAR_IND_VAR_MUL_VC 0x0005 /* var muls var | cnst and *varptr1 */
-#define VAR_IND_VAR_DIV_VC 0x0006 /* var divs var | cnst by *varptr1 */
-#define VAR_IND_C_DIV_VAR 0x0007 /* var divs *varptr1 by constant */
-#define VAR_INDVAR_MASK 0x000f
-
-/* Binary ops between an integer and a variable */
-#define VAR_IND_INT_SUM_IV (VAR_IND_BINOP_INT | VAR_IND_VAR_SUM_VC)
-#define VAR_IND_IV_DIF_INT (VAR_IND_BINOP_INT | VAR_IND_VAR_DIF_VC)
-#define VAR_IND_INT_DIF_IV (VAR_IND_BINOP_INT | VAR_IND_C_DIF_VAR)
-#define VAR_IND_INT_MUL_IV (VAR_IND_BINOP_INT | VAR_IND_VAR_MUL_VC)
-#define VAR_IND_IV_DIV_INT (VAR_IND_BINOP_INT | VAR_IND_VAR_DIV_VC)
-#define VAR_IND_INT_DIV_IV (VAR_IND_BINOP_INT | VAR_IND_C_DIV_VAR)
-
-/* Binary ops between a double float and a variable */
-#define VAR_IND_DBL_SUM_IV (VAR_IND_BINOP_DBL | VAR_IND_VAR_SUM_VC)
-#define VAR_IND_IV_DIF_DBL (VAR_IND_BINOP_DBL | VAR_IND_VAR_DIF_VC)
-#define VAR_IND_DBL_DIF_IV (VAR_IND_BINOP_DBL | VAR_IND_C_DIF_VAR)
-#define VAR_IND_DBL_MUL_IV (VAR_IND_BINOP_DBL | VAR_IND_VAR_MUL_VC)
-#define VAR_IND_IV_DIV_DBL (VAR_IND_BINOP_DBL | VAR_IND_VAR_DIV_VC)
-#define VAR_IND_DBL_DIV_IV (VAR_IND_BINOP_DBL | VAR_IND_C_DIV_VAR)
-
-/* Binary ops between two variables: varptr2 op varptr1 */
-#define VAR_IND_IV_SUM_IV (VAR_IND_BINOP_VAR | VAR_IND_VAR_SUM_VC)
-#define VAR_IND_IV_DIF_IV (VAR_IND_BINOP_VAR | VAR_IND_VAR_DIF_VC)
-#define VAR_IND_IV_MUL_IV (VAR_IND_BINOP_VAR | VAR_IND_VAR_MUL_VC)
-#define VAR_IND_IV_DIV_IV (VAR_IND_BINOP_VAR | VAR_IND_VAR_DIV_VC)
-
-#define VAR_HAS_BOOLEAN(vp) \
- (((vp)->var_type & VAR_TYPE_SET_MASK) == VAR_TYPE_BOOL_SET)
-
-#define VAR_HAS_INTEGER(vp) \
- (((vp)->var_type & VAR_TYPE_SET_MASK) == VAR_TYPE_INT_SET)
-
-#define VAR_HAS_DOUBLE(vp) \
- (((vp)->var_type & VAR_TYPE_SET_MASK) == VAR_TYPE_DBL_SET)
-
-#define VAR_HAS_STRING(vp) \
- (((vp)->var_type & VAR_TYPE_SET_MASK) == VAR_TYPE_STR_SET)
-
-#define VAR_HAS_RANDDIST(vp) \
- (((vp)->var_type & VAR_TYPE_SET_MASK) == VAR_TYPE_RAND_SET)
-
-#define VAR_HAS_INDVAR(vp) \
- ((((vp)->var_type & VAR_TYPE_SET_MASK) == VAR_TYPE_INDVAR_SET) && \
- (((vp)->var_type & VAR_INDBINOP_MASK) == VAR_IND_ASSIGN))
-
-#define VAR_HAS_BINOP(vp) \
- ((((vp)->var_type & VAR_TYPE_SET_MASK) == VAR_TYPE_INDVAR_SET) && \
- (((vp)->var_type & VAR_INDBINOP_MASK) != VAR_IND_ASSIGN))
-
-#define VAR_SET_BOOL(vp, val) \
- { \
- (vp)->var_val.boolean = (val); \
- (vp)->var_type = \
- (((vp)->var_type & (~VAR_TYPE_SET_MASK)) | VAR_TYPE_BOOL_SET);\
- }
-
-#define VAR_SET_INT(vp, val) \
- { \
- (vp)->var_val.integer = (val); \
- (vp)->var_type = \
- (((vp)->var_type & (~VAR_TYPE_SET_MASK)) | VAR_TYPE_INT_SET); \
- }
-
-#define VAR_SET_DBL(vp, val) \
- { \
- (vp)->var_val.dbl_flt = (val); \
- (vp)->var_type = \
- (((vp)->var_type & (~VAR_TYPE_SET_MASK)) | \
- VAR_TYPE_DBL_SET); \
- }
-
-#define VAR_SET_STR(vp, val) \
- { \
- (vp)->var_val.string = (val); \
- (vp)->var_type = \
- (((vp)->var_type & (~VAR_TYPE_SET_MASK)) | \
- VAR_TYPE_STR_SET); \
- }
-
-#define VAR_SET_RAND(vp, val) \
- { \
- (vp)->var_val.randptr = (val); \
- (vp)->var_type = \
- (((vp)->var_type & (~VAR_TYPE_SET_MASK)) | \
- VAR_TYPE_RAND_SET); \
- }
-
-#define VAR_SET_INDVAR(vp, val) \
- { \
- (vp)->var_varptr1 = (val); \
- (vp)->var_type = \
- (((vp)->var_type & (~(VAR_TYPE_SET_MASK | \
- VAR_INDVAR_MASK))) | \
- VAR_TYPE_INDVAR_SET); \
- }
-
-#define VAR_SET_BINOP_INDVAR(vp, val, st) \
- { \
- (vp)->var_varptr1 = (val); \
- (vp)->var_type = \
- (((vp)->var_type & (~(VAR_TYPE_SET_MASK | \
- VAR_INDVAR_MASK))) | \
- (VAR_TYPE_INDVAR_SET | st)); \
- }
-
-avd_t avd_bool_alloc(boolean_t bool);
-avd_t avd_int_alloc(fbint_t integer);
-avd_t avd_str_alloc(char *string);
-boolean_t avd_get_bool(avd_t);
-fbint_t avd_get_int(avd_t);
-double avd_get_dbl(avd_t);
-char *avd_get_str(avd_t);
-void avd_update(avd_t *avdp, var_t *lvar_list);
-avd_t var_ref_attr(char *name);
-int var_assign_boolean(char *name, boolean_t bool);
-int var_assign_integer(char *name, fbint_t integer);
-int var_assign_double(char *name, double dbl);
-int var_assign_string(char *name, char *string);
-int var_assign_var(char *name, char *string);
-int var_assign_op_var_int(char *name, int optype, char *src1, fbint_t src2);
-int var_assign_op_var_var(char *name, int optype, char *src1, char *src2);
-void var_update_comp_lvars(var_t *newlvar, var_t *proto_comp_vars,
- var_t *mstr_lvars);
-var_t *var_define_randvar(char *name);
-var_t *var_find_randvar(char *name);
-boolean_t var_to_boolean(char *name);
-fbint_t var_to_integer(char *name);
-double var_to_double(char *name);
-var_t *var_lvar_alloc_local(char *name);
-var_t *var_lvar_assign_boolean(char *name, boolean_t);
-var_t *var_lvar_assign_integer(char *name, fbint_t);
-var_t *var_lvar_assign_double(char *name, double);
-var_t *var_lvar_assign_string(char *name, char *string);
-var_t *var_lvar_assign_var(char *name, char *src_name);
-char *var_to_string(char *name);
-char *var_randvar_to_string(char *name, int param);
-int var_is_set4_randvar(char *name);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FB_VARS_H */
diff --git a/usr/src/cmd/filebench/config/Makefile b/usr/src/cmd/filebench/config/Makefile
deleted file mode 100644
index fe8e43b211..0000000000
--- a/usr/src/cmd/filebench/config/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-.KEEP_STATE:
-
-include ../../Makefile.cmd
-
-CONFIGS = fileio.prof filemacro.prof filemicro.prof generic.func \
-seqread.prof randomread.prof multi_fileserver.prof newfeatures.prof \
-videoserver.prof
-ROOTUSRBENCHDIR = $(ROOT)/usr/benchmarks
-ROOTUSRBENCHFBCONFIGDIR = $(ROOTUSRBENCHDIR)/filebench/config
-FBCONFIGS = $(CONFIGS:%=$(ROOTUSRBENCHFBCONFIGDIR)/%)
-
-FILEMODE= 0444
-
-all clobber clean lint:
-
-$(ROOTUSRBENCHDIR):
- $(INS.dir)
-
-$(ROOTUSRBENCHFBCONFIGDIR):
- $(INS.dir)
-
-$(ROOTUSRBENCHFBCONFIGDIR)/%:%
- $(INS.file)
-
-install: $(ROOTUSRBENCHDIR) .WAIT $(ROOTUSRBENCHFBCONFIGDIR) .WAIT $(FBCONFIGS)
diff --git a/usr/src/cmd/filebench/config/fileio.prof b/usr/src/cmd/filebench/config/fileio.prof
deleted file mode 100644
index a5ac590228..0000000000
--- a/usr/src/cmd/filebench/config/fileio.prof
+++ /dev/null
@@ -1,125 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-DEFAULTS {
- runtime = 120;
- dir = /tmp;
- stats = /tmp;
- filesystem = tmpfs;
- description = "fileio tmpfs";
- filesize = 10g;
-}
-
-CONFIG randomread2k {
- function = generic;
- personality = randomread;
- nthreads = 16;
- iosize = 2k;
-}
-
-CONFIG randomread8k {
- function = generic;
- personality = randomread;
- nthreads = 16;
- iosize = 8k;
-}
-
-CONFIG randomread1m {
- function = generic;
- personality = randomread;
- nthreads = 16;
- iosize = 1m;
-}
-
-CONFIG randomwrite2k {
- function = generic;
- personality = randomwrite;
- nthreads = 16;
- iosize = 2k;
-}
-
-CONFIG randomwrite8k {
- function = generic;
- personality = randomwrite;
- nthreads = 16;
- iosize = 8k;
-}
-
-CONFIG randomwrite1m {
- function = generic;
- personality = randomwrite;
- nthreads = 16;
- iosize = 1m;
-}
-
-CONFIG singlestreamread1m {
- function = generic;
- personality = singlestreamread;
- iosize = 1m;
-}
-
-CONFIG singlestreamreaddirect1m {
- function = generic;
- personality = singlestreamreaddirect;
- iosize = 1m;
-}
-
-CONFIG singlestreamwrite1m {
- function = generic;
- personality = singlestreamwrite;
- iosize = 1m;
-}
-
-CONFIG singlestreamwritedirect1m {
- function = generic;
- personality = singlestreamwritedirect;
- iosize = 1m;
-}
-
-CONFIG multistreamread1m {
- function = generic;
- personality = multistreamread;
- iosize = 1m;
-}
-
-CONFIG multistreamreaddirect1m {
- function = generic;
- personality = multistreamreaddirect;
- iosize = 1m;
-}
-
-CONFIG multistreamwrite1m {
- function = generic;
- personality = multistreamwrite;
- iosize = 1m;
-}
-
-CONFIG multistreamwritedirect1m {
- function = generic;
- personality = multistreamwritedirect;
- iosize = 1m;
-}
-
diff --git a/usr/src/cmd/filebench/config/filemacro.prof b/usr/src/cmd/filebench/config/filemacro.prof
deleted file mode 100644
index d03841981f..0000000000
--- a/usr/src/cmd/filebench/config/filemacro.prof
+++ /dev/null
@@ -1,129 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-DEFAULTS {
- runtime = 120;
- dir = /tmp;
- stats = /tmp;
- filesystem = tmpfs;
- description = "filemacro tmpfs";
-}
-
-CONFIG fileserver {
- function = generic;
- personality = fileserver;
- nfiles = 20000;
- meandirwidth = 20;
- filesize = 2k;
- nthreads = 100;
- meaniosize = 16k;
-}
-
-CONFIG varmail {
- personality = varmail;
- function = generic;
- nfiles = 20000;
- meandirwidth = 1000000;
- filesize = 1k;
- nthreads = 16;
- meaniosize = 16k;
-}
-
-CONFIG webproxy {
- personality = webproxy;
- function = generic;
- nfiles = 20000;
- meandirwidth = 1000000;
- filesize = 1k;
- nthreads = 100;
- meaniosize = 16k;
-}
-
-CONFIG webserver {
- personality = webserver;
- function = generic;
- nfiles = 20000;
- meandirwidth = 20;
- filesize = 1k;
- nthreads = 100;
-}
-
-CONFIG large_db_oltp_2k_cached {
- personality = oltp;
- function = generic;
- cached = 1;
- directio = 0;
- iosize = 2k;
- nshadows = 200;
- ndbwriters = 10;
- usermode = 20000;
- filesize = 1g;
- memperthread = 1m;
- workingset = 0;
-}
-
-CONFIG large_db_oltp_2k_uncached {
- personality = oltp;
- function = generic;
- cached = 0;
- directio = 1;
- iosize = 2k;
- nshadows = 200;
- ndbwriters = 10;
- usermode = 20000;
- filesize = 1g;
- memperthread = 1m;
- workingset = 0;
-}
-
-CONFIG large_db_oltp_8k_cached {
- personality = oltp;
- function = generic;
- cached = 1;
- directio = 0;
- iosize = 8k;
- nshadows = 200;
- ndbwriters = 10;
- usermode = 20000;
- filesize = 1g;
- memperthread = 1m;
- workingset = 0;
-}
-
-CONFIG large_db_oltp_8k_uncached {
- personality = oltp;
- function = generic;
- cached = 0;
- directio = 1;
- iosize = 8k;
- nshadows = 200;
- ndbwriters = 10;
- usermode = 20000;
- filesize = 1g;
- memperthread = 1m;
- workingset = 0;
-}
-
diff --git a/usr/src/cmd/filebench/config/filemicro.prof b/usr/src/cmd/filebench/config/filemicro.prof
deleted file mode 100644
index 5a2b2b8f76..0000000000
--- a/usr/src/cmd/filebench/config/filemicro.prof
+++ /dev/null
@@ -1,143 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-DEFAULTS {
- runtime = 60;
- dir = /tmp;
- stats = /tmp;
- filesystem = tmpfs;
- description = "filemicro tmpfs";
-}
-
-CONFIG createandalloc {
- function = generic;
- personality = filemicro_create;
-}
-
-CONFIG createandallocsync {
- function = generic;
- personality = filemicro_create;
- sync = true;
-}
-
-CONFIG createallocfsync {
- function = generic;
- personality = filemicro_writefsync;
-}
-
-CONFIG createallocappend {
- function = generic;
- personality = filemicro_createrand;
-}
-
-CONFIG randread2k {
- function = generic;
- personality = filemicro_rread;
-}
-
-CONFIG randread2kcached {
- function = generic;
- personality = filemicro_rread;
- cached = true;
-}
-
-CONFIG randwrite2ksync {
- function = generic;
- personality = filemicro_rwrite;
- sync = true;
-}
-
-CONFIG randwrite2ksync4thread {
- function = generic;
- personality = filemicro_rwrite;
- nthreads = 4;
- sync = true;
-}
-
-CONFIG randwrite8kfsynccached {
- function = generic;
- personality = filemicro_rwritefsync;
- cached = true;
-}
-
-CONFIG seqread32k {
- function = generic;
- personality = filemicro_seqread;
- iosize = 32k;
- filesize = 100m;
-}
-
-CONFIG seqread32kcached {
- function = generic;
- personality = filemicro_seqread;
- iosize = 32k;
- filesize = 100m;
- cached = true;
-}
-
-CONFIG seqwrite32k {
- function = generic;
- personality = filemicro_seqwrite;
- iosize = 32k;
-}
-
-CONFIG seqwrite32kdsync {
- function = generic;
- personality = filemicro_seqwrite;
- iosize = 32k;
- sync = true;
-}
-
-CONFIG seqwriterand8k {
- function = generic;
- personality = filemicro_seqwriterand;
-}
-
-CONFIG unlink1g {
- function = generic;
- personality = filemicro_delete;
- nthreads = 1;
-}
-
-CONFIG createfiles {
- function = generic;
- personality = filemicro_createfiles;
-}
-
-CONFIG rwritedsync {
- function = generic;
- personality = filemicro_rwritedsync;
-}
-
-CONFIG filemicro_seqwriterandvargam {
- function = generic;
- personality = filemicro_seqwriterandvargam;
-}
-
-CONFIG filemicro_seqwriterandvartab {
- function = generic;
- personality = filemicro_seqwriterandvartab;
-}
diff --git a/usr/src/cmd/filebench/config/generic.func b/usr/src/cmd/filebench/config/generic.func
deleted file mode 100644
index a2adfcb521..0000000000
--- a/usr/src/cmd/filebench/config/generic.func
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-sub pre_run {
- # Initialize filebench to appropriate personality, create files
- # and processes
- op_init();
-
- # The op_load command automatically creates files
- op_load(conf_reqval("personality"));
-
- # Flush the FS cache
- op_fsflush();
-
- # Initialise statistics and argument arrays
- @ext_stats=();
- @file_stats=();
- @arg_stats=();
-}
-
-sub post_run {
- my $statsbase = get_STATSBASE();
-
- # Create a html summary of the run
- system ("cd $statsbase; " . get_FILEBENCH() . "/scripts/filebench_compare $statsbase")
-}
-
-sub bm_run {
- my $runtime = conf_reqval("runtime");
- my $fs = get_CONFNAME();
- my $warmuptime = "";
-
- if (conf_exists("warmuptime") == 1) {
- $warmuptime = conf_reqval("warmuptime");
- }
-
- # The following array must not contain empty values ! This causes the
- # statistics scripts to miss arguments !
- # Clear, run the benchmark, snap statistics
- # This command will also run external statistics (supplied in an array)
- # if desired
- # Statistics automatically dumped into directory matching stats
- # profile variable
- # <stats>/<hostname>-<date-time>/<personality>
-
- # create processes and start run, then collect statistics
- op_stats($runtime,$warmuptime,"stats.$fs",@ext_stats,@file_stats,@arg_stats);
-}
-
-1;
diff --git a/usr/src/cmd/filebench/config/multi_fileserver.prof b/usr/src/cmd/filebench/config/multi_fileserver.prof
deleted file mode 100644
index f5fee327c0..0000000000
--- a/usr/src/cmd/filebench/config/multi_fileserver.prof
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Example multi-client fileserver workload. Three clients named "client1",
-# "client2" and "client3" access one file server whose shared directory is
-# mounted on each client under the pathname "/theserver". This will run the
-# fileserver workload on each of the clients, using seperate filesets for
-# each server.
-
-MULTICLIENT {
- targetpath = /theserver;
- clients = client1, client2, client3;
-}
-
-DEFAULTS {
- runtime = 60;
- dir = /tmp;
- stats = /tmp;
- filesystem = nfs;
- description = "fileserver nfs";
-}
-
-CONFIG fileserver {
- function = generic;
- personality = fileserver;
- nfiles = 1000;
- meandirwidth = 20;
- filesize = 16k;
- nthreads = 1;
- meaniosize = 2k;
-}
diff --git a/usr/src/cmd/filebench/config/newfeatures.prof b/usr/src/cmd/filebench/config/newfeatures.prof
deleted file mode 100644
index b974448bd5..0000000000
--- a/usr/src/cmd/filebench/config/newfeatures.prof
+++ /dev/null
@@ -1,101 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Excersizes the latest features of FileBench by running their
-# respective test workloads.
-
-DEFAULTS {
- runtime = 120;
- dir = /tmp;
- stats = /tmp;
- filesystem = tmpfs;
- description = "newfeatures tmpfs";
-}
-
-CONFIG seqwrite_randvar_gamma {
- function = generic;
- personality = filemicro_seqwriterandvargam;
-}
-
-CONFIG seqwrite_randvar_tabular {
- function = generic;
- personality = filemicro_seqwriterandvartab;
-}
-
-CONFIG rate_limit_copy {
- function = generic;
- personality = ratelimcopyfiles;
- eventrate = 20;
-}
-
-CONFIG list_dirs_test {
- function = generic;
- personality = listdirs;
-}
-
-CONFIG make_dirs_test {
- function = generic;
- personality = makedirs;
-}
-
-CONFIG remove_dirs_test {
- function = generic;
- personality = removedirs;
-}
-
-CONFIG open_files_test {
- function = generic;
- personality = openfiles;
-}
-
-CONFIG video_server_test {
- function = generic;
- personality = videoserver;
- filesize = 2g;
- numactivevids = 4;
- numpassivevids = 20;
- nthreads = 6;
- eventrate = 12;
- repintval = 20;
- passvidsname = bigfileset;
- actvidsname = u2fileset;
- warmuptime = 120;
-}
-
-CONFIG file_indexing_test {
- function = generic;
- personality = randomfileaccess;
- warmuptime = 120;
-}
-
-CONFIG network_file_system {
- function = generic;
- personality = networkfs;
- warmuptime = 120;
-}
-
-CONFIG composite_flowop_test {
- function = generic;
- personality = compflow_demo;
- warmuptime = 120;
-}
diff --git a/usr/src/cmd/filebench/config/randomread.prof b/usr/src/cmd/filebench/config/randomread.prof
deleted file mode 100644
index c224064268..0000000000
--- a/usr/src/cmd/filebench/config/randomread.prof
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-DEFAULTS {
- runtime = 60;
- dir = /tmp;
- stats = /tmp;
- filesystem = tmpfs;
- description = "randomread tmpfs";
-}
-
-CONFIG randomread2k {
- function = generic;
- personality = randomread;
- filesize = 160m;
- iosize = 2k;
- nthreads = 1;
-}
diff --git a/usr/src/cmd/filebench/config/seqread.prof b/usr/src/cmd/filebench/config/seqread.prof
deleted file mode 100644
index 17b87e0410..0000000000
--- a/usr/src/cmd/filebench/config/seqread.prof
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-DEFAULTS {
- runtime = 120;
- dir = /tmp;
- stats = /tmp;
- filesystem = tmpfs;
- description = "seqread tmpfs";
-}
-
-CONFIG seqread1m {
- function = generic;
- personality = multistreamread;
- filesize = 40m;
- iosize = 1m;
- nthreads = 1;
-}
diff --git a/usr/src/cmd/filebench/config/videoserver.prof b/usr/src/cmd/filebench/config/videoserver.prof
deleted file mode 100644
index 93d62ef29d..0000000000
--- a/usr/src/cmd/filebench/config/videoserver.prof
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-DEFAULTS {
- runtime = 120;
- dir = /export/home/tmp;
- stats = /tmp;
- filesystem = zfs;
- description = "fileserver zfs";
-}
-
-CONFIG video_server {
- function = generic;
- personality = videoserver;
- filesize = 2g;
- numactivevids = 8;
- numpassivevids = 40;
- nthreads = 16;
- eventrate = 32;
- repintval = 60;
-}
diff --git a/usr/src/cmd/filebench/fbscript/Makefile b/usr/src/cmd/filebench/fbscript/Makefile
deleted file mode 100644
index fdb1d2d00a..0000000000
--- a/usr/src/cmd/filebench/fbscript/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-.KEEP_STATE:
-
-include ../../Makefile.cmd
-
-SCRIPT = filebench
-ROOTUSRBENCHDIR = $(ROOT)/usr/benchmarks
-ROOTUSRBENCHFBBINDIR = $(ROOTUSRBENCHDIR)/filebench/bin
-FBSCRIPT = $(SCRIPT:%=$(ROOTUSRBENCHFBBINDIR)/%)
-
-all clean lint:
-
-clobber:
- $(RM) $(SCRIPT)
-
-$(ROOTUSRBENCHDIR) $(ROOTUSRBENCHFBBINDIR):
- $(INS.dir)
-
-$(ROOTUSRBENCHFBBINDIR)/%: %
- $(INS.file)
-
-install: $(ROOTUSRBENCHDIR) .WAIT $(ROOTUSRBENCHFBBINDIR) .WAIT $(FBSCRIPT)
diff --git a/usr/src/cmd/filebench/fbscript/filebench.pl b/usr/src/cmd/filebench/fbscript/filebench.pl
deleted file mode 100755
index e55ed2a819..0000000000
--- a/usr/src/cmd/filebench/fbscript/filebench.pl
+++ /dev/null
@@ -1,1189 +0,0 @@
-#!/usr/bin/perl
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-use POSIX;
-use Socket;
-
-my $MULTI_CLIENT = 0;
-my $USE_XANADU = 0;
-my $TIMEOUT = 60;
-my $EOL = "\n";
-my $FILEBENCH = "/usr/benchmarks/filebench";
-my $PROG = "bin/go_filebench";
-my $SHAREDFILEALLOCATOR;
-my $TARGETPATH;
-my $TARGETDIR;
-my $FB_MASTERPATH;
-my $STATSBASE;
-my $CONFNAME;
-my $FSCRIPT;
-my $SCRIPT_NO;
-my @CLIENTLIST = ();
-my %CLIENTHASH = ();
-my @CONFLIST;
-my %MULTIDATA = ();
-my %CMDLINEDATA = ();
-my %DEFDATA = ();
-my %CONFDATA = ();
-my %STATSHASH = ();
-my $OPTIONFLAGS = "cleanupstorage dofscheck";
-@ext_stats=();
-@file_stats=();
-@arg_stats=();
-@pid_arr=();
-
-# The following if test caters for running benchpoint from an alternative path
-#if (-r $ENV{"FILEBENCH") {
-# $FILEBENCH = $ENV{"FILEBENCH"};
-#}
-
-##############################################################################
-## Configuration hash data operations
-##############################################################################
-
-# This sub allows a function program to extract the base directory for filebench
-sub get_FILEBENCH {
- return ($FILEBENCH);
-}
-
-sub get_STATSBASE {
- return ($STATSBASE);
-}
-
-sub get_CONFNAME {
- return ($CONFNAME);
-}
-
-sub multi_putval {
- my ($key) = shift;
- my ($val) = shift;
- @{MULTIDATA{$key}} = ();
- push(@{ $MULTIDATA{$key} }, $val);
-}
-
-sub multi_getval {
- my ($key) = shift;
- return ("@{$MULTIDATA{$key}}");
-}
-
-sub multi_exists {
- my ($key) = shift;
- if (exists($MULTIDATA{$key})) {
- return (1);
- }
- return (0);
-}
-
-sub conf_getval {
- my ($key) = shift;
- return ("@{$CONFDATA{$key}}");
-}
-
-sub conf_reqval {
- my ($key) = shift;
-
- if (exists($CONFDATA{$key})) {
- return ("@{$CONFDATA{$key}}");
- }
- print "ERROR: required key \"$key\" missing from configuration\n";
- exit(1);
-}
-
-sub conf_exists {
- my ($key) = shift;
- if (exists($CONFDATA{$key})) {
- return (1);
- }
- return (0);
-}
-
-sub conf_hash {
- return(%CONFDATA);
-}
-
-##############################################################################
-## Filebench Operations
-##############################################################################
-
-sub op_init {
-}
-
-sub op_load {
- my ($workload) = shift;
- $scriptname = conf_reqval("statsdir") . "/thisrun.f";
-
- if($workload ne '') {
- print ("Creating Client Script " . $scriptname . "\n");
- open (FSCRIPT, ">$scriptname");
- chmod (0755, $scriptname);
- print FSCRIPT "#!$FILEBENCH/$PROG -f\n\n";
- # Load the df
- print FSCRIPT "load $workload\n";
- # Load the user defined defaults
- op_load_defaults();
-
- # enable multiclient, if needed
- if ($MULTI_CLIENT == 1) {
- print FSCRIPT "enable multi master=".multi_getval("masterhost").", client=".conf_getval("myname")."\n";
- }
-
- # Check to see if the path is legal and pointing to the correct FS
- if (conf_exists("dofscheck") == 1) {
- print FSCRIPT "fscheck path=" . conf_reqval("dir") . " fstype=" . conf_reqval("filesystem") . "\n";
- }
-
- # Create the associated files and filesets
- print FSCRIPT "create filesets\n";
- }
- $SCRIPT_NO = 1;
- return(0);
-}
-
-sub op_fsflush {
- print FSCRIPT "fsflush fstype=" . conf_reqval("filesystem") . "\n";
-}
-
-sub op_set {
- my ($var, $val) = @_;
- if($var eq 'debug') {
- print FSCRIPT "debug $val\n";
- } elsif($var ne '') {
- print FSCRIPT "set \$$var=$val\n";
- }
- return(0);
-}
-
-sub op_eventrate {
- my ($eventrate) = shift;
- if ($eventrate ne '') {
- print FSCRIPT "eventgen rate=$eventrate\n";
- return(0);
- }
-}
-
-sub op_run {
- my ($time) = shift;
- print FSCRIPT "run $time\n";
- return(0);
-}
-
-sub op_sleep {
- my ($time) = shift;
- print FSCRIPT "sleep $time\n";
- return(0);
-}
-
-sub op_msg {
- my ($msg) = shift;
- print FSCRIPT "echo \"$msg\"\n";
- return(0);
-}
-
-sub op_quit {
- # Shutdown the appropriate processes
- print FSCRIPT "shutdown processes\n";
-
- # remove filesets, if requested
- if (conf_exists("cleanupstorage") == 1) {
- printf FSCRIPT "shutdown filesets\n";
- }
-
- # Quit filebench
- print FSCRIPT "quit\n";
- close(FSCRIPT);
-}
-
-sub op_statsdir {
- print FSCRIPT "stats directory ".conf_reqval("statsdir")."\n";
- return(0);
-}
-
-sub op_indiv_vars {
- my ($ivar) = shift;
- print FSCRIPT "echo \"\$$ivar\"\n";
- my ($imatch, $ierr, $ibefore, $iafter) = &expect(FSCRIPT,
- $TIMEOUT, "filebench>");
-
- $ibefore =~ /(.*): (.*): (-*\d+)/;
- $imatch = $3;
- $imatch =~ s/^\s+//;
- chomp($imatch);
- return($imatch);
-}
-
-sub op_indiv_stats {
- my ($var) = shift;
- print FSCRIPT "echo \"\${stats.$var}\"\n";
- my ($match, $err, $before, $after) = &expect(FSCRIPT,
- $TIMEOUT, "filebench>");
-
- $before =~ /(.*): (.*): (-*\d+)/;
- $match = $3;
- $match =~ s/^\s+//;
- chomp($match);
- return($match);
-}
-
-sub op_stats {
- my ($time) = shift;
- my ($warmup) = shift;
- my ($statsfile) = shift;
- my $mstrstatsdir = $STATSBASE."/".$CONFNAME;
-
- if ($MULTI_CLIENT == 1) {
- print FSCRIPT "domultisync value=1\n";
- }
-
- # Create the associated processes and start them running
- print FSCRIPT "create processes\n";
-
- if ($warmup ne '') {
- print FSCRIPT "warmup $warmup\n";
- }
-
- if (($time ne '') && ($statsfile ne '')) {
- # Clear the current statistics buffers
- print FSCRIPT "stats clear\n";
-
- # Start external statistics collection (if any)
- # Note all statistics arrays MUST be the same length !
- if (@ext_stats != ()) {
- if (($#ext_stats == $#file_stats) && ($#ext_stats == $#arg_stats)) {
- $script = $mstrstatsdir . "/stats$SCRIPT_NO.sh";
- open (RUNSCRIPT, ">$script");
- chmod (0755, $script);
- print FSCRIPT "system \"$script\"\n";
- $SCRIPT_NO++;
- $index=0;
- foreach my $ext (@ext_stats) {
- print RUNSCRIPT "$FILEBENCH/scripts/collect_$ext $ext $file_stats[$index] ";
- print RUNSCRIPT $mstrstatsdir;
- print RUNSCRIPT " $time $FILEBENCH $arg_stats[$index] &\n";
- $index++;
- }
- }
- }
- close(RUNSCRIPT);
-
- # Sleep for the run time
- print FSCRIPT "sleep $time\n";
-
- # Snap the statistics
- print FSCRIPT "stats snap\n";
-
- # Dump the statistics to a raw file - out required due to filename constraint
- if ($MULTI_CLIENT == 1) {
- print FSCRIPT "domultisync value=2\n";
- print FSCRIPT "stats multidump \"$statsfile.out\"\n";
- } else {
- print FSCRIPT "stats dump \"$statsfile.out\"\n";
- }
-
- # Statistics reaping occurs here
- if (@ext_stats != ()) {
- if (($#ext_stats == $#file_stats) && ($#ext_stats == $#arg_stats)) {
- $script = $mstrstatsdir . "/stats$SCRIPT_NO.sh";
- open (RUNSCRIPT, ">$script");
- chmod (0755, $script);
- print FSCRIPT "system \"$script\"\n";
- $SCRIPT_NO++;
- foreach my $ext (@ext_stats) {
- print RUNSCRIPT "$FILEBENCH/scripts/kill_stats $ext &\n";
- }
- close(RUNSCRIPT);
- }
- }
-
- # Dump the statistics to a Xanadu compatible XML file
- if ($USE_XANADU) {
- op_xmlstats($statsfile);
-
- $script = $mstrstatsdir . "/stats$SCRIPT_NO.pl";
- open (RUNSCRIPT, ">$script");
- chmod (0755, $script);
- print FSCRIPT "system \"$script\"\n";
- $SCRIPT_NO++;
-
- # The following loop adds the benchpoint run parameters and statistics into the filebench XML file
- # We capture the meta data from the start of the filebench xml file
- print RUNSCRIPT "#!/usr/bin/perl\n";
- print RUNSCRIPT "\$phase=1;\n";
- print RUNSCRIPT "open(STATSFILE,\"<".$mstrstatsdir."/$statsfile.xml\");\n";
- print RUNSCRIPT "open(OSTATSFILE,\">".$mstrstatsdir."/$statsfile.new.xml\");\n";
- print RUNSCRIPT "while (<STATSFILE>) {\n";
- print RUNSCRIPT "\t\$temp=\$_;\n";
- print RUNSCRIPT "\tif ((!((/.*meta.*/) || (/.*stat_doc.*/))) && (\$phase == 1)) {\n";
- print RUNSCRIPT "\t\topen(XMLFILE,\"<".$mstrstatsdir."/$statsfile.config.xml\");\n";
- print RUNSCRIPT "\t\twhile (<XMLFILE>) {\n";
- print RUNSCRIPT "\t\t\tprint OSTATSFILE \$_;\n";
- print RUNSCRIPT "\t\t}\n";
- print RUNSCRIPT "\t\tclose(XMLFILE);\n";
- print RUNSCRIPT "\t\t\$phase++;\n";
- print RUNSCRIPT "\t}\n";
- print RUNSCRIPT "\tprint OSTATSFILE \$temp;\n";
- print RUNSCRIPT "}\n";
- print RUNSCRIPT "close(STATSFILE);\n";
- print RUNSCRIPT "close(OSTATSFILE);\n";
- print RUNSCRIPT "unlink(\"".$mstrstatsdir."/$statsfile.xml\");\n";
- print RUNSCRIPT "unlink(\"".$mstrstatsdir."/$statsfile.config.xml\");\n";
- print RUNSCRIPT "system(\"mv ".$mstrstatsdir."/$statsfile.new.xml ".$mstrstatsdir."/$statsfile.xml\");\n";
-
- $script = $mstrstatsdir . "/stats$SCRIPT_NO.sh";
- open (RUNSCRIPT, ">$script");
- chmod (0755, $script);
- print FSCRIPT "system \"$script\"\n";
- $SCRIPT_NO++;
-
- print RUNSCRIPT "mkdir ".$mstrstatsdir."/xml\n";
- print RUNSCRIPT "mkdir ".$mstrstatsdir."/html\n";
-
- print RUNSCRIPT "mv ".$mstrstatsdir."/$statsfile.xml ".$mstrstatsdir."/xml/$statsfile.xml\n";
-
- # Process XML file using Xanadu 2
- print RUNSCRIPT "$FILEBENCH/xanadu/scripts/xanadu import ".$mstrstatsdir." ".$mstrstatsdir."/xml ".conf_reqval("function")."-".$mstrstatsdir."\n";
- print RUNSCRIPT "$FILEBENCH/xanadu/scripts/xanadu export ".$mstrstatsdir."/xml ".$mstrstatsdir."/html\n";
- close(RUNSCRIPT);
- }
- }
- return(0);
-}
-
-sub op_xmlstats {
- my ($statsfile) = shift;
- my $mstrstatsdir = $STATSBASE."/".$CONFNAME;
- if($statsfile ne '') {
- print FSCRIPT "stats xmldump \"$statsfile.xml\"\n";
-
- # The following loop adds the benchpoint run parameters and statistics into a temporary XML file
- open(OSTATSFILE,">".$mstrstatsdir."/$statsfile.config.xml");
- %CONFHASH = conf_hash();
- # There is no test for whether CONFHASH contains no keys
- # The following two lines is to obtain the stats run directory name for xanadu meta data
- print OSTATSFILE "<meta name=\"RunId\" value=\"".conf_reqval("function")."-".$mstrstatsdir."\"/>\n";
- print OSTATSFILE "<stat_group name=\"Benchpoint Configuration\">\n";
- print OSTATSFILE "<cell_list>\n";
- foreach $k (keys(%CONFHASH)) {
- print OSTATSFILE "<cell>@{ $CONFHASH{$k} }</cell>\n";
- }
- print OSTATSFILE "</cell_list>\n";
- print OSTATSFILE "<dim_list>\n";
- print OSTATSFILE "<dim>\n";
- print OSTATSFILE "<dimval>Value</dimval>\n";
- print OSTATSFILE "</dim>\n";
- print OSTATSFILE "<dim>\n";
- foreach $k (keys(%CONFHASH)) {
- print OSTATSFILE "<dimval>$k</dimval>\n";
- }
- print OSTATSFILE "</dim>\n";
- print OSTATSFILE "</dim_list>\n";
- print OSTATSFILE "</stat_group>\n";
- close(OSTATSFILE);
-
- return(0);
- }
- return(1);
-}
-
-sub op_command {
- my ($command) = shift;
- if($command ne '') {
- print FSCRIPT "$command\n";
- }
- return(0);
-}
-
-sub op_statshash {
- op_indiv_stats("iocount");
- $STATSHASH{"iocount"} = op_indiv_stats("iocount");
- $STATSHASH{"iorate"} = op_indiv_stats("iorate");
- $STATSHASH{"ioreadrate"} = op_indiv_stats("ioreadrate");
- $STATSHASH{"iowriterate"} = op_indiv_stats("iowriterate");
- $STATSHASH{"iobandwidth"} = op_indiv_stats("iobandwidth");
- $STATSHASH{"iolatency"} = op_indiv_stats("iolatency");
- $STATSHASH{"iocpu"} = op_indiv_stats("iocpu");
- $STATSHASH{"oheadcpu"} = op_indiv_stats("oheadcpu");
- $STATSHASH{"iowait"} = op_indiv_stats("iowait");
- $STATSHASH{"syscpu"} = op_indiv_stats("syscpu");
- $STATSHASH{"iocpusys"} = op_indiv_stats("iocpusys");
- return(%STATSHASH);
-}
-
-sub op_load_defaults {
-# The following code causes an intermittent bug - may be fixed at a later date
-# Prevents the capture of filebench default parameters
-# print FSCRIPT "vars\n";
-# my ($match, $err, $before, $after) = &expect(FSCRIPT,
-# $TIMEOUT, "filebench>");
-# chomp($before);
-# $before =~ /(.*): (.*): (.*)/;
-# $match = $3;
-# my @vars = split(/ /, $match);
-# my $value = "";
-# # Cater for the default filebench commands
-# foreach my $var (@vars) {
-# if (!conf_exists($var)) {
-# $var =~ s/ //g;
-# if ($var ne '') {
-# $value = op_indiv_vars($var);
-# push(@{ $CONFDATA{$var} }, $value);
-# }
-# }
-# }
-
- # Cater for the user defined defaults
- foreach $var (keys(%CONFDATA)) {
- if (conf_exists($var)) {
- $var =~ s/ //g;
- my $val = conf_getval($var);
-
- if (($SHAREDFILEALLOCATOR) and ($var eq "sharedprealloc")) {
- if (conf_reqval("myname") ne $SHAREDFILEALLOCATOR) {
- $val = "0";
- }
- }
-
- if ($val ne "") {
- op_set($var, $val);
- }
- }
- }
-}
-
-##############################################################################
-## Local functions
-##############################################################################
-
-sub parse_profile {
- my ($profile) = shift;
- my ($config_section, $default_section, $multi_section);
-
- open(CFILE, "$profile") or
- die "ERROR: couldn't open profile $profile";
-
- while(<CFILE>) {
- my ($line) = $_;
- chomp($line);
- $line =~ s/^\s+//; # Get rid of spaces
-
- if($line =~ /^#/ or $line eq "") {
- } else {
- if($line =~ /}/) {
- if($multi_section == 1) {
- $multi_section = 0;
- }
- if($default_section == 1) {
- $default_section = 0;
- }
- if($config_section == 1) {
- $config_section = 0;
- }
- } elsif($multi_section) {
- $line =~ /([^\s]+)\s*=\s*(.+);/;
- my $opt = $1;
- my $val = $2;
- chomp($opt);
- chomp($val);
- my @vals = ();
- # Check to see if this needs to be a list
- if($val =~ /,/) {
- push(@vals, $+) while $val =~
- m{"([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx;
- push(@vals, undef) if substr($val, -1,1) eq ',';
- @{ $MULTIDATA{$opt} } = @vals;
- } else {
- @{MULTIDATA{$opt}} = ();
- push(@{ $MULTIDATA{$opt} }, $val);
- }
- } elsif($default_section) {
- if ($line =~ /([^\s]+)\s*=\s*(.+);/) {
- my $opt = $1;
- my $val = $2;
- chomp($opt);
- chomp($val);
- my @vals = ();
- # Check to see if this needs to be a list
- if(($val =~ /,/) && ($val !~ /"/)) {
- push(@vals, $+) while $val =~
- m{"([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx;
- push(@vals, undef) if substr($val, -1,1) eq ',';
- @{ $DEFDATA{$opt} } = @vals;
- } elsif(exists($CMDLINEDATA{$opt})) {
- @{DEFDATA{$opt}} = ();
- push(@{ $DEFDATA{$opt} }, @{$CMDLINEDATA{$opt}});
- } else {
- @{DEFDATA{$opt}} = ();
- push(@{ $DEFDATA{$opt} }, $val);
- }
- } else {
- if ($line =~ /([^;]+);/) {
- my $opt = $1;
- if ($OPTIONFLAGS =~ /$opt/) {
- @{DEFDATA{$opt}} = ();
- push(@{ $DEFDATA{$opt} }, "");
- }
- }
- }
- } else {
- if($line =~ /^CONFIG /) {
- my $config = $line;
- $config =~ s/CONFIG\s+(.+) {/$1/;
- push(@CONFLIST, $config);
- $config_section = 1;
- } elsif($line =~ /MULTICLIENT\s{/) {
- $multi_section = 1;
- $MULTI_CLIENT = 1;
- } elsif($line =~ /DEFAULTS\s{/) {
- $default_section = 1;
- }
- }
- }
- }
-}
-
-
-#
-# Parse the configuration file
-#
-sub parse_config {
- my ($config) = shift;
-
- my $config_section = 0;
-
- print "parsing profile for config: $config\n";
-
- # Howdy
- seek(CFILE, 0, 0);
-
- while(<CFILE>) {
- # Read in the line and chomp...munch...chomp
- my ($line) = $_;
- chomp($line);
- $line =~ s/^\s+//; # Get rid of spaces
-
- # look for our stuff
- if ($line =~ /CONFIG $config /) {
- $config_section = 1;
- }
-
- if($line =~ /}/) {
- $config_section = 0;
- }
-
- # Skip until our config is found
- next if (!$config_section);
-
- next if ($line =~ /^#/ or $line eq "");
-
- if ($line =~ /([^\s]+)\s*=\s*(.+);/) {
- my $opt = $1;
- my $val = $2;
- chomp($opt);
- chomp($val);
- my @vals = ();
- # Check to see if this needs to be a list
- if(($val =~ /,/) && ($val !~ /"/)) {
- push(@vals, $+) while $val =~
- m{"([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx;
- push(@vals, undef) if substr($val, -1,1) eq ',';
- @{ $CONFDATA{$opt} } = @vals;
- } else {
- @{CONFDATA{$opt}} = ();
- push(@{ $CONFDATA{$opt} }, $val);
- }
- } else {
- $line =~ /($OPTIONFLAGS);/;
- my $opt = $1;
- chomp($opt);
- @{CONFDATA{$opt}} = ();
- push(@{ $CONFDATA{$opt} }, "");
- }
- }
-
- # Bye, bye
- #close(CFILE) or die "ERROR: config file closing difficulties";
- return \%confdata;
-}
-
-sub build_run
-{
- # The following function is taken from the user's function file
- pre_run();
-
- # Set the global statistics directory for this run
- op_statsdir();
-
- # The following function is taken from the user's function file
- bm_run();
-
- # Finish and close the .f script
- op_quit();
-}
-
-# statistics aggregation section
-my %FLOWOPVALS;
-my @SUMMARYVALS;
-
-sub init_combined_stats
-{
- %FLOWOPVALS = ();
- @SUMMARYVALS = (0,0,0,0,0,0);
-}
-
-sub add_2combstats
-{
- my ($confname) = shift;
- my ($thisclient) = shift;
- my $clstatdir;
- my $flowopmode = 0;
- my $summarymode = 0;
-
- print "adding in stats for client: $thisclient, configuration: $confname\n";
-
- $clstatdir = multi_getval("masterpath")."/".$thisclient;
-
- print "from: ".$clstatdir."/stats.".$confname.".out\n";
- open (CLSTATS, $clstatdir."/stats.".$confname.".out");
- while(<CLSTATS>) {
- my ($line) = $_;
- chomp($line);
- if (($flowopmode == 0) and ($summarymode == 0)) {
- if ($line =~ /^Flowop totals:/) {
- $flowopmode = 1;
- next;
- }
- if ($line =~ /^IO Summary:/) {
- $summarymode = 1;
- next;
- }
- }
- if ($line eq "") {
- $flowopmode = 0;
- $summarymode = 0;
- next;
- }
-
- # get the good stuff
- if ($flowopmode == 1) {
- my @elementlist;
- my @valuelist;
- my $flkey;
- my $vallistref = [];
-
- @elementlist = split(' ', $line);
- $flkey = $elementlist[0];
- @valuelist = @elementlist[1..$#elementlist];
-
- if (exists($FLOWOPVALS{$flkey})) {
- my $numvals;
-
- $vallistref = $FLOWOPVALS{$flkey};
- $numvals = @{$vallistref};
- for (my $idx = 0; $idx < $numvals; $idx++) {
- $vallistref->[$idx] += $valuelist[$idx];
- }
- } else {
- # newly found flowop name
- $vallistref = [@valuelist];
- $FLOWOPVALS{$flkey} = $vallistref;
- }
- next;
- }
-
- # get final totals
- if ($summarymode == 1) {
- my @valuelist;
-
- @valuelist = split(' ', $line);
-
- for (my $idx = 0; $idx <= $#valuelist; $idx++) {
- $SUMMARYVALS[$idx] += $valuelist[$idx];
- }
- next;
- }
- }
- close (CLSTATS);
-}
-
-sub print_usage
-{
- print "Usage:\n\tfilebench -c <stat_dir>\n";
- print "\tfilebench [-b <base_path>] ";
- print "[-D[ ]<variable name>[ |=| = ]<value>]... <profile name>\n";
-}
-
-sub dump_combined_stats
-{
- my ($confname) = shift;
- my $totvalsref = [];
- my $flkey;
- use FileHandle;
-
-## set up output formating info
-format flowoplinefrm =
-@<<<<<<<<<<<<<<<<<<< @#######ops/s @###.#mb/s @#####.#ms/op @#######us/op-cpu
-$flkey, $totvalsref->[0], $totvalsref->[1], $totvalsref->[2]/$#CLIENTLIST, $totvalsref->[3]/$#CLIENTLIST
-.
-
-format summarylinefrm =
-
-IO Summary: @#######ops, @#####.#ops/s, (@####/@#### r/w) @#####.#mb/s, @######us cpu/op, @####.#ms latency
-$SUMMARYVALS[0], $SUMMARYVALS[1], $SUMMARYVALS[2], $SUMMARYVALS[3], $SUMMARYVALS[4], $SUMMARYVALS[5], $SUMMARYVALS[6]
-.
-
- open (SUMSTATS, ">$STATSBASE/$confname/stats.$confname.out");
- print "Per-Operation Breakdown:\n";
- print SUMSTATS "Per-Operation Breakdown:\n";
-
- format_name STDOUT "flowoplinefrm";
- format_name SUMSTATS "flowoplinefrm";
-
- foreach $flkey (keys %FLOWOPVALS) {
-
- $totvalsref = $FLOWOPVALS{$flkey};
-
- write STDOUT;
- write SUMSTATS;
- }
-
- format_name STDOUT "summarylinefrm";
- format_name SUMSTATS "summarylinefrm";
-
- write STDOUT;
- write SUMSTATS;
- close (SUMSTATS);
-}
-
-#
-# polls the synchronization socket for each client in turn every 5 seconds,
-# then sends synch responses once all clients have "checked in". The
-# sample number in the received sync requests must match the sequence
-# number supplied with the call.
-#
-sub sync_receive
-{
- my $seqnum = shift;
-# my @cl_list;
- my %cl_hash = ();
- %cl_hash = %CLIENTHASH;
-
- my $count = @CLIENTLIST;
- print "waiting for sync message: $seqnum from $count clients\n";
- while ($count > 0) {
- my $rcv_str = "";
-
- sleep 5;
-
- foreach my $client_name (keys %cl_hash)
- {
- my $clientdata = $CLIENTHASH{$client_name};
- my $client_hndl = $$clientdata[0];
- print "recv sync: $client_name undefined handle\n" unless defined($client_hndl);
- my $client_iaddr = $$clientdata[1];
- my $sn = $$clientdata[2];
- my $rtn = 0;
-
- do {
- my $tmp_str;
- $rtn = recv($client_hndl, $tmp_str, 80, MSG_DONTWAIT);
- if (defined($rtn)) {
- $rcv_str = $rcv_str.$tmp_str;
- }
- } until (!defined($rtn) || ($rcv_str =~ /$EOL/s ));
-
- if (defined($rtn)) {
- my %ophash = ();
- my $ok;
-
- my @oplist = split /,/,$rcv_str;
- foreach my $opent (@oplist)
- {
- my ($op, $val) = split /=/,$opent;
- $ophash{$op} = $val;
- }
- $ok = ($sn == $seqnum);
- $ok &&= defined((my $cmd_val = $ophash{"cmd"}));
- $ok &&= defined((my $samp_val = $ophash{"sample"}));
- if ($ok && ($cmd_val eq "SYNC") && ($samp_val == $seqnum))
- {
- delete $cl_hash{$client_name};
- $count--;
- print "received a sync request from $client_name\n";
- ${$CLIENTHASH{$client_name}}[2] = ($sn + 1);
- } else {
- print "received invalid sync request string [".rcv_str."] from client $client_name\n";
- }
- }
- }
- }
- print "received all sync requests for seq $seqnum, sending responses\n";
- foreach my $client_name (@CLIENTLIST)
- {
- my $clientdata = $CLIENTHASH{$client_name};
- my $client_hndl = $$clientdata[0];
- print "send resp: $client_name undefined handle\n" unless defined($client_hndl);
-
- send ($client_hndl, "rsp=PASS,sample=$seqnum\n", 0);
- }
-}
-
-#
-# waits for all known clients to connect, then calls sync_recieve(1) to
-# sync_receive(N) to wait for N sync requests for designated sync points
-# 1..N.
-#
-sub sync_server
-{
- my $port = shift || 8001;
- my $proto = getprotobyname('tcp');
- my $paddr;
- my $count;
-
- socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
- setsockopt(Server, SOL_SOCKET, SO_REUSEADDR,
- pack("l", 1)) || die "setsockopt: $1";
- bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $1";
- listen(Server, SOMAXCONN) || die "listen: $1";
-
-# wait for connection requests from clients
- print "sync: Waiting for ".@CLIENTLIST." Clients\n";
- for ($count = @CLIENTLIST; $count > 0; $count--) {
- $paddr = accept(my $client_hndl, Server);
- die "bad socket address" unless $paddr;
-
- my ($port, $iaddr) = sockaddr_in($paddr);
- my $cl_name = gethostbyaddr($iaddr, AF_INET);
-
- if (!exists($CLIENTHASH{$cl_name})) {
- die "sync from unknown client $cl_name";
- }
-
- print "received sync connection from client: $cl_name\n";
- ${$CLIENTHASH{$cl_name}}[0] = $client_hndl;
- ${$CLIENTHASH{$cl_name}}[1] = $iaddr;
- }
-
-# indicate that all clients have checked in
- sync_receive(1);
- if (conf_exists("runtime") == 1) {
- my $runtime = conf_getval("runtime");
- sleep $runtime;
- }
- sync_receive(2);
-}
-
-##############################################################################
-## Main program
-##############################################################################
-
-## Make sure arguments are okay
-$numargs = $#ARGV + 1;
-
-if($numargs < 1) {
- print_usage();
- exit(2);
-}
-
-for (my $idx = 0; $idx < $numargs;) {
- my $cur_argv = $ARGV[$idx++];
- my $cmdvar = "";
- my $cmddata = "";
-
- # See if filebench_compare should be run
- if($cur_argv eq "-c") {
- if($numargs < ($idx + 1)) {
- print_usage();
- exit(2);
- }
- # next argument variable is path to results files
- exec("$FILEBENCH/scripts/filebench_compare", $ARGV[$idx++]);
- }
-
- # Capture specification of an alternate FileBench path
- if($cur_argv eq "-b") {
- if($numargs < ($idx + 1)) {
- print_usage();
- exit(2);
- }
- # next argument is the base path name
- $FILEBENCH = $ARGV[$idx++];
-
- # See if Default variable will be supplied.
- } elsif($cur_argv =~ /^-D(.*)/) {
- my $def_arg = $1;
-
- # rest of info in separate argvs
- if ($def_arg eq "") {
- if($numargs < ($idx + 2)) {
- print_usage();
- exit(2);
- }
-
- # get next bit
- $def_arg = $ARGV[$idx++];
- }
-
- # with variable name but without "=" or value
- if($def_arg =~ /^([^=]+)$/) {
- $cmdvar = $1;
- if($numargs < ($idx + 2)) {
- print_usage();
- exit(2);
- }
-
- # get data from next argument, or next after that if '=' encountered
- $cmddata = $ARGV[$idx++];
- if ($cmddata eq "=") {
- if($numargs < ($idx + 2)) {
- print_usage();
- exit(2);
- }
- $cmddata = $ARGV[$idx++];
- } else {
- $cmddata =~ s/^=//;
- }
-
- # see if variable name and data supplied
- } elsif($def_arg =~ /^([^=]+)=(.+)/) {
- $cmdvar = $1;
- $cmddata = $2;
- if($numargs < ($idx + 1)) {
- print_usage();
- exit(2);
- }
-
- # see if variable name and '=' but no data supplied
- } elsif($def_arg =~ /^([^=]+)=$/) {
- $cmdvar = $1;
- if($numargs < ($idx + 2)) {
- print_usage();
- exit(2);
- }
- $cmddata = $ARGV[$idx++];
- }
-
- # push the variable onto the command line hash
- $CMDLINEDATA{$cmdvar} = ();
- push(@{ $CMDLINEDATA{$cmdvar} }, $cmddata);
-
- # otherwise argument is the profile name
- } else {
- $PROFILENAME = $cur_argv;
- }
-}
-
-$PROFILE = $PROFILENAME;
-$PROFILE =~ s/.*\/(.+)$/$1/;
-parse_profile("$PROFILENAME.prof");
-
-%CONFDATA = ();
-%CONFDATA = %DEFDATA;
-
-# get the name of the host this script is running on
-my $hostname = `hostname`;
-chomp($hostname);
-
-# Check for Multi-Client operation
-if ($MULTI_CLIENT == 1) {
-
- if (multi_exists("targetpath")) {
- $TARGETPATH = multi_getval("targetpath");
- } else {
- print "ERROR: Target pathname required for multi-client operation\n";
- exit(1);
- }
-
- if (multi_exists("clients")) {
- @CLIENTLIST = split(' ',multi_getval("clients"));
- } else {
- print "ERROR: client list required for multi-client operation\n";
- exit(1);
- }
-
- if (multi_exists("sharefiles")) {
- $SHAREDFILEALLOCATOR = multi_getval("sharefiles");
- } else {
- $SHAREDFILEALLOCATOR = "";
- }
-
- $TARGETDIR = $TARGETPATH.conf_getval("dir");
-
- # Setup the multi client statistics base directory
- $STATSBASE = $TARGETPATH.conf_reqval("stats");
-
- multi_putval("masterhost", $hostname) unless multi_exists("masterhost");
- multi_putval("masterpath", $STATSBASE) unless multi_exists("masterpath");
-
- # create a path for filebench.pl to use to access the master directory
- $FB_MASTERPATH = multi_getval("masterpath");
-
- print "Target PathName = $TARGETPATH, path = ".multi_getval("masterpath")."\n";
-
-} else {
- # Setup the single client statistics base directory
- $STATSBASE = conf_reqval("stats");
-}
-
-my $filesystem = conf_reqval("filesystem");
-$STATSBASE = $STATSBASE . "/$hostname-$filesystem-$PROFILENAME-";
-my $timestamp = strftime "%b_%e_%Y-%Hh_%Mm_%Ss", localtime;
-$timestamp =~ s/ //;
-$STATSBASE = $STATSBASE . $timestamp;
-
-foreach $config_name (@CONFLIST)
-{
- %CONFDATA = ();
- %CONFDATA = %DEFDATA;
- $CONFNAME = $config_name;
- parse_config("$config_name");
- my $function = conf_reqval("function");
- my $statsdir;
-
- if (-f "$function.func") {
- require "$function.func";
- } else {
- require "$FILEBENCH/config/$function.func";
- }
-
- # Setup the final statistics directory
- system("mkdir -p $STATSBASE");
-
- # Leave a log of the run info
- open (RUNLOG, ">$STATSBASE/thisrun.prof");
- print RUNLOG "# " . conf_reqval("description") . "\n";
- close (RUNLOG);
-
- system ("cat $PROFILENAME.prof >>".$STATSBASE."/thisrun.prof");
-
- $statsdir = $STATSBASE . "/" . $config_name;
- system("mkdir -p $statsdir");
- system("chmod a+w $statsdir");
-
- if ($MULTI_CLIENT == 1) {
- my @pidlist;
- my %multi_confdata;
- my $procpid;
- my $syncclients = "";
-
- %multi_confdata = %CONFDATA;
-
- foreach my $thisclient (@CLIENTLIST) {
- my $tmpdir;
- my $tmpstatdir;
- my @clientdata;
-
- %CONFDATA = ();
- %CONFDATA = %multi_confdata;
- printf "building client: " . $thisclient . "\n";
-
- # Setup the statistics directory for each client
- $tmpstatdir = multi_getval("masterpath")."/".$thisclient;
-
- if ($SHAREDFILEALLOCATOR) {
- $tmpdir = $TARGETDIR;
- } else {
- $tmpdir = $TARGETDIR."/".$thisclient;
- }
-
-# add info to client hash
- @clientdata = ();
- $clientdata[2] = 1;
- $CLIENTHASH{$thisclient} = \@clientdata;
- $syncclients = $syncclients." --client ".$thisclient;
-
- push(@{ $CONFDATA{"myname"} }, $thisclient);
- push(@{ $CONFDATA{"statsdir"} }, $tmpstatdir);
- system("mkdir -p ".$FB_MASTERPATH."/".$thisclient);
- system("chmod 0777 ".$FB_MASTERPATH."/".$thisclient);
-
- # modify dir config variable for multiclient
- if (conf_exists("dir")) {
- @{$CONFDATA{"dir"}} = ($tmpdir);
- }
- build_run();
- }
-
- # Begin the RUN!!!
- print "Running " . $STATSBASE . "\n";
-
- #spawn the synchronization server
- print "Starting sync server on host ".$hostname."\n";
- if ($procpid = fork) {
- push(@pidlist, $procpid);
- } else {
- sync_server();
- exit(0);
- }
-
- sleep(3);
-
- # remotely execute the run on each client
- foreach $thisclient (@CLIENTLIST) {
- if($procpid = fork) {
- push(@pidlist, $procpid);
- } else {
- if ($thisclient eq $hostname) {
- print "Starting local client: $thisclient\n";
- system(multi_getval("masterpath")."/".$thisclient."/thisrun.f");
- } else {
- print "Starting remote client: $thisclient\n";
- system("ssh ".$thisclient." ".multi_getval("masterpath")."/".$thisclient."/thisrun.f >> ".multi_getval("masterpath")."/".$thisclient."/runs.out");
- }
- exit(0);
- }
- }
-
- # wait for all of them to finish
- foreach $procpid (@pidlist) {
- waitpid($procpid, 0);
- }
-
- init_combined_stats();
-
- foreach $thisclient (@CLIENTLIST) {
- add_2combstats($config_name, $thisclient);
- }
-
- # dump the combined client stats
- dump_combined_stats($config_name);
-
- } else {
- push(@{ $CONFDATA{"statsdir"} }, $statsdir);
-
- build_run();
-
- # Execute the run
- print "Running " . conf_reqval("statsdir") . "/thisrun.f\n";
- system ($statsdir."/thisrun.f");
-
-
- }
-
-}
-
-# The following function is taken from the user's function file
-post_run();
-
-print "\n";
diff --git a/usr/src/cmd/filebench/i386/Makefile b/usr/src/cmd/filebench/i386/Makefile
deleted file mode 100644
index 8b50a9fe5e..0000000000
--- a/usr/src/cmd/filebench/i386/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.com
-
-FBBINDIRi386 = $(ROOTFBBINDIR)/i386
-PROGi386 = $(PROG:%=$(FBBINDIRi386)/%)
-
-$(FBBINDIRi386):
- $(INS.dir)
-
-$(FBBINDIRi386)/%: %
- $(INS.file)
-
-install: all .WAIT $(FBBINDIRi386) .WAIT $(PROGi386)
diff --git a/usr/src/cmd/filebench/scripts/Makefile b/usr/src/cmd/filebench/scripts/Makefile
deleted file mode 100644
index f0400292d8..0000000000
--- a/usr/src/cmd/filebench/scripts/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-.KEEP_STATE:
-
-include ../../Makefile.cmd
-
-SCRIPTS = filebench_compare fs_flush
-ROOTUSRBENCHDIR = $(ROOT)/usr/benchmarks
-ROOTUSRBENCHFBSCRIPTSDIR = $(ROOTUSRBENCHDIR)/filebench/scripts
-FBSCRIPTS = $(SCRIPTS:%=$(ROOTUSRBENCHFBSCRIPTSDIR)/%)
-
-all clean lint:
-
-clobber:
- $(RM) $(SCRIPTS)
-
-$(ROOTUSRBENCHDIR) $(ROOTUSRBENCHFBSCRIPTSDIR):
- $(INS.dir)
-
-$(ROOTUSRBENCHFBSCRIPTSDIR)/%: %
- $(INS.file)
-
-install: $(ROOTUSRBENCHDIR) .WAIT $(ROOTUSRBENCHFBSCRIPTSDIR) .WAIT $(FBSCRIPTS)
diff --git a/usr/src/cmd/filebench/scripts/filebench_compare.pl b/usr/src/cmd/filebench/scripts/filebench_compare.pl
deleted file mode 100755
index 51a799b374..0000000000
--- a/usr/src/cmd/filebench/scripts/filebench_compare.pl
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/perl
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-
-#
-# Compare filebench results
-#
-# Usage: filebench_summary <dir1> <dir2> ...
-#
-
-use CGI ':standard';
-
-$maxiopsoverall = 0;
-$maxiopsrate = 0;
-$maxbandwidth = 0;
-
-#
-# Create html and text
-#
-open (HTML, ">index.html");
-print HTML start_html(-title=>'Filebench');
-print HTML "<body>";
-#
-# Print aggregate flowop stats
-#
-foreach $dir (@ARGV) {
-
- printf ("Generating html for $dir\n");
- open (PROFILE, "<$dir/thisrun.prof");
- $description = <PROFILE>;
- $description =~ s/.*"(.+)".*/$1/;
-
- $files = `ls $dir/stats.*.out $dir/*/stats.*.out 2>/dev/null`;
- foreach $file (split(/\n/, $files)) {
- print "file = $file\n";
-
- # Search backwards in-case the hostname is of FQDN or there's a
- # '.' in $dir.
- $rstr = reverse $file;
- ($rfstype, $rworkload, $rprefix) = split(/\./, $rstr);
- $prefix = reverse $rprefix;
- $workload = reverse $rworkload;
- $fstype = reverse $rfstype;
-
- $dataset = $dir;
- $dataset =~ s/.*\/(.+)$/$1/;
- $dataset =~ s/\/$//;
- $desc{$dataset} = "$description";
-
- open (STATS, $file);
- $tmp = <STATS>;
- while (<STATS>) {
- ($flowop, $ops, $bandwidth, $latency, $cpu, $wait, $seconds) = split(/[ \t]+/, $_);
-
- if (/^$/) {
- $tmp = <STATS>;
- ($fluff, $opcnt, $ops, $reads, $writes, $bandwidth,
- $cpu) = split(/[ \tA-z:\/,]+/, $tmp);
- $ops{$workload, $dataset} = $ops;
- last;
- }
-
- $ops =~ s/ops\/s//;
- $bandwidth =~ s/mb\/s//;
- $latency =~ s/ms\/op//;
- $cpu =~ s/us\/op//;
-
- # Collapse shadow reads into single metric
- if ($flowop =~ /shadowread/) {
- $flowop = "shadow-read";
- }
-
- # Collapse database writes into single metric
- if ($flowop =~ /db.*write/) {
- $flowop = "db-write";
- }
-
- # Collapse database writes into single metric
- if ($flowop =~ /db.*write/) {
- $flowop = "db-write";
- }
-
- $datasets{$dataset} = $dataset;
- $workloads{$workload} = $workload;
-
- $flowops{$flowop} = $flowop;
- $wkl_flowops{$flowop, $workload} = $flowop;
- $wkl_workload{$flowop, $workload} = $workload;
- $flow_ops{$flowop, $workload, $dataset} += $ops;
- $flow_bandwidth{$flowop, $workload, $dataset} += $bandwidth;
- $flow_latency{$flowop, $workload, $dataset} += $latency;
- $flow_cpu{$flowop, $workload, $dataset} += $cpu;
-
- $bandwidth{$workload, $dataset} += $bandwidth;
- $latency{$workload, $dataset} += $latency;
- $cpu{$workload, $dataset} += $cpu;
-
- $flowopcnt{$flowop, $workload, $dataset}++;
- $workloadcnt{$workload, $dataset}++;
- }
- close(STATS);
- }
-}
-
-# HTML IOPS
-print HTML h1('Throughput breakdown (ops per second)');
-print HTML "<table border=1>";
-print HTML "<b><td>Workload</td>";
-foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- print HTML "<td>$desc{$dataset}</td>";
-}
-print HTML "</b></tr>";
-
-foreach $workload (sort (keys %workloads)) {
- print HTML "<b><tr><td>$workload</td>";
- $last = 0;
- foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- $color = "white";
- $this = $ops{$workload, $dataset};
- if ($last && ($this - $last) < ($last * -0.1)) {
- $color = "red";
- }
- if ($last && ($this - $last) > ($last * 0.1)) {
- $color = "green";
- }
- printf HTML ("<td>%d</td\n", $this);
- $last = $ops{$workload, $dataset};
- }
- print HTML "</b></tr>";
-}
-print HTML "</table>";
-
-# HTML Bandwidth
-print HTML h1('Bandwidth breakdown (MB/s)');
-print HTML "<table border=1>";
-print HTML "<td>Workload</td>";
-foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- print HTML "<td>$desc{$dataset}</td>";
-}
-print HTML "</tr>";
-foreach $workload (sort (keys %workloads)) {
- $bandwidth = 0;
- foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- $bandwidth += $bandwidth{$workload, $dataset};
- }
- next if ($bandwidth == 0);
- print HTML "<tr><td>$workload</td>";
- foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- printf HTML ("<td>%d</td>\n", $bandwidth{$workload, $dataset});
- }
- print HTML "</tr>";
-}
-print HTML "</table>";
-
-# HTML Latency
-print HTML h1('Latency breakdown (ms per op)');
-print HTML "<table border=1>";
-print HTML "<td>Workload</td>";
-foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- print HTML "<td>$desc{$dataset}</td>";
-}
-
-print HTML "</tr>";
-foreach $workload (sort (keys %workloads)) {
- print HTML "<tr><td>$workload</td>";
- foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- if ( $workloadcnt{$workload, $dataset}) {
- printf HTML ("<td>%.1f</td>", $latency{$workload,
- $dataset} / $workloadcnt{$workload, $dataset});
- } else {
- printf HTML ("<td></td>");
- }
- }
- print HTML "</tr>";
- foreach $flowop (keys %wkl_flowops) {
- next if ("$wkl_workload{$flowop}" ne "$workload");
- print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>";
- foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- if ( $flowopcnt{$flowop, $dataset}) {
- printf HTML ("<td>%.1f</td>\n", $flow_latency{$flowop,
- $dataset} / $flowopcnt{$flowop, $dataset});
- } else {
- printf HTML ("<td></td>");
- }
- }
- print HTML "</i></tr>";
- }
-}
-print HTML "</table>";
-
-# HTML Efficiency
-print HTML h1('Efficiency breakdown (Code path length in uS/op)');
-print HTML "<table border=1>";
-print HTML "<td>Workload</td>";
-foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- print HTML "<td>$desc{$dataset}</td>";
-}
-print HTML "</tr>";
-foreach $workload (sort (keys %workloads)) {
- print HTML "<tr><td>$workload</td>";
- foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- if ($workloadcnt{$workload, $dataset}) {
- printf HTML ("<td>%d</td>", $cpu{$workload, $dataset}
- / $workloadcnt{$workload, $dataset});
- } else {
- printf HTML ("<td></td>");
- }
- }
- print HTML "</tr>";
- foreach $flowop (keys %wkl_flowops) {
- next if ("$wkl_workload{$flowop}" ne "$workload");
- print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>";
- foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
- if ($flowopcnt{$flowop, $dataset}) {
- printf HTML ("<td>%d</td>\n", $flow_cpu{$flowop,
- $dataset} / $flowopcnt{$flowop, $dataset});
- } else {
- printf HTML ("<td></td>");
- }
- }
- print HTML "</i></tr>";
- }
-}
-print HTML "</table>";
-
-end_html();
diff --git a/usr/src/cmd/filebench/scripts/fs_flush.pl b/usr/src/cmd/filebench/scripts/fs_flush.pl
deleted file mode 100755
index c7b46e15d4..0000000000
--- a/usr/src/cmd/filebench/scripts/fs_flush.pl
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/perl
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-#
-# Put commands in here to flush the file system cache after
-# file set creation but prior to steady state
-#
-# For most file systems, filebench already handles fs cache flushing
-# For ZFS, it needs some help, so this script does
-# "zpool export <poolname>" then "zpool import <poolname>"
-#
-
-$fs = $ARGV[0];
-$dir = $ARGV[1];
-
-#
-# if not zfs, inform user and exit.
-#
-if (($fs =~ m/^zfs$/) != 1) {
- print "filesystem type is: $fs, no action required, so exiting\n";
- exit(0);
-}
-
-#
-# It is zfs. Find name of pool to export/import from supplied
-# directory path name $dir
-#
-# Example:
-# # zfs list -H
-# tank 164K 24.0G 19K /tank
-# tank/a 18K 24.0G 18K /tank/a
-# tank/b 18K 24.0G 18K /wombat
-# #
-# # ./fs_flush zfs /wombat
-# 'zpool export tank'
-# 'zpool import tank'
-# #
-#
-
-# Get a list of zfs file systems mounted locally
-@zlist = `/usr/sbin/zfs list -H`;
-
-#
-# Compare the list with the supplied directory path name
-#
-chomp @zlist;
-foreach ( @zlist ) {
- #
- # For listed zfs file systems, extract the root and
- # mount point information
- #
- my $zline = $_;
- ($root, $b, $c, $d, $mntpnt) = split /\t/, $zline, 5;
-
- # See if the supplied directory path includes this mount point
- if(($mntpnt ne "\/") && ($dir =~/^$mntpnt/)) {
-
- #
- # We have a winner! The root name up to the
- # first forward slash is the pool name
- #
- ($pool) = split /\//, $root;
-
- # save zpool.cache
- my $tempfile = "/tmp/zpool.cache$$";
- my $cachefile = "";
-
- if (run_prog("cp /etc/zfs/zpool.cache $tempfile") == 0) {
- $cachefile = "-c $tempfile "
- }
-
- # Do the cache flushing
-
- print "'zpool export \/ import $pool'\n";
- if (run_prog("zpool export $pool") == 0) {
- system("zpool import $cachefile$pool");
- }
- system("rm -f $tempfile") if ($cachefile ne "");
- exit(0);
- }
-}
-exit(-1);
-
-sub run_prog
-{
- my $progname = shift;
-
- my $res = system($progname);
-
- #return error if failed for any reason
- return -1 if (($res == -1) || ($res & 127));
-
- return ($res >> 8);
-}
diff --git a/usr/src/cmd/filebench/sparcv9/Makefile b/usr/src/cmd/filebench/sparcv9/Makefile
deleted file mode 100644
index 539d2b0146..0000000000
--- a/usr/src/cmd/filebench/sparcv9/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.com
-include ../../Makefile.cmd.64
-
-FBBINDIRsparcv9 = $(ROOTFBBINDIR)/sparcv9
-PROGsparcv9 = $(PROG:%=$(FBBINDIRsparcv9)/%)
-
-$(FBBINDIRsparcv9):
- $(INS.dir)
-
-$(FBBINDIRsparcv9)/%: %
- $(INS.file)
-
-install: all .WAIT $(FBBINDIRsparcv9) .WAIT $(PROGsparcv9)
diff --git a/usr/src/cmd/filebench/workloads/Makefile b/usr/src/cmd/filebench/workloads/Makefile
deleted file mode 100644
index d064a6b350..0000000000
--- a/usr/src/cmd/filebench/workloads/Makefile
+++ /dev/null
@@ -1,95 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-.KEEP_STATE:
-
-include ../../Makefile.cmd
-
-WORKLOADS = \
- bringover.f \
- compflow_demo.f \
- copyfiles.f \
- createfiles.f \
- deletefiles.f \
- filemicro_create.f \
- filemicro_createfiles.f \
- filemicro_createrand.f \
- filemicro_delete.f \
- filemicro_rread.f \
- filemicro_rwrite.f \
- filemicro_rwritedsync.f \
- filemicro_rwritefsync.f \
- filemicro_seqwriterandvargam.f \
- filemicro_seqwriterandvartab.f \
- filemicro_seqread.f \
- filemicro_seqwrite.f \
- filemicro_seqwriterand.f \
- filemicro_statfile.f \
- filemicro_writefsync.f \
- fileserver.f \
- listdirs.f \
- makedirs.f \
- mongo.f \
- multistreamread.f \
- multistreamreaddirect.f \
- multistreamwrite.f \
- multistreamwritedirect.f \
- networkfs.f \
- oltp.f \
- openfiles.f \
- randomfileaccess.f \
- randomread.f \
- randomrw.f \
- randomwrite.f \
- ratelimcopyfiles.f \
- removedirs.f \
- singlestreamread.f \
- singlestreamreaddirect.f \
- singlestreamwrite.f \
- singlestreamwritedirect.f \
- tpcso.f \
- varmail.f \
- videoserver.f \
- webproxy.f \
- webserver.f
-
-ROOTUSRBENCHDIR = $(ROOT)/usr/benchmarks
-ROOTUSRBENCHFBWORKLOADSDIR = $(ROOTUSRBENCHDIR)/filebench/workloads
-FBWORKLOADS = $(WORKLOADS:%=$(ROOTUSRBENCHFBWORKLOADSDIR)/%)
-
-FILEMODE= 0444
-
-all clobber clean lint:
-
-$(ROOTUSRBENCHDIR):
- $(INS.dir)
-
-$(ROOTUSRBENCHFBWORKLOADSDIR):
- $(INS.dir)
-
-$(ROOTUSRBENCHFBWORKLOADSDIR)/%: %
- $(INS.file)
-
-install: $(ROOTUSRBENCHDIR) .WAIT $(ROOTUSRBENCHFBWORKLOADSDIR) .WAIT $(FBWORKLOADS)
diff --git a/usr/src/cmd/filebench/workloads/bringover.f b/usr/src/cmd/filebench/workloads/bringover.f
deleted file mode 100644
index b575ed9870..0000000000
--- a/usr/src/cmd/filebench/workloads/bringover.f
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-set $dir=/tmp
-set $nfiles=1000
-set $dirwidth=20
-set $filesize=16k
-set $iosize=1m
-set $nthreads=1
-
-set mode quit firstdone
-
-define fileset name=srcfiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc,paralloc
-define fileset name=destfiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=openfile1,filesetname=srcfiles,fd=1
- flowop readwholefile name=readfile1,fd=1,iosize=$iosize
- flowop createfile name=createfile2,filesetname=destfiles,fd=2
- flowop writewholefile name=writefile2,fd=2,srcfd=1,iosize=$iosize
- flowop closefile name=closefile1,fd=1
- flowop closefile name=closefile2,fd=2
- }
-}
-
-echo "Bringover Version 2.5 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$dirwidth=<value> defaults to $dirwidth"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/compflow_demo.f b/usr/src/cmd/filebench/workloads/compflow_demo.f
deleted file mode 100644
index ec556396ab..0000000000
--- a/usr/src/cmd/filebench/workloads/compflow_demo.f
+++ /dev/null
@@ -1,85 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-set $dir=/tmp
-set $nfiles=700
-set $meandirwidth=20
-set $filesize=128k
-set $nthreads=10
-set $meaniosize=16k
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80, paralloc
-
-define fileset name=u2fileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80, paralloc
-
-define fileset name=u3fileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80, paralloc
-
-define flowop name=readwrite, $fileset
-{
- flowop openfile name=openfile4,filesetname=$fileset,fd=1
- flowop openfile name=openfile5,filesetname=$fileset,fd=2
- flowop readwholefile name=readfile1,fd=1
- flowop writewholefile name=writefile1,fd=2,srcfd=1
- flowop closefile name=closefile4,fd=1
- flowop closefile name=closefile5,fd=2
-}
-
-define flowop name=dowork, $filesetnm, $rwiters
-{
- flowop createfile name=createfile1,filesetname=$filesetnm,fd=1
- flowop appendfilerand name=appendfilerand1,iosize=$meaniosize,fd=1
- flowop closefile name=closefile1,fd=1
- flowop readwrite name=rw1, iters=$rwiters, $fileset=$filesetnm
- flowop deletefile name=deletefile1,filesetname=$filesetnm
- flowop statfile name=statfile1,filesetname=$filesetnm
-}
-
-define process name=filereader1,instances=1
-{
- thread name=user1,memsize=10m,instances=$nthreads
- {
- flowop dowork name=dowork1, iters=1, $rwiters=5, $filesetnm=bigfileset
- }
-
- thread name=user2,memsize=10m,instances=$nthreads
- {
- flowop dowork name=dowork2, iters=1, $rwiters=4, $filesetnm=u2fileset
- }
-
- thread name=user3,memsize=10m,instances=$nthreads
- {
- flowop dowork name=dowork3, iters=1, $rwiters=3, $filesetnm=u3fileset
- }
-}
-
-echo "CompFlow_Demo Version 1.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meaniosize=<value> defaults to $meaniosize"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/copyfiles.f b/usr/src/cmd/filebench/workloads/copyfiles.f
deleted file mode 100644
index 732684a7ab..0000000000
--- a/usr/src/cmd/filebench/workloads/copyfiles.f
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-set $dir=/tmp
-set $nfiles=1000
-set $dirwidth=20
-set $filesize=16k
-set $iosize=1m
-set $nthreads=1
-
-set mode quit firstdone
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc=100,paralloc
-define fileset name=destfiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=openfile1,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile1,fd=1,iosize=$iosize
- flowop createfile name=createfile2,filesetname=destfiles,fd=2
- flowop writewholefile name=writefile2,fd=2,srcfd=1,iosize=$iosize
- flowop closefile name=closefile1,fd=1
- flowop closefile name=closefile2,fd=2
- }
-}
-
-echo "CopyFiles Version 2.5 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$dirwidth=<value> defaults to $dirwidth"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/createfiles.f b/usr/src/cmd/filebench/workloads/createfiles.f
deleted file mode 100644
index a61fc30fe5..0000000000
--- a/usr/src/cmd/filebench/workloads/createfiles.f
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-set $dir=/tmp
-set $nfiles=50000
-set $meandirwidth=100
-set $filesize=16k
-set $iosize=1m
-set $nthreads=16
-
-set mode quit firstdone
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth
-
-define process name=filecreate,instances=1
-{
- thread name=filecreatethread,memsize=10m,instances=$nthreads
- {
- flowop createfile name=createfile1,filesetname=bigfileset,fd=1
- flowop writewholefile name=writefile1,fd=1,iosize=$iosize
- flowop closefile name=closefile1,fd=1
- flowop opslimit name=limit
- }
-}
-
-echo "Createfiles Version 2.5 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/deletefiles.f b/usr/src/cmd/filebench/workloads/deletefiles.f
deleted file mode 100644
index 4870c4732c..0000000000
--- a/usr/src/cmd/filebench/workloads/deletefiles.f
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $nfiles=50000
-set $meandirwidth=100
-set $filesize=16k
-set $nthreads=16
-
-set mode quit firstdone
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100,paralloc
-
-define process name=filedelete,instances=1
-{
- thread name=filedeletethread,memsize=10m,instances=$nthreads
- {
- flowop deletefile name=deletefile1,filesetname=bigfileset,fd=1
- flowop opslimit name=limit
- }
-}
-
-echo "Deletefiles Version 2.3 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_create.f b/usr/src/cmd/filebench/workloads/filemicro_create.f
deleted file mode 100644
index a3eed09e7b..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_create.f
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Simple way to create a file. Start off with a zero length file, and issue
-# 1024 ($count) 1MB appends.
-
-set $dir=/tmp
-set $count=1024
-set $iosize=1m
-set $nthreads=1
-set $sync=false
-
-define file name=largefile,path=$dir,size=0,prealloc
-
-define process name=filecreater,instances=1
-{
- thread name=filecreaterthread,memsize=10m,instances=$nthreads
- {
- flowop appendfile name=append-file,filename=largefile,dsync=$sync,iosize=$iosize
- flowop finishoncount name=finish,value=$count
- }
-}
-
-echo "FileMicro-Create Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$count=<value> defaults to $count"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_createfiles.f b/usr/src/cmd/filebench/workloads/filemicro_createfiles.f
deleted file mode 100644
index 8f9104d7f9..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_createfiles.f
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Creates a fileset with 20,000 entries ($nfiles), but only preallocates
-# 50% of the files. Each file's size is set via a gamma distribution with
-# a median size of 1KB ($filesize).
-#
-# The single thread then creates a new file and writes the whole file with
-# 1MB I/Os. The thread stops after 5000 files ($count/num of flowops) have
-# been created and written to.
-
-set $dir=/tmp
-set $count=15000
-set $filesize=1k
-set $iosize=1m
-set $meandirwidth=100000
-set $nfiles=20000
-set $nthreads=1
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=50
-
-define process name=filecreate,instances=1
-{
- thread name=filecreatethread,memsize=10m,instances=$nthreads
- {
- flowop createfile name=createfile1,filesetname=bigfileset,fd=1
- flowop writewholefile name=writefile1,filesetname=bigfileset,fd=1,iosize=$iosize
- flowop closefile name=closefile1,fd=1
- flowop finishoncount name=finish,value=$count
- }
-}
-
-echo "FileMicro-Createfiles Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$count=<value> defaults to $count"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$meandirwidth=<value> defaults to $meandirwidth"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_createrand.f b/usr/src/cmd/filebench/workloads/filemicro_createrand.f
deleted file mode 100644
index 27ec833c1a..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_createrand.f
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded asynchronous ($sync) random appends (random I/Os
-# in the range of [1B - 1MB]) to a 1GB file.
-# Does a fsync after 10 ($iters) appends.
-# Stops after 1GB ($bytes) has been appended/written.
-
-set $dir=/tmp
-set $bytes=1g
-set $iosize=1m
-set $iters=10
-set $nthreads=1
-set $sync=false
-
-define file name=largefile,path=$dir,size=0,prealloc
-
-define process name=filecreater,instances=1
-{
- thread name=filecreaterthread,memsize=10m,instances=$nthreads
- {
- flowop appendfilerand name=append-file,filename=largefile,dsync=$sync,iosize=$iosize,iters=$iters
- flowop fsync name=sync
- flowop finishonbytes name=finish,value=$bytes
- }
-}
-
-echo "FileMicro-CreateRand Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$bytes=<value> defaults to $bytes"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$iters=<value> defaults to $iters"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_delete.f b/usr/src/cmd/filebench/workloads/filemicro_delete.f
deleted file mode 100644
index 206710fd11..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_delete.f
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Create a fileset of 50,000 entries ($nfiles), where each file's size is set
-# via a gamma distribution with the median size of 16KB ($filesize).
-# Fire off 16 threads ($nthreads), where each thread stops after
-# deleting 1000 ($count) files.
-
-set $dir=/tmp
-set $count=1000
-set $filesize=16k
-set $nfiles=5000
-set $meandirwidth=100
-set $nthreads=16
-
-set mode quit firstdone
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100,paralloc
-
-define process name=filedelete,instances=1
-{
- thread name=filedeletethread,memsize=10m,instances=$nthreads
- {
- flowop deletefile name=deletefile1,filesetname=bigfileset
- flowop opslimit name=limit
- flowop finishoncount name=finish,value=$count
- }
-}
-
-echo "FileMicro-Delete Version 2.4 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$count=<value> defaults to $count"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run"
-
diff --git a/usr/src/cmd/filebench/workloads/filemicro_rread.f b/usr/src/cmd/filebench/workloads/filemicro_rread.f
deleted file mode 100644
index d29e620532..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_rread.f
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded random reads (2KB I/Os) on a 1GB file.
-# Stops after 128MB ($bytes) has been read.
-
-set $dir=/tmp
-set $bytes=128m
-set $cached=false
-set $filesize=1g
-set $iosize=2k
-set $iters=1
-set $nthreads=1
-
-define file name=bigfile1,path=$dir,size=$filesize,prealloc,reuse,cached=$cached
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop read name=write-file,filesetname=bigfile1,random,iosize=$iosize,iters=$iters
- flowop finishonbytes name=finish,value=$bytes
- }
-}
-
-echo "FileMicro-ReadRand Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$bytes=<value> defaults to $bytes"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iters=<value> defaults to $iters"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_rwrite.f b/usr/src/cmd/filebench/workloads/filemicro_rwrite.f
deleted file mode 100644
index ee3b10cd1d..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_rwrite.f
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded asynchronous ($sync) random writes (2KB I/Os) on a 1GB file.
-# Stops when 128MB ($bytes) has been written.
-
-set $dir=/tmp
-set $bytes=128m
-set $cached=false
-set $filesize=1g
-set $iosize=2k
-set $iters=1
-set $nthreads=1
-set $sync=false
-
-define file name=bigfile1,path=$dir,size=$filesize,prealloc,reuse,cached=$cached
-
-define process name=filewriter,instances=1
-{
- thread name=filewriterthread,memsize=10m,instances=$nthreads
- {
- flowop write name=write-file,filename=bigfile1,random,dsync=$sync,iosize=$iosize,iters=$iters
- flowop finishonbytes name=finish,value=$bytes
- }
-}
-
-echo "FileMicro-WriteRand Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$bytes=<value> defaults to $bytes"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$iters=<value> defaults to $iters"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_rwritedsync.f b/usr/src/cmd/filebench/workloads/filemicro_rwritedsync.f
deleted file mode 100644
index b4e48bace8..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_rwritedsync.f
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded synchronous (O_DSYNC) random writes (2KB I/Os) on a 1GB file.
-# Stops when 64K ($count) writes have been done.
-
-set $dir=/tmp
-set $count=65536
-set $filesize=1g
-set $iosize=2k
-set $iters=1
-set $nthreads=1
-
-define file name=bigfile,path=$dir,size=$filesize,prealloc,reuse
-
-define process name=filewriter,instances=1
-{
- thread name=filewriterthread,memsize=10m,instances=$nthreads
- {
- flowop write name=write-file,filename=bigfile,random,dsync,iosize=$iosize,iters=$iters
- flowop finishoncount name=finish,value=$count
- }
-}
-
-echo "FileMicro-WriteRandDsync Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$count=<value> defaults to $count"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$iters=<value> defaults to $iters"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_rwritefsync.f b/usr/src/cmd/filebench/workloads/filemicro_rwritefsync.f
deleted file mode 100644
index 24d2766bdd..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_rwritefsync.f
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded asynchronous random writes (8KB I/Os) on a 1GB file.
-# A fsync is issued after 16K ($iters) worth of writes.
-# Stops after one ($count) fsync.
-
-set $dir=/tmp
-set $cached=false
-set $count=1
-set $filesize=1g
-set $iosize=8k
-set $iters=16384
-set $nthreads=1
-
-define file name=bigfile,path=$dir,size=$filesize,prealloc,cached=$cached
-
-define process name=filewriter,instances=1
-{
- thread name=filewriterthread,memsize=10m,instances=$nthreads
- {
- flowop write name=write-file,filename=bigfile,random,iosize=$iosize,iters=$iters
- flowop fsync name=sync-file
- flowop finishoncount name=finish,value=$count
- }
-}
-
-echo "FileMicro-WriteRandFsync Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$count=<value> defaults to $count"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$iters=<value> defaults to $iters"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_seqread.f b/usr/src/cmd/filebench/workloads/filemicro_seqread.f
deleted file mode 100644
index f3ba0a4731..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_seqread.f
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded sequential reads (1MB I/Os) on a 1G file.
-
-set $dir=/tmp
-set $cached=false
-set $filesize=1g
-set $iosize=1m
-set $nthreads=1
-
-define file name=largefile,path=$dir,size=$filesize,prealloc,reuse,cached=$cached
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread-file,filename=largefile,iosize=$iosize
- }
-}
-
-echo "FileMicro-SeqRead Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_seqwrite.f b/usr/src/cmd/filebench/workloads/filemicro_seqwrite.f
deleted file mode 100644
index 54418161d3..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_seqwrite.f
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded asynchronous ($sync) sequential writes (1MB I/Os) to
-# a 1GB file.
-# Stops after 1 series of 1024 ($count) writes has been done.
-
-set $dir=/tmp
-set $cached=false
-set $count=1024
-set $iosize=1m
-set $nthreads=1
-set $sync=false
-
-define file name=bigfile,path=$dir,size=0,prealloc,cached=$cached
-
-define process name=filewriter,instances=1
-{
- thread name=filewriterthread,memsize=10m,instances=$nthreads
- {
- flowop appendfile name=write-file,dsync=$sync,filename=bigfile,iosize=$iosize,iters=$count
- flowop finishoncount name=finish,value=1
- }
-}
-
-echo "FileMicro-SeqWrite Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$count=<value> defaults to $count"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_seqwriterand.f b/usr/src/cmd/filebench/workloads/filemicro_seqwriterand.f
deleted file mode 100644
index e38fcf2bf8..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_seqwriterand.f
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-# Single threaded appends/writes (I/Os of random size in the range
-# of [1B - 8KB]) to a 1GB file.
-# Stops after 128K ($count) writes have been done.
-
-set $dir=/tmp
-set $cached=false
-set $count=128k
-set $iosize=8k
-set $nthreads=1
-set $sync=false
-
-define file name=bigfile,path=$dir,size=0,prealloc,cached=$cached
-
-define process name=filewriter,instances=1
-{
- thread name=filewriterthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=open-file,filename=bigfile,fd=1
- flowop appendfilerand name=appendrand-file,dsync=$sync,iosize=$iosize,fd=1,iters=$count
- flowop closefile name=close,fd=1
- flowop finishoncount name=finish,value=1
- }
-}
-
-echo "FileMicro-SeqWriteRand Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$count=<bool> defaults to $count"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_seqwriterandvargam.f b/usr/src/cmd/filebench/workloads/filemicro_seqwriterandvargam.f
deleted file mode 100644
index e63bd1b636..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_seqwriterandvargam.f
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-# Sequential write() of a 1G file, size picked from a gamma distribution
-# min of 1k and a mean of 5.5K, followed by close(), cached.
-
-
-
-set $dir=/tmp
-set $nthreads=1
-set $cached=false
-set $sync=false
-set $count=128k
-
-define randvar name=$iosize, type=gamma, min=1k, mean=5632, gamma=1500
-
-define fileset name=bigfileset,path=$dir,size=0,entries=$nthreads,dirwidth=1024,prealloc=100,cached=$cached
-
-define process name=filewriter,instances=1
-{
- thread name=filewriterthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=open-file,filesetname=bigfileset,fd=1
- flowop appendfile name=write-file,dsync=$sync,iosize=$iosize,fd=1,iters=$count
- flowop closefile name=close,fd=1
- flowop finishoncount name=finish,value=1
- }
-}
-
-echo "FileMicro-SeqWriteRandVarGam Version 1.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$count=<value> defaults to $count"
-usage " set \$iosize.type=<type> defaults to $iosize.type"
-usage " set \$iosize.randsrc=<src> defaults to $iosize.randsrc"
-usage " set \$iosize.mean=<mean> defaults to $iosize.mean"
-usage " set \$iosize.gamma=<gamma> defaults to $iosize.gamma"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_seqwriterandvartab.f b/usr/src/cmd/filebench/workloads/filemicro_seqwriterandvartab.f
deleted file mode 100644
index ddbaa67cf9..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_seqwriterandvartab.f
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-# Sequential write() of a 1G file, size picked from a table in
-# the [1K,64K] range with a mean of 5.5K, followed by close(), cached.
-
-
-
-set $dir=/tmp
-set $nthreads=1
-set $cached=false
-set $sync=false
-set $count=128k
-
-define randvar name=$iosize, type=tabular, min=1k, randtable =
-{{ 80, 1k, 4k},
- { 15, 4k, 16k},
- { 05, 16k, 64k}}
-
-define fileset name=bigfileset,path=$dir,size=0,entries=$nthreads,dirwidth=1024,prealloc=100,cached=$cached
-
-define process name=filewriter,instances=1
-{
- thread name=filewriterthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=open-file,filesetname=bigfileset,fd=1
- flowop appendfile name=write-file,dsync=$sync,iosize=$iosize,fd=1,iters=$count
- flowop closefile name=close,fd=1
- flowop finishoncount name=finish,value=1
- }
-}
-
-echo "FileMicro-SeqWriteRandVarTab Version 1.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$count=<value> defaults to $count"
-usage " set \$iosize.type=<type> defaults to $iosize.type"
-usage " set \$iosize.randsrc=<src> defaults to $iosize.randsrc"
-usage " set \$iosize.mean=<mean> defaults to $iosize.mean"
-usage " set \$iosize.gamma=<gamma> defaults to $iosize.gamma"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_statfile.f b/usr/src/cmd/filebench/workloads/filemicro_statfile.f
deleted file mode 100644
index 2098d8ce4a..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_statfile.f
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# Creates a fileset of $nfiles number of files, then loops through them
-# using $nthreads number of threads, doing "stat" calls on each file.
-#
-
-set $dir=/tmp
-set $nfiles=10000
-set $meandirwidth=20
-set $filesize=128k
-set $nthreads=20
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100
-
-define process name=examinefiles,instances=1
-{
- thread name=examinefilethread, memsize=10m,instances=$nthreads
- {
- flowop statfile name=statfile1,filesetname=bigfileset
- }
-}
-
-echo "Stat File Version 1.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_writefsync.f b/usr/src/cmd/filebench/workloads/filemicro_writefsync.f
deleted file mode 100644
index 1b54c9c361..0000000000
--- a/usr/src/cmd/filebench/workloads/filemicro_writefsync.f
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-# Single threaded appends/writes (8KB I/Os) to a 1GB file.
-# Each loop iteration does a fsync after 1250 ($iters) appends.
-# Stops after 128K ($count) appends have been done.
-
-set $dir=/tmp
-set $count=128k
-set $iosize=8k
-set $iters=1250
-set $nthreads=1
-
-define file name=bigfile,path=$dir,size=0,prealloc
-
-define process name=filecreater,instances=1
-{
- thread name=filecreaterthread,memsize=10m,instances=$nthreads
- {
- flowop appendfile name=append-file,filename=bigfile,iosize=$iosize,iters=$iters
- flowop fsync name=sync-file
- flowop finishoncount name=finish,value=$count
- }
-}
-
-echo "FileMicro-WriteFsync Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$count=<value> defaults to $count"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$iters=<value> defaults to $iters"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/fileserver.f b/usr/src/cmd/filebench/workloads/fileserver.f
deleted file mode 100644
index 894cc379aa..0000000000
--- a/usr/src/cmd/filebench/workloads/fileserver.f
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-set $dir=/tmp
-set $nfiles=10000
-set $meandirwidth=20
-set $filesize=128k
-set $nthreads=50
-set $meaniosize=16k
-set $fixediosize=1m
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop createfile name=createfile1,filesetname=bigfileset,fd=1
- flowop writewholefile name=wrtfile1,srcfd=1,fd=1,iosize=$fixediosize
- flowop closefile name=closefile1,fd=1
- flowop openfile name=openfile1,filesetname=bigfileset,fd=1
- flowop appendfilerand name=appendfilerand1,iosize=$meaniosize,fd=1
- flowop closefile name=closefile2,fd=1
- flowop openfile name=openfile2,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile1,fd=1,iosize=$fixediosize
- flowop closefile name=closefile3,fd=1
- flowop deletefile name=deletefile1,filesetname=bigfileset
- flowop statfile name=statfile1,filesetname=bigfileset
- }
-}
-
-echo "FileServer Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meaniosize=<value> defaults to $meaniosize"
-usage " set \$fixediosize=<size> defaults to $fixediosize"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/listdirs.f b/usr/src/cmd/filebench/workloads/listdirs.f
deleted file mode 100644
index e3fadc66c3..0000000000
--- a/usr/src/cmd/filebench/workloads/listdirs.f
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Creates a fileset with a fairly deep directory tree, then does readdir
-# operations on them for a specified amount of time
-#
-set $dir=/tmp
-set $nfiles=50000
-set $meandirwidth=5
-set $nthreads=16
-
-define fileset name=bigfileset,path=$dir,size=0,entries=$nfiles,dirwidth=$meandirwidth,prealloc
-
-define process name=lsdir,instances=1
-{
- thread name=dirlister,memsize=1m,instances=$nthreads
- {
- flowop listdir name=open1,filesetname=bigfileset
- }
-}
-
-echo "ListDirs Version 1.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run 60"
diff --git a/usr/src/cmd/filebench/workloads/makedirs.f b/usr/src/cmd/filebench/workloads/makedirs.f
deleted file mode 100644
index 34f2991468..0000000000
--- a/usr/src/cmd/filebench/workloads/makedirs.f
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Creates a directory with $ndirs potential leaf directories, than mkdir's them
-#
-set $dir=/tmp
-set $ndirs=10000
-set $meandirwidth=100
-set $nthreads=16
-
-set mode quit firstdone
-
-define fileset name=bigfileset,path=$dir,size=0,leafdirs=$ndirs,dirwidth=$meandirwidth
-
-define process name=dirmake,instances=1
-{
- thread name=dirmaker,memsize=1m,instances=$nthreads
- {
- flowop makedir name=mkdir1,filesetname=bigfileset
- }
-}
-
-echo "MakeDirs Version 1.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage " set \$ndirs=<value> defaults to $ndirs"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage "(sets mean dir width and dir depth is calculated as log (width, ndirs)"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/mongo.f b/usr/src/cmd/filebench/workloads/mongo.f
deleted file mode 100644
index f6d7ec6f2d..0000000000
--- a/usr/src/cmd/filebench/workloads/mongo.f
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $nfiles=1000
-set $dirwidth=20
-set $filesize=16k
-set $nthreads=1
-set $meaniosize=16k
-set $readiosize=1m
-
-set mode quit firstdone
-
-define fileset name=postset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc,paralloc
-define fileset name=postsetdel,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc,paralloc
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=openfile1,filesetname=postset,fd=1
- flowop appendfilerand name=appendfilerand1,iosize=$meaniosize,fd=1
- flowop closefile name=closefile1,fd=1
- flowop openfile name=openfile2,filesetname=postset,fd=1
- flowop readwholefile name=readfile1,fd=1,iosize=$readiosize
- flowop closefile name=closefile2,fd=1
- flowop deletefile name=deletefile1,filesetname=postsetdel
- }
-}
-
-echo "Mongo-like Version 2.3 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$dirwidth=<value> defaults to $dirwidth"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meaniosize=<value> defaults to $meaniosize"
-usage " set \$readiosize=<size> defaults to $readiosize"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/multistreamread.f b/usr/src/cmd/filebench/workloads/multistreamread.f
deleted file mode 100644
index 66dd7d54d9..0000000000
--- a/usr/src/cmd/filebench/workloads/multistreamread.f
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $filesize=1g
-set $nthreads=1
-set $iosize=1m
-set $directio=0
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile2,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile3,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile4,path=$dir,size=$filesize,prealloc,reuse
-
-define process name=seqread,instances=1
-{
- thread name=seqread1,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread1,filename=largefile1,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
- thread name=seqread2,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread2,filename=largefile2,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
- thread name=seqread3,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread3,filename=largefile3,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
- thread name=seqread4,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread4,filename=largefile4,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Multi Stream Read Version 2.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$directio=<bool> defaults to $directio"
-usage " "
-usage " run runtime (e.g. run 60)"
-
diff --git a/usr/src/cmd/filebench/workloads/multistreamreaddirect.f b/usr/src/cmd/filebench/workloads/multistreamreaddirect.f
deleted file mode 100644
index 36c5c31546..0000000000
--- a/usr/src/cmd/filebench/workloads/multistreamreaddirect.f
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $nthreads=1
-set $filesize=1g
-set $iosize=1m
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile2,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile3,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile4,path=$dir,size=$filesize,prealloc,reuse
-
-define process name=seqread,instances=1
-{
- thread name=seqread1,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread1,filename=largefile1,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
- thread name=seqread2,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread2,filename=largefile2,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
- thread name=seqread3,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread3,filename=largefile3,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
- thread name=seqread4,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread4,filename=largefile4,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Multi Stream Read Direct Version 2.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " "
-usage " run runtime (e.g. run 60)"
-
diff --git a/usr/src/cmd/filebench/workloads/multistreamwrite.f b/usr/src/cmd/filebench/workloads/multistreamwrite.f
deleted file mode 100644
index af536ce9ff..0000000000
--- a/usr/src/cmd/filebench/workloads/multistreamwrite.f
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $filesize=1g
-set $nthreads=1
-set $iosize=1m
-set $directio=0
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile2,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile3,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile4,path=$dir,size=$filesize,prealloc,reuse
-
-define process name=seqwrite,instances=1
-{
- thread name=seqwrite1,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite1,filename=largefile1,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
- thread name=seqwrite2,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite2,filename=largefile2,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
- thread name=seqwrite3,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite3,filename=largefile3,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
- thread name=seqwrite4,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite4,filename=largefile4,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Multi Stream Write Version 2.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$directio=<bool> defaults to $directio"
-usage " "
-usage " run runtime (e.g. run 60)"
-
diff --git a/usr/src/cmd/filebench/workloads/multistreamwritedirect.f b/usr/src/cmd/filebench/workloads/multistreamwritedirect.f
deleted file mode 100644
index 8ba21ab7f5..0000000000
--- a/usr/src/cmd/filebench/workloads/multistreamwritedirect.f
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $filesize=1g
-set $nthreads=1
-set $iosize=1m
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile2,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile3,path=$dir,size=$filesize,prealloc,reuse
-define file name=largefile4,path=$dir,size=$filesize,prealloc,reuse
-
-define process name=seqwrite,instances=1
-{
- thread name=seqwrite1,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite1,filename=largefile1,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
- thread name=seqwrite2,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite2,filename=largefile2,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
- thread name=seqwrite3,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite3,filename=largefile3,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
- thread name=seqwrite4,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite4,filename=largefile4,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Multi Stream Write Direct Version 2.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/networkfs.f b/usr/src/cmd/filebench/workloads/networkfs.f
deleted file mode 100644
index 9200411703..0000000000
--- a/usr/src/cmd/filebench/workloads/networkfs.f
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# $dir - directory for datafiles
-# $eventrate - event generator rate (0 == free run)
-# $nfiles - number of data files
-# $nthreads - number of worker threads
-
-set $dir=/tmp
-set $cached=false
-set $eventrate=10
-set $meandirwidth=20
-set $nthreads=1
-set $nfiles=10000
-set $sync=false
-set $totalfiles=$nfiles * $eventrate
-
-eventgen rate=$eventrate
-
-define randvar name=$wrtiosize, type=tabular, min=1k, round=1k, randtable =
-{{ 0, 1k, 7k},
- {50, 9k, 15k},
- {14, 17k, 23k},
- {14, 33k, 39k},
- {12, 65k, 71k},
- {10, 129k, 135k}
-}
-
-define randvar name=$rdiosize, type=tabular, min=8k, round=1k, randtable =
-{{85, 8k, 8k},
- { 8, 17k, 23k},
- { 4, 33k, 39k},
- { 2, 65k, 71k},
- { 1, 129k, 135k}
-}
-
-define randvar name=$filesize, type=tabular, min=1k, round=1k, randtable =
-{{33, 1k, 1k},
- {21, 1k, 3k},
- {13, 3k, 5k},
- {10, 5k, 11k},
- {08, 11k, 21k},
- {05, 21k, 43k},
- {04, 43k, 85k},
- {03, 85k, 171k},
- {02, 171k, 341k},
- {01, 341k, 1707k}
-}
-
-define randvar name=$fileidx, type=gamma, min=0, gamma=100
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$totalfiles,dirwidth=$meandirwidth,prealloc=60,cached=$cached
-
-define flowop name=rmw, $filesetrmw
-{
- flowop openfile name=openfile1,filesetname=$filesetrmw,indexed=$fileidx,fd=1
- flowop readwholefile name=readfile1,iosize=$rdiosize,fd=1
- flowop createfile name=newfile2,filesetname=$filesetrmw,indexed=$fileidx,fd=2
- flowop writewholefile name=writefile2,fd=2,iosize=$wrtiosize,srcfd=1
- flowop closefile name=closefile1,fd=1
- flowop closefile name=closefile2,fd=2
- flowop deletefile name=deletefile1,fd=1
-}
-
-define flowop name=launch, $filesetlch
-{
- flowop openfile name=openfile3,filesetname=$filesetlch,indexed=$fileidx,fd=3
- flowop readwholefile name=readfile3,iosize=$rdiosize,fd=3
- flowop openfile name=openfile4,filesetname=$filesetlch,indexed=$fileidx,fd=4
- flowop readwholefile name=readfile4,iosize=$rdiosize,fd=4
- flowop closefile name=closefile3,fd=3
- flowop openfile name=openfile5,filesetname=$filesetlch,indexed=$fileidx,fd=5
- flowop readwholefile name=readfile5,iosize=$rdiosize,fd=5
- flowop closefile name=closefile4,fd=4
- flowop closefile name=closefile5,fd=5
-}
-
-define flowop name=appnd, $filesetapd
-{
- flowop openfile name=openfile6,filesetname=$filesetapd,indexed=$fileidx,fd=6
- flowop appendfilerand name=appendfilerand6,iosize=$wrtiosize,fd=6
- flowop closefile name=closefile6,fd=6
-}
-
-define process name=netclient,instances=1
-{
- thread name=fileuser,memsize=10m,instances=$nthreads
- {
- flowop launch name=launch1, iters=1, $filesetlch=bigfileset
- flowop rmw name=rmw1, iters=6, $filesetrmw=bigfileset
- flowop appnd name=appnd1, iters=3, $filesetapd=bigfileset
- flowop statfile name=statfile1,filesetname=bigfileset,indexed=$fileidx
- flowop eventlimit name=ratecontrol
- }
-}
-
-echo "NetworkFileServer Version 1.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " set \$wrtiosize.type=<type> defaults to $wrtiosize.type"
-usage " set \$wrtiosize.randsrc=<src> defaults to $wrtiosize.randsrc"
-usage " set \$rdiosize.type=<type> defaults to $rdiosize.type"
-usage " set \$rdiosize.randsrc=<src> defaults to $rdiosize.randsrc"
-usage " set \$filesize.type=<type> defaults to $filesize.type"
-usage " set \$filesize.randsrc=<src> defaults to $filesize.randsrc"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/oltp.f b/usr/src/cmd/filebench/workloads/oltp.f
deleted file mode 100644
index f036797ef8..0000000000
--- a/usr/src/cmd/filebench/workloads/oltp.f
+++ /dev/null
@@ -1,117 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# $dir - directory for datafiles
-# $eventrate - event generator rate (0 == free run)
-# $iosize - iosize for database block access
-# $nshadows - number of shadow processes
-# $ndbwriters - number of database writers
-# $nfiles - number of data files
-# $nlogfiles - number of log files
-
-set $dir=/tmp
-set $eventrate=0
-set $runtime=30
-set $iosize=2k
-set $nshadows=200
-set $ndbwriters=10
-set $usermode=200000
-set $filesize=10m
-set $memperthread=1m
-set $workingset=0
-set $cached=0
-set $logfilesize=10m
-set $nfiles=10
-set $nlogfiles=1
-set $directio=0
-
-eventgen rate = $eventrate
-
-# Define a datafile and logfile
-define fileset name=datafiles,path=$dir,size=$filesize,filesizegamma=0,entries=$nfiles,dirwidth=1024,prealloc=100,cached=$cached,reuse
-define fileset name=logfile,path=$dir,size=$logfilesize,filesizegamma=0,entries=$nlogfiles,dirwidth=1024,prealloc=100,cached=$cached,reuse
-
-define process name=lgwr,instances=1
-{
- thread name=lgwr,memsize=$memperthread,useism
- {
- flowop aiowrite name=lg-write,filesetname=logfile,
- iosize=256k,random,directio=$directio,dsync
- flowop aiowait name=lg-aiowait
- flowop semblock name=lg-block,value=3200,highwater=1000
- }
-}
-
-# Define database writer processes
-define process name=dbwr,instances=$ndbwriters
-{
- thread name=dbwr,memsize=$memperthread,useism
- {
- flowop aiowrite name=dbwrite-a,filesetname=datafiles,
- iosize=$iosize,workingset=$workingset,random,iters=100,opennext,directio=$directio,dsync
- flowop hog name=dbwr-hog,value=10000
- flowop semblock name=dbwr-block,value=1000,highwater=2000
- flowop aiowait name=dbwr-aiowait
- }
-}
-
-
-define process name=shadow,instances=$nshadows
-{
- thread name=shadow,memsize=$memperthread,useism
- {
- flowop read name=shadowread,filesetname=datafiles,
- iosize=$iosize,workingset=$workingset,random,opennext,directio=$directio
- flowop hog name=shadowhog,value=$usermode
- flowop sempost name=shadow-post-lg,value=1,target=lg-block,blocking
- flowop sempost name=shadow-post-dbwr,value=1,target=dbwr-block,blocking
- flowop eventlimit name=random-rate
- }
-}
-
-echo "OLTP Version 2.3 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " "
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " "
-usage " set \$filesize=<size> defaults to $filesize, n.b. there are ten files of this size"
-usage " "
-usage " set \$logfilesize=<size> defaults to $logfilesize, n.b. there is one file of this size"
-usage " "
-usage " set \$iosize=<value> defaults to $iosize, typically 2k or 8k"
-usage " "
-usage " set \$cached=<bool> defaults to $cached"
-usage " "
-usage " set \$memperthread=<value> defaults to $memperthread"
-usage " "
-usage " set \$directio=<value> defaults to $directio"
-usage " "
-usage " run runtime (e.g. run 60)"
-usage " "
-usage "Note - total filesize should be at least 2x physical memory size for conforming test)"
-usage " i.e. if physmem = 4G, set filesize to 4G * 2 / 10, or 800m"
-usage " "
-usage "Note - this workload needs at least 512MB of of memory"
-usage " "
-
diff --git a/usr/src/cmd/filebench/workloads/openfiles.f b/usr/src/cmd/filebench/workloads/openfiles.f
deleted file mode 100644
index b6eb1be835..0000000000
--- a/usr/src/cmd/filebench/workloads/openfiles.f
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Creates a fileset with $nfiles empty files, then proceeds to open each one
-# and then close it.
-#
-set $dir=/tmp
-set $nfiles=50000
-set $meandirwidth=100
-set $nthreads=16
-
-define fileset name=bigfileset,path=$dir,size=0,entries=$nfiles,dirwidth=$meandirwidth,prealloc
-
-define process name=fileopen,instances=1
-{
- thread name=fileopener,memsize=1m,instances=$nthreads
- {
- flowop openfile name=open1,filesetname=bigfileset,fd=1
- flowop closefile name=close1,fd=1
- }
-}
-
-echo "Openfiles Version 1.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " "
-usage " run 60"
diff --git a/usr/src/cmd/filebench/workloads/randomfileaccess.f b/usr/src/cmd/filebench/workloads/randomfileaccess.f
deleted file mode 100644
index f1b25df232..0000000000
--- a/usr/src/cmd/filebench/workloads/randomfileaccess.f
+++ /dev/null
@@ -1,89 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Exercises the indexed attribute of the fileset_pick() function.
-#
-
-set $dir=/tmp
-set $cached=false
-set $meandirwidth=20
-set $nthreads=5
-set $nfiles=10000
-set $sync=false
-
-define randvar name=$wrtiosize, min=512, round=512, type=gamma, mean=16k
-
-define randvar name=$rdiosize, type=tabular, min=8k, round=1k, randtable =
-{{85, 8k, 8k},
- {15, 8k, 64k}
-}
-
-define randvar name=$filesize, type=tabular, min=1k, randtable =
-{{33, 1k, 1k},
- {21, 1k, 3k},
- {13, 3k, 5k},
- {10, 5k, 11k},
- {08, 11k, 21k},
- {05, 21k, 43k},
- {04, 43k, 85k},
- {03, 85k, 171k},
- {02, 171k, 341k},
- {01, 341k, 1707k}
-}
-
-define randvar name=$fileidx, type=gamma, min=0, gamma=100
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100,cached=$cached
-
-define process name=netclient,instances=1
-{
- thread name=fileuser,memsize=10m,instances=$nthreads
- {
- flowop openfile name=openfile1,filesetname=bigfileset,indexed=$fileidx,fd=1
- flowop openfile name=openfile2,filesetname=bigfileset,indexed=$fileidx,fd=2
- flowop openfile name=openfile3,filesetname=bigfileset,indexed=$fileidx,fd=3
- flowop appendfilerand name=appendfilerand1,iosize=$wrtiosize,fd=1
- flowop closefile name=closefile1,fd=1
- flowop readwholefile name=readfile1,iosize=$rdiosize,fd=2
- flowop readwholefile name=readfile2,iosize=$rdiosize,fd=3
- flowop closefile name=closefile2,fd=2
- flowop closefile name=closefile3,fd=3
- }
-}
-
-echo "NetworkServer Version 1.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$cached=<bool> defaults to $cached"
-usage " set \$wrtiosize.type=<type> defaults to $wrtiosize.type"
-usage " set \$wrtiosize.randsrc=<src> defaults to $wrtiosize.randsrc"
-usage " set \$wrtiosize.mean=<mean> defaults to $wrtiosize.mean"
-usage " set \$wrtiosize.gamma=<gamma> defaults to $wrtiosize.gamma"
-usage " set \$rdiosize.type=<type> defaults to $rdiosize.type"
-usage " set \$rdiosize.randsrc=<src> defaults to $rdiosize.randsrc"
-usage " set \$filesize.type=<type> defaults to $filesize.type"
-usage " set \$filesize.randsrc=<src> defaults to $filesize.randsrc"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$sync=<bool> defaults to $sync"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/randomread.f b/usr/src/cmd/filebench/workloads/randomread.f
deleted file mode 100644
index ffde5102f5..0000000000
--- a/usr/src/cmd/filebench/workloads/randomread.f
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# $dir - directory for datafiles
-# $eventrate - event generator rate (0 == free run)
-# $filesize - size of data file
-# $iosize - size of each read
-# $nthreads - number of worker threads
-
-set $dir=/tmp
-set $eventrate=0
-set $filesize=1m
-set $iosize=8k
-set $nthreads=1
-set $workingset=0
-set $directio=0
-
-eventgen rate=$eventrate
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse,paralloc
-
-define process name=rand-read,instances=1
-{
- thread name=rand-thread,memsize=5m,instances=$nthreads
- {
- flowop read name=rand-read1,filename=largefile1,iosize=$iosize,random,workingset=$workingset,directio=$directio
- flowop eventlimit name=rand-rate
- }
-}
-
-echo "Random Read Version 2.1 IO personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$workingset=<value> defaults to $workingset"
-usage " set \$directio=<bool> defaults to $directio"
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/randomrw.f b/usr/src/cmd/filebench/workloads/randomrw.f
deleted file mode 100644
index c28c1c37d2..0000000000
--- a/usr/src/cmd/filebench/workloads/randomrw.f
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# $dir - directory for datafiles
-# $eventrate - event generator rate (0 == free run)
-# $filesize - size of data file
-# $iosize - size of each I/O request
-# $nthreads - number of worker threads
-
-set $dir=/tmp
-set $eventrate=0
-set $filesize=1m
-set $iosize=8k
-set $nthreads=1
-set $workingset=0
-set $directio=0
-
-eventgen rate=$eventrate
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse,paralloc
-
-define process name=rand-rw,instances=1
-{
- thread name=rand-r-thread,memsize=5m,instances=$nthreads
- {
- flowop read name=rand-read1,filename=largefile1,iosize=$iosize,random,workingset=$workingset,directio=$directio
- flowop eventlimit name=rand-rdrate
- }
- thread name=rand-w-thread,memsize=5m,instances=$nthreads
- {
- flowop write name=rand-write1,filename=largefile1,iosize=$iosize,random,workingset=$workingset,directio=$directio
- flowop eventlimit name=rand-wtrate
- }
-}
-
-echo "Random RW Version 2.1 IO personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$workingset=<value> defaults to $workingset"
-usage " set \$directio=<bool> defaults to $directio"
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/randomwrite.f b/usr/src/cmd/filebench/workloads/randomwrite.f
deleted file mode 100644
index 97daad4e42..0000000000
--- a/usr/src/cmd/filebench/workloads/randomwrite.f
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# $dir - directory for datafiles
-# $eventrate - event generator rate (0 == free run)
-# $filesize - size of data file
-# $iosize - size of each I/O request
-# $nthreads - number of worker threads
-
-set $dir=/tmp
-set $eventrate=0
-set $filesize=1m
-set $iosize=8k
-set $nthreads=1
-set $workingset=0
-set $directio=0
-
-eventgen rate=$eventrate
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse,paralloc
-
-define process name=rand-write,instances=1
-{
- thread name=rand-thread,memsize=5m,instances=$nthreads
- {
- flowop write name=rand-write1,filename=largefile1,iosize=$iosize,random,workingset=$workingset,directio=$directio
- flowop eventlimit name=rand-rate
- }
-}
-
-echo "Random Write Version 2.1 IO personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$workingset=<value> defaults to $workingset"
-usage " set \$directio=<bool> defaults to $directio"
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/ratelimcopyfiles.f b/usr/src/cmd/filebench/workloads/ratelimcopyfiles.f
deleted file mode 100644
index 0a2347686b..0000000000
--- a/usr/src/cmd/filebench/workloads/ratelimcopyfiles.f
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-# RateLimCopyFiles.f uses the iopslimit flowop with the target attribute
-# set to the writewholefile flowop to limit the rate to one writewholefile
-# operation per event. Without the target attribute set, the limit will
-# be one writewholefile OR readwholefile operation per event, so in effect
-# it will run at half the rate. Without the target attribute, this workload
-# is identical to copyfiles.f. Set the event generator rate by setting
-# the $eventrate variable, for instance by typing:
-# set $eventrate=20
-# at the go_filebench prompt to get twenty events per second.
-#
-
-# $dir - directory for datafiles
-# $eventrate - event generator rate (0 == free run)
-# $filesize - size of data file
-# $iosize - size of each I/O request
-# $nfiles - number of files in the fileset
-# $nthreads - number of worker threads
-
-set $dir=/tmp
-set $eventrate=10
-set $dirwidth=20
-set $filesize=16k
-set $iosize=1m
-set $nfiles=1000
-set $nthreads=1
-
-eventgen rate=$eventrate
-set mode quit firstdone
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc=100
-define fileset name=destfiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=openfile1,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile1,fd=1,iosize=$iosize
- flowop createfile name=createfile2,filesetname=destfiles,fd=2
- flowop writewholefile name=writefile2,filesetname=destfiles,fd=2,srcfd=1,iosize=$iosize
- flowop closefile name=closefile1,fd=1
- flowop closefile name=closefile2,fd=2
- flowop iopslimit name=iopslim1, target=writefile2
- }
-}
-
-echo "RateLimCopyFiles Version 1.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " set \$dirwidth=<value> defaults to $dirwidth"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/removedirs.f b/usr/src/cmd/filebench/workloads/removedirs.f
deleted file mode 100644
index debf062817..0000000000
--- a/usr/src/cmd/filebench/workloads/removedirs.f
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Creates a fileset with $ndirs empty leaf directories then rmdir's all of them
-#
-set $dir=/tmp
-set $ndirs=10000
-set $meandirwidth=100
-set $nthreads=16
-
-set mode quit firstdone
-
-define fileset name=bigfileset,path=$dir,size=0,leafdirs=$ndirs,dirwidth=$meandirwidth,prealloc
-
-define process name=remdir,instances=1
-{
- thread name=removedirectory,memsize=1m,instances=$nthreads
- {
- flowop removedir name=dirremover,filesetname=bigfileset
- }
-}
-
-echo "RemoveDir Version 1.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage " set \$ndirs=<value> defaults to $ndirs"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage "(sets mean dir width and dir depth is calculated as log (width, ndirs)"
-usage " "
-usage " run"
diff --git a/usr/src/cmd/filebench/workloads/singlestreamread.f b/usr/src/cmd/filebench/workloads/singlestreamread.f
deleted file mode 100644
index a5852dc7dc..0000000000
--- a/usr/src/cmd/filebench/workloads/singlestreamread.f
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $filesize=5g
-set $nthreads=1
-set $iosize=1m
-set $directio=0
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse
-
-define process name=seqread,instances=1
-{
- thread name=seqread,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread,filename=largefile1,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Single Stream Read Version 2.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$directio=<bool> defaults to $directio"
-usage " "
-usage "This workload needs $filesize of disk space by default"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/singlestreamreaddirect.f b/usr/src/cmd/filebench/workloads/singlestreamreaddirect.f
deleted file mode 100644
index abd44e12d8..0000000000
--- a/usr/src/cmd/filebench/workloads/singlestreamreaddirect.f
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $filesize=5g
-set $nthreads=1
-set $iosize=1m
-
-define file name=largefile1,path=$dir,size=$filesize,prealloc,reuse
-
-define process name=seqread,instances=1
-{
- thread name=seqread,memsize=10m,instances=$nthreads
- {
- flowop read name=seqread,filename=largefile1,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Single Stream Read Version 2.0 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " "
-usage "This workload needs $filesize of disk space by default"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/singlestreamwrite.f b/usr/src/cmd/filebench/workloads/singlestreamwrite.f
deleted file mode 100644
index 7ff39a4670..0000000000
--- a/usr/src/cmd/filebench/workloads/singlestreamwrite.f
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $directio=false
-set $iosize=1m
-set $nthreads=1
-
-define file name=largefile1,path=$dir,prealloc
-
-define process name=seqwrite,instances=1
-{
- thread name=seqwrite,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite,filename=largefile1,iosize=$iosize,directio=$directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Single Stream Write Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$directio=<bool> defaults to $directio"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/singlestreamwritedirect.f b/usr/src/cmd/filebench/workloads/singlestreamwritedirect.f
deleted file mode 100644
index 26f4968dd4..0000000000
--- a/usr/src/cmd/filebench/workloads/singlestreamwritedirect.f
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $iosize=1m
-set $nthreads=1
-
-define file name=largefile1,path=$dir,prealloc
-
-define process name=seqwrite,instances=1
-{
- thread name=seqwrite,memsize=10m,instances=$nthreads
- {
- flowop write name=seqwrite,filename=largefile1,iosize=$iosize,directio
- flowop bwlimit name=limit
- }
-}
-
-echo "Single Stream Write Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$iosize=<value> defaults to $iosize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/tpcso.f b/usr/src/cmd/filebench/workloads/tpcso.f
deleted file mode 100644
index f73211c87a..0000000000
--- a/usr/src/cmd/filebench/workloads/tpcso.f
+++ /dev/null
@@ -1,268 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-# $dir - directory for datafiles
-# $eventrate - event generator rate (0 == free run)
-# $iosize - iosize for database block access
-# $nshadows - number of shadow processes
-# $ndbwriters - number of database writers
-
-set $dir=/tmp
-set $eventrate=0
-set $iosize=2k
-set $nshadows=200
-set $ndbwriters=10
-set $runtime=30
-set $usermode=20000
-set $memperthread=1m
-
-debug 1
-eventgen rate=$eventrate
-
-# Define a datafile and logfile
-define file name=aux.df,path=$dir,size=251m,reuse,prealloc,paralloc
-define file name=control_001,path=$dir,size=2m,reuse,prealloc,paralloc
-define file name=cust_0_0,path=$dir,size=6704m,reuse,prealloc,paralloc
-define file name=cust_0_1,path=$dir,size=6704m,reuse,prealloc,paralloc
-define file name=cust_0_2,path=$dir,size=6704m,reuse,prealloc,paralloc
-define file name=cust_0_3,path=$dir,size=6704m,reuse,prealloc,paralloc
-define file name=dist_0_0,path=$dir,size=31m,reuse,prealloc,paralloc
-define file name=hist_0_0,path=$dir,size=3002m,reuse,prealloc,paralloc
-define file name=icust1_0_0,path=$dir,size=4943m,reuse,prealloc,paralloc
-define file name=icust2_0_0,path=$dir,size=4943m,reuse,prealloc,paralloc
-define file name=idist_0_0,path=$dir,size=11m,reuse,prealloc,paralloc
-define file name=iitem_0_0,path=$dir,size=11m,reuse,prealloc,paralloc
-define file name=iordr2_0_0,path=$dir,size=1651m,reuse,prealloc,paralloc
-define file name=istok_0_0,path=$dir,size=2262m,reuse,prealloc,paralloc
-define file name=item_0_0,path=$dir,size=21m,reuse,prealloc,paralloc
-define file name=iware_0_0,path=$dir,size=11m,reuse,prealloc,paralloc
-define file name=nord_0_0,path=$dir,size=561m,reuse,prealloc,paralloc
-define file name=ordr_0_0,path=$dir,size=44301m,reuse,prealloc,paralloc
-define file name=roll1,path=$dir,size=2001m,reuse,prealloc,paralloc
-define file name=sp_0,path=$dir,size=1001m,reuse,prealloc,paralloc
-define file name=stok_0_0,path=$dir,size=8052m,reuse,prealloc,paralloc
-define file name=stok_0_1,path=$dir,size=8052m,reuse,prealloc,paralloc
-define file name=stok_0_2,path=$dir,size=8052m,reuse,prealloc,paralloc
-define file name=stok_0_3,path=$dir,size=8052m,reuse,prealloc,paralloc
-define file name=stok_0_4,path=$dir,size=8052m,reuse,prealloc,paralloc
-define file name=system_1,path=$dir,size=401m,reuse,prealloc,paralloc
-define file name=temp_0_0,path=$dir,size=4943m,reuse,prealloc,paralloc
-define file name=temp_0_1,path=$dir,size=4943m,reuse,prealloc,paralloc
-define file name=ware_0_0,path=$dir,size=11m,reuse,prealloc,paralloc
-define file name=log_1_1,path=$dir,size=1021m,reuse,prealloc,paralloc
-
-# Define database writer processes
-define process name=dbwr,instances=$ndbwriters
-{
- thread name=dbwr,memsize=$memperthread,useism
- {
- flowop aiowrite name=dbaiowrite-aux.df,filename=aux.df,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-control_001,filename=control_001,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-cust_0_0,filename=cust_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-cust_0_1,filename=cust_0_1,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-cust_0_2,filename=cust_0_2,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-cust_0_3,filename=cust_0_3,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-dist_0_0,filename=dist_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-hist_0_0,filename=hist_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-icust1_0_0,filename=icust1_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-icust2_0_0,filename=icust2_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-idist_0_0,filename=idist_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-iitem_0_0,filename=iitem_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-iordr2_0_0,filename=iordr2_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-istok_0_0,filename=istok_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-item_0_0,filename=item_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-iware_0_0,filename=iware_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-nord_0_0,filename=nord_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-ordr_0_0,filename=ordr_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-roll1,filename=roll1,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-sp_0,filename=sp_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-stok_0_0,filename=stok_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-stok_0_1,filename=stok_0_1,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-stok_0_2,filename=stok_0_2,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-stok_0_3,filename=stok_0_3,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-stok_0_4,filename=stok_0_4,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-system_1,filename=system_1,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-temp_0_0,filename=temp_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-temp_0_1,filename=temp_0_1,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop aiowrite name=dbaiowrite-ware_0_0,filename=ware_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio,iters=10
- flowop hog name=dbwr-hog,value=10000
- flowop semblock name=dbwr-block,value=100,highwater=10000
- flowop aiowait name=dbwr-aiowait
- }
-}
-
-define process name=lgwr,instances=1
-{
- thread name=lgwr,memsize=$memperthread,useism
- {
- flowop write name=lg-write,filename=log_1_1,
- iosize=256k,workingset=1g,random,dsync,directio
-# flowop delay name=lg-delay,value=1
- flowop semblock name=lg-block,value=320,highwater=1000
- }
-}
-
-define process name=shadow,instances=$nshadows
-{
- thread name=shadow,memsize=$memperthread,useism
- {
- flowop read name=shadowread-aux.df,filename=aux.df,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-control_001,filename=control_001,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-cust_0_0,filename=cust_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-cust_0_1,filename=cust_0_1,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-cust_0_2,filename=cust_0_2,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-cust_0_3,filename=cust_0_3,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-dist_0_0,filename=dist_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-hist_0_0,filename=hist_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-icust1_0_0,filename=icust1_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-icust2_0_0,filename=icust2_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-idist_0_0,filename=idist_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-iitem_0_0,filename=iitem_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-iordr2_0_0,filename=iordr2_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-istok_0_0,filename=istok_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-item_0_0,filename=item_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-iware_0_0,filename=iware_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-nord_0_0,filename=nord_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-ordr_0_0,filename=ordr_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-roll1,filename=roll1,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-sp_0,filename=sp_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-stok_0_0,filename=stok_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-stok_0_1,filename=stok_0_1,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-stok_0_2,filename=stok_0_2,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-stok_0_3,filename=stok_0_3,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-stok_0_4,filename=stok_0_4,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-system_1,filename=system_1,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-temp_0_0,filename=temp_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-temp_0_1,filename=temp_0_1,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-ware_0_0,filename=ware_0_0,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop read name=shadowread-log_1_1,filename=log_1_1,
- iosize=$iosize,workingset=10g,random,dsync,directio
- flowop hog name=shadowhog,value=$usermode
- flowop sempost name=shadow-post-lg,value=1,target=lg-block,blocking
- flowop sempost name=shadow-post-dbwr,value=1,target=dbwr-block,blocking
- flowop eventlimit name=random-rate
- }
-}
-
-echo "Tpcso Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " "
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " "
-usage " set \$iosize=<value> defaults to $iosize, typically 2k or 8k"
-usage " "
-usage " set \$memperthread=<value> defaults to $memperthread, there are 211 threads"
-usage " "
-usage " run runtime (e.g. run 60)"
-usage " "
-usage "Note - this workload needs at least 512MB of of memory"
-usage " "
diff --git a/usr/src/cmd/filebench/workloads/varmail.f b/usr/src/cmd/filebench/workloads/varmail.f
deleted file mode 100644
index d78a9c0567..0000000000
--- a/usr/src/cmd/filebench/workloads/varmail.f
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $nfiles=1000
-set $meandirwidth=1000000
-set $filesize=16k
-set $nthreads=16
-set $meaniosize=16k
-set $readiosize=1m
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop deletefile name=deletefile1,filesetname=bigfileset
- flowop createfile name=createfile2,filesetname=bigfileset,fd=1
- flowop appendfilerand name=appendfilerand2,iosize=$meaniosize,fd=1
- flowop fsync name=fsyncfile2,fd=1
- flowop closefile name=closefile2,fd=1
- flowop openfile name=openfile3,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile3,fd=1,iosize=$readiosize
- flowop appendfilerand name=appendfilerand3,iosize=$meaniosize,fd=1
- flowop fsync name=fsyncfile3,fd=1
- flowop closefile name=closefile3,fd=1
- flowop openfile name=openfile4,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile4,fd=1,iosize=$readiosize
- flowop closefile name=closefile4,fd=1
- }
-}
-
-echo "Varmail Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meaniosize=<value> defaults to $meaniosize"
-usage " set \$readiosize=<size> defaults to $readiosize"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " dirdepth therefore defaults to dir depth of 1 as in postmark"
-usage " set $meandir lower to increase depth beyond 1 if desired)"
-usage " "
-usage " run runtime (e.g. run 60)"
-
diff --git a/usr/src/cmd/filebench/workloads/videoserver.f b/usr/src/cmd/filebench/workloads/videoserver.f
deleted file mode 100644
index 05451e3900..0000000000
--- a/usr/src/cmd/filebench/workloads/videoserver.f
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# This workloads emulates a video server. It has two filesets, one of videos
-# being actively served, and one of videos availabe but currently inactive
-# (passive). However, one thread, vidwriter, is writing new videos to replace
-# no longer viewed videos in the passive set. Meanwhile $nthreads threads are
-# serving up videos from the activevids fileset. If the desired rate is R mb/s,
-# and $nthreads is set to T, then set the $srvbwrate to R * T to get the
-# desired rate per video stream. The video replacement rate of one video
-# file per replacement interval, is set by $repintval which defaults to
-# 10 seconds. Thus the write bandwidth will be set as $filesize/$repintval.
-
-set $dir=/tmp
-set $eventrate=96
-set $filesize=10g
-set $nthreads=48
-set $numactivevids=32
-set $numpassivevids=194
-set $reuseit=false
-set $readiosize=256k
-set $writeiosize=1m
-#
-set $passvidsname=passivevids
-set $actvidsname=activevids
-#
-set $repintval=10
-
-eventgen rate=$eventrate
-
-define fileset name=$actvidsname,path=$dir,size=$filesize,entries=$numactivevids,dirwidth=4,prealloc,paralloc,reuse=$reuseit
-define fileset name=$passvidsname,path=$dir,size=$filesize,entries=$numpassivevids,dirwidth=20,prealloc=50,paralloc,reuse=$reuseit
-
-define process name=vidwriter,instances=1
-{
- thread name=vidwriter,memsize=10m,instances=1
- {
- flowop deletefile name=vidremover,filesetname=$passvidsname
- flowop createfile name=wrtopen,filesetname=$passvidsname,fd=1
- flowop writewholefile name=newvid,iosize=$writeiosize,fd=1,srcfd=1
- flowop closefile name=wrtclose, fd=1
- flowop delay name=replaceinterval, value=$repintval
- }
-}
-
-define process name=vidreaders,instances=1
-{
- thread name=vidreaders,memsize=10m,instances=$nthreads
- {
- flowop read name=vidreader,filesetname=$actvidsname,iosize=$readiosize
- flowop bwlimit name=serverlimit, target=vidreader
- }
-}
-
-echo "Video Server Version 1.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir> defaults to $dir"
-usage " set \$eventrate=<value> defaults to $eventrate"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$writeiosize=<value> defaults to $writeiosize"
-usage " set \$readiosize=<value> defaults to $readiosize"
-usage " set \$numactivevids=<value> defaults to $numactivevids"
-usage " set \$numpassivevids=<value> defaults to $numpassivevids"
-usage " "
-usage " run runtime (e.g. run 60)"
-
diff --git a/usr/src/cmd/filebench/workloads/webproxy.f b/usr/src/cmd/filebench/workloads/webproxy.f
deleted file mode 100644
index 2946d648fa..0000000000
--- a/usr/src/cmd/filebench/workloads/webproxy.f
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-
-set $dir=/tmp
-set $nfiles=10000
-set $meandirwidth=1000000
-set $filesize=16k
-set $nthreads=100
-set $meaniosize=16k
-set $readiosize=1m
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80
-
-define process name=proxycache,instances=1
-{
- thread name=proxycache,memsize=10m,instances=$nthreads
- {
- flowop deletefile name=deletefile1,filesetname=bigfileset
- flowop createfile name=createfile1,filesetname=bigfileset,fd=1
- flowop appendfilerand name=appendfilerand1,iosize=$meaniosize,fd=1
- flowop closefile name=closefile1,fd=1
- flowop openfile name=openfile2,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile2,fd=1,iosize=$readiosize
- flowop closefile name=closefile2,fd=1
- flowop openfile name=openfile3,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile3,fd=1,iosize=$readiosize
- flowop closefile name=closefile3,fd=1
- flowop openfile name=openfile4,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile4,fd=1,iosize=$readiosize
- flowop closefile name=closefile4,fd=1
- flowop openfile name=openfile5,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile5,fd=1,iosize=$readiosize
- flowop closefile name=closefile5,fd=1
- flowop openfile name=openfile6,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile6,fd=1,iosize=$readiosize
- flowop closefile name=closefile6,fd=1
- flowop opslimit name=limit
- }
-}
-
-echo "Proxy Cache Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$meaniosize=<value> defaults to $meaniosize"
-usage " set \$readiosize=<size> defaults to $readiosize"
-usage " set \$meandirwidth=<size> defaults to $meandirwidth"
-usage "(sets mean dir width and dir depth is calculated as log (width, nfiles)"
-usage " dirdepth therefore defaults to dir depth of 1 as in postmark"
-usage " set $meandir lower to increase depth beyond 1 if desired)"
-usage " "
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/filebench/workloads/webserver.f b/usr/src/cmd/filebench/workloads/webserver.f
deleted file mode 100644
index d054a41041..0000000000
--- a/usr/src/cmd/filebench/workloads/webserver.f
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-set $dir=/tmp
-set $nfiles=1000
-set $dirwidth=20
-set $filesize=16k
-set $nthreads=100
-set $iosize=1m
-
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc=100
-define fileset name=logfiles,path=$dir,size=$filesize,entries=1,dirwidth=$dirwidth,prealloc
-
-define process name=filereader,instances=1
-{
- thread name=filereaderthread,memsize=10m,instances=$nthreads
- {
- flowop openfile name=openfile1,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile1,fd=1,iosize=$iosize
- flowop closefile name=closefile1,fd=1
- flowop openfile name=openfile2,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile2,fd=1,iosize=$iosize
- flowop closefile name=closefile2,fd=1
- flowop openfile name=openfile3,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile3,fd=1,iosize=$iosize
- flowop closefile name=closefile3,fd=1
- flowop openfile name=openfile4,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile4,fd=1,iosize=$iosize
- flowop closefile name=closefile4,fd=1
- flowop openfile name=openfile5,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile5,fd=1,iosize=$iosize
- flowop closefile name=closefile5,fd=1
- flowop openfile name=openfile6,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile6,fd=1,iosize=$iosize
- flowop closefile name=closefile6,fd=1
- flowop openfile name=openfile7,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile7,fd=1,iosize=$iosize
- flowop closefile name=closefile7,fd=1
- flowop openfile name=openfile8,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile8,fd=1,iosize=$iosize
- flowop closefile name=closefile8,fd=1
- flowop openfile name=openfile9,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile9,fd=1,iosize=$iosize
- flowop closefile name=closefile9,fd=1
- flowop openfile name=openfile10,filesetname=bigfileset,fd=1
- flowop readwholefile name=readfile10,fd=1,iosize=$iosize
- flowop closefile name=closefile10,fd=1
- flowop appendfilerand name=appendlog,filesetname=logfiles,iosize=16k,fd=2
- }
-}
-
-echo "Webserver Version 2.1 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
-usage " set \$filesize=<size> defaults to $filesize"
-usage " set \$nfiles=<value> defaults to $nfiles"
-usage " set \$dirwidth=<value> defaults to $dirwidth"
-usage " set \$nthreads=<value> defaults to $nthreads"
-usage " set \$iosize=<size> defaults to $iosize"
-usage " run runtime (e.g. run 60)"
diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c
index dcd1d42a42..384121a589 100644
--- a/usr/src/cmd/zonecfg/zonecfg.c
+++ b/usr/src/cmd/zonecfg/zonecfg.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013, Joyent Inc. All rights reserved.
*/
@@ -6212,6 +6213,8 @@ verify_func(cmd_t *cmd)
char brand[MAXNAMELEN];
char hostidp[HW_HOSTID_LEN];
char fsallowedp[ZONE_FS_ALLOWED_MAX];
+ priv_set_t *privs;
+ char *privname = NULL;
int err, ret_val = Z_OK, arg;
int pset_res;
boolean_t save = B_FALSE;
@@ -6279,6 +6282,18 @@ verify_func(cmd_t *cmd)
saw_error = B_TRUE;
}
+ if ((privs = priv_allocset()) == NULL) {
+ zerr(gettext("%s: priv_allocset failed"), zone);
+ return;
+ }
+ if (zonecfg_get_privset(handle, privs, &privname) != Z_OK) {
+ zerr(gettext("%s: invalid privilege: %s"), zone, privname);
+ priv_freeset(privs);
+ free(privname);
+ return;
+ }
+ priv_freeset(privs);
+
if (zonecfg_get_hostid(handle, hostidp,
sizeof (hostidp)) == Z_INVALID_PROPERTY) {
zerr(gettext("%s: invalid hostid: %s"),
diff --git a/usr/src/man/man1/Makefile b/usr/src/man/man1/Makefile
index c87388e5f6..21b0b0aa69 100644
--- a/usr/src/man/man1/Makefile
+++ b/usr/src/man/man1/Makefile
@@ -132,7 +132,6 @@ MANFILES= acctcom.1 \
fdformat.1 \
fgrep.1 \
file.1 \
- filebench.1 \
filesync.1 \
find.1 \
finger.1 \
diff --git a/usr/src/man/man1/filebench.1 b/usr/src/man/man1/filebench.1
deleted file mode 100644
index 3d15c9b743..0000000000
--- a/usr/src/man/man1/filebench.1
+++ /dev/null
@@ -1,175 +0,0 @@
-'\" te
-.\" Copyright (c) 2007, Sun Microsystems Inc. All Rights Reserved.
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH FILEBENCH 1 "Oct 9, 2007"
-.SH NAME
-filebench \- framework of workloads to measure and compare filesystem
-performance
-.SH SYNOPSIS
-.LP
-.nf
-\fB/usr/benchmarks/filebench/bin/filebench\fR \fIprofile\fR
-.fi
-
-.LP
-.nf
-\fB/usr/benchmarks/filebench/bin/filebench\fR \fB-c\fR \fIstats_dir...\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-\fBfilebench\fR runs workloads to measure and compare filesystem performance.
-.sp
-.LP
-Full documentation can be found at the performance community at:
-http://www.opensolaris.org
-.SH OPTIONS
-.sp
-.LP
-The following options are supported:
-.sp
-.ne 2
-.na
-\fB\fB-c\fR \fIstats_dir...\fR\fR
-.ad
-.RS 19n
-Generates a HTML file (\fBindex.html\fR) that is a comparison of the specified
-directories. \fIstats_dir\fR specifies the directory or directories in which
-the results are stored.
-.RE
-
-.SH OPERANDS
-.sp
-.LP
-The following operands are supported:
-.sp
-.ne 2
-.na
-\fB\fIprofile\fR\fR
-.ad
-.RS 11n
-Specifies the name of the configuration file ending in \fB\&.prof\fR. The
-configuration file specifies:
-.RS +4
-.TP
-.ie t \(bu
-.el o
-what workloads to run,
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-what parameters to run,
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-the directory path on which to operate, and
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-the directory path in which to store the results.
-.RE
-.RE
-
-.SH EXIT STATUS
-.sp
-.LP
-The following exit values are returned:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 5n
-Successful completion.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 5n
-An error occurred.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB2\fR\fR
-.ad
-.RS 5n
-Invalid command line options were specified.
-.RE
-
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRRunning the Multi-stream Sequential Read Workload
-.sp
-.LP
-The following example runs the workloads described in the configuration file
-named \fBsqread.prof\fR:
-
-.sp
-.in +2
-.nf
-# filebench sqread
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 2 \fRComparing Multiple Runs
-.sp
-.LP
-The following example compares the results of two previous runs.
-
-.sp
-.LP
-This example assumes that the results from the two previous \fBfilebench\fR
-runs were located in the directories:
-\fB/stats/wombat-zfs-noel-Jun_27_2007-15h_45m_33s\fR and
-\fB/stats/wombat-ufs-noel-Jun_27_2007-15h_52m_11s\fR.
-
-.sp
-.LP
-This example generates a HTML file named \fBindex.html\fR in your current
-working directory.
-
-.sp
-.in +2
-.nf
-# filebench -c /stats/wombat-zfs-noel-Jun_27_2007-15h_45m_33s \e
- /stats/wombat-ufs-noel-Jun_27_2007-15h_52m_11s
-.fi
-.in -2
-.sp
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Uncommitted
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBattributes\fR(5)
diff --git a/usr/src/pkg/manifests/benchmark-filebench.mf b/usr/src/pkg/manifests/benchmark-filebench.mf
index fd44a0ca58..775ae3996f 100644
--- a/usr/src/pkg/manifests/benchmark-filebench.mf
+++ b/usr/src/pkg/manifests/benchmark-filebench.mf
@@ -24,94 +24,5 @@
#
set name=pkg.fmri value=pkg:/benchmark/filebench@$(PKGVERS)
-set name=pkg.description \
- value="FileBench Commands, Workloads, Scripts, and Config Files"
-set name=pkg.summary value=FileBench
-set name=info.classification \
- value=org.opensolaris.category.2008:Development/System
+set name=pkg.obsolete value=true
set name=variant.arch value=$(ARCH)
-dir path=usr group=sys
-dir path=usr/benchmarks
-dir path=usr/benchmarks/filebench
-dir path=usr/benchmarks/filebench/bin
-$(i386_ONLY)dir path=usr/benchmarks/filebench/bin/$(ARCH)
-dir path=usr/benchmarks/filebench/bin/$(ARCH64)
-dir path=usr/benchmarks/filebench/config
-dir path=usr/benchmarks/filebench/scripts
-dir path=usr/benchmarks/filebench/workloads
-dir path=usr/share/man/man1
-$(i386_ONLY)file path=usr/benchmarks/filebench/bin/$(ARCH)/go_filebench \
- mode=0555
-file path=usr/benchmarks/filebench/bin/$(ARCH64)/go_filebench mode=0555
-file path=usr/benchmarks/filebench/bin/filebench mode=0555
-file path=usr/benchmarks/filebench/config/fileio.prof mode=0444
-file path=usr/benchmarks/filebench/config/filemacro.prof mode=0444
-file path=usr/benchmarks/filebench/config/filemicro.prof mode=0444
-file path=usr/benchmarks/filebench/config/generic.func mode=0444
-file path=usr/benchmarks/filebench/config/multi_fileserver.prof mode=0444
-file path=usr/benchmarks/filebench/config/newfeatures.prof mode=0444
-file path=usr/benchmarks/filebench/config/randomread.prof mode=0444
-file path=usr/benchmarks/filebench/config/seqread.prof mode=0444
-file path=usr/benchmarks/filebench/config/videoserver.prof mode=0444
-file path=usr/benchmarks/filebench/scripts/filebench_compare mode=0555
-file path=usr/benchmarks/filebench/scripts/fs_flush mode=0555
-file path=usr/benchmarks/filebench/workloads/bringover.f mode=0444
-file path=usr/benchmarks/filebench/workloads/compflow_demo.f mode=0444
-file path=usr/benchmarks/filebench/workloads/copyfiles.f mode=0444
-file path=usr/benchmarks/filebench/workloads/createfiles.f mode=0444
-file path=usr/benchmarks/filebench/workloads/deletefiles.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_create.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_createfiles.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_createrand.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_delete.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_rread.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_rwrite.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_rwritedsync.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_rwritefsync.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_seqread.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_seqwrite.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_seqwriterand.f \
- mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_seqwriterandvargam.f \
- mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_seqwriterandvartab.f \
- mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_statfile.f mode=0444
-file path=usr/benchmarks/filebench/workloads/filemicro_writefsync.f mode=0444
-file path=usr/benchmarks/filebench/workloads/fileserver.f mode=0444
-file path=usr/benchmarks/filebench/workloads/listdirs.f mode=0444
-file path=usr/benchmarks/filebench/workloads/makedirs.f mode=0444
-file path=usr/benchmarks/filebench/workloads/mongo.f mode=0444
-file path=usr/benchmarks/filebench/workloads/multistreamread.f mode=0444
-file path=usr/benchmarks/filebench/workloads/multistreamreaddirect.f mode=0444
-file path=usr/benchmarks/filebench/workloads/multistreamwrite.f mode=0444
-file path=usr/benchmarks/filebench/workloads/multistreamwritedirect.f \
- mode=0444
-file path=usr/benchmarks/filebench/workloads/networkfs.f mode=0444
-file path=usr/benchmarks/filebench/workloads/oltp.f mode=0444
-file path=usr/benchmarks/filebench/workloads/openfiles.f mode=0444
-file path=usr/benchmarks/filebench/workloads/randomfileaccess.f mode=0444
-file path=usr/benchmarks/filebench/workloads/randomread.f mode=0444
-file path=usr/benchmarks/filebench/workloads/randomrw.f mode=0444
-file path=usr/benchmarks/filebench/workloads/randomwrite.f mode=0444
-file path=usr/benchmarks/filebench/workloads/ratelimcopyfiles.f mode=0444
-file path=usr/benchmarks/filebench/workloads/removedirs.f mode=0444
-file path=usr/benchmarks/filebench/workloads/singlestreamread.f mode=0444
-file path=usr/benchmarks/filebench/workloads/singlestreamreaddirect.f \
- mode=0444
-file path=usr/benchmarks/filebench/workloads/singlestreamwrite.f mode=0444
-file path=usr/benchmarks/filebench/workloads/singlestreamwritedirect.f \
- mode=0444
-file path=usr/benchmarks/filebench/workloads/tpcso.f mode=0444
-file path=usr/benchmarks/filebench/workloads/varmail.f mode=0444
-file path=usr/benchmarks/filebench/workloads/videoserver.f mode=0444
-file path=usr/benchmarks/filebench/workloads/webproxy.f mode=0444
-file path=usr/benchmarks/filebench/workloads/webserver.f mode=0444
-file path=usr/share/man/man1/filebench.1
-hardlink path=usr/benchmarks/filebench/bin/go_filebench \
- target=../../../../usr/lib/isaexec
-legacy pkg=SUNWfilebench \
- desc="FileBench Commands, Workloads, Scripts, and Config Files" \
- name=FileBench
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
diff --git a/usr/src/uts/common/inet/ip/icmp.c b/usr/src/uts/common/inet/ip/icmp.c
index 8da126f7dc..a4abdbd130 100644
--- a/usr/src/uts/common/inet/ip/icmp.c
+++ b/usr/src/uts/common/inet/ip/icmp.c
@@ -3463,7 +3463,7 @@ icmp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
v4mapped, connp->conn_netstack)) {
/* Mismatched v4mapped/v6 specified by srcid. */
mutex_exit(&connp->conn_lock);
@@ -4455,7 +4455,7 @@ icmp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6,
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
v4mapped, connp->conn_netstack)) {
/* Mismatched v4mapped/v6 specified by srcid. */
mutex_exit(&connp->conn_lock);
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index 4a6e835b67..c919563289 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -2733,7 +2733,7 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
v4mapped, connp->conn_netstack)) {
/* Mismatch - v4mapped/v6 specified by srcid. */
mutex_exit(&connp->conn_lock);
@@ -3754,7 +3754,7 @@ udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6,
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
v4mapped, connp->conn_netstack)) {
/* Mismatched v4mapped/v6 specified by srcid. */
mutex_exit(&connp->conn_lock);
@@ -5571,7 +5571,7 @@ udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
srcid = sin6->__sin6_src_id;
v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
v4mapped, connp->conn_netstack)) {
/* Mismatch v4mapped/v6 specified by srcid. */
return (EADDRNOTAVAIL);