summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/filebench/common/filebench.h2
-rw-r--r--usr/src/cmd/filebench/common/fileset.c62
-rw-r--r--usr/src/cmd/filebench/common/fileset.h4
-rw-r--r--usr/src/cmd/filebench/common/flowop.c87
-rw-r--r--usr/src/cmd/filebench/common/flowop.h1
-rw-r--r--usr/src/cmd/filebench/common/flowop_library.c158
-rw-r--r--usr/src/cmd/filebench/common/ipc.c2
-rw-r--r--usr/src/cmd/filebench/common/ipc.h3
-rw-r--r--usr/src/cmd/filebench/common/misc.c3
-rw-r--r--usr/src/cmd/filebench/common/procflow.c40
-rw-r--r--usr/src/cmd/filebench/workloads/Makefile1
-rw-r--r--usr/src/cmd/filebench/workloads/bringover.f8
-rw-r--r--usr/src/cmd/filebench/workloads/copyfiles.f8
-rw-r--r--usr/src/cmd/filebench/workloads/createfiles.f6
-rw-r--r--usr/src/cmd/filebench/workloads/deletefiles.f8
-rw-r--r--usr/src/cmd/filebench/workloads/filemicro_delete.f6
-rw-r--r--usr/src/cmd/filebench/workloads/mongo.f10
-rw-r--r--usr/src/cmd/filebench/workloads/ratelimcopyfiles.f72
-rw-r--r--usr/src/pkgdefs/SUNWfilebench/prototype_com1
19 files changed, 420 insertions, 62 deletions
diff --git a/usr/src/cmd/filebench/common/filebench.h b/usr/src/cmd/filebench/common/filebench.h
index f6c3e63b34..512d713d6c 100644
--- a/usr/src/cmd/filebench/common/filebench.h
+++ b/usr/src/cmd/filebench/common/filebench.h
@@ -119,7 +119,7 @@ void filebench_shutdown(int error);
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
-#define FILEBENCH_VERSION "1.3.1"
+#define FILEBENCH_VERSION "1.3.2"
#define FILEBENCHDIR "/usr/benchmarks/filebench"
#define FILEBENCH_PROMPT "filebench> "
#define MAX_LINE_LEN 1024
diff --git a/usr/src/cmd/filebench/common/fileset.c b/usr/src/cmd/filebench/common/fileset.c
index 57d97ad2e6..d402c49431 100644
--- a/usr/src/cmd/filebench/common/fileset.c
+++ b/usr/src/cmd/filebench/common/fileset.c
@@ -47,6 +47,13 @@
* 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.
+ *
+ * This routine is called from fileset_createset(), which is in turn
+ * 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);
@@ -298,6 +305,12 @@ fileset_alloc_file(filesetentry_t *entry)
entry->fse_size);
entry->fse_flags |= FSE_EXISTS;
+ (void) ipc_mutex_lock(
+ &entry->fse_fileset->fs_num_files_lock);
+ entry->fse_fileset->fs_num_act_files++;
+ (void) ipc_mutex_unlock(
+ &entry->fse_fileset->fs_num_files_lock);
+
(void) close(fd);
return (0);
@@ -317,6 +330,13 @@ fileset_alloc_file(filesetentry_t *entry)
entry->fse_size);
entry->fse_flags |= FSE_EXISTS;
+
+ (void) ipc_mutex_lock(
+ &entry->fse_fileset->fs_num_files_lock);
+ entry->fse_fileset->fs_num_act_files++;
+ (void) ipc_mutex_unlock(
+ &entry->fse_fileset->fs_num_files_lock);
+
(void) close(fd);
return (0);
}
@@ -337,6 +357,10 @@ fileset_alloc_file(filesetentry_t *entry)
entry->fse_flags |= FSE_EXISTS;
+ (void) ipc_mutex_lock(&entry->fse_fileset->fs_num_files_lock);
+ entry->fse_fileset->fs_num_act_files++;
+ (void) ipc_mutex_unlock(&entry->fse_fileset->fs_num_files_lock);
+
for (seek = 0; seek < entry->fse_size; ) {
off64_t wsize;
int ret = 0;
@@ -431,9 +455,14 @@ fileset_openfile(fileset_t *fileset,
return (-1);
}
- if (flag & O_CREAT)
+ if (flag & O_CREAT) {
entry->fse_flags |= FSE_EXISTS;
+ (void) ipc_mutex_lock(&fileset->fs_num_files_lock);
+ fileset->fs_num_act_files++;
+ (void) ipc_mutex_unlock(&fileset->fs_num_files_lock);
+ }
+
if (attrs & FLOW_ATTR_DSYNC) {
#ifdef sun
open_attrs |= O_DSYNC;
@@ -486,6 +515,25 @@ fileset_pick(fileset_t *fileset, int flags, int tid)
(void) ipc_mutex_lock(&filebench_shm->shm_fileset_lock);
+ /* see if asking for impossible */
+ (void) ipc_mutex_lock(&fileset->fs_num_files_lock);
+ if (flags & FILESET_PICKEXISTS) {
+ if (fileset->fs_num_act_files == 0) {
+ (void) ipc_mutex_unlock(&fileset->fs_num_files_lock);
+ (void) ipc_mutex_unlock(
+ &filebench_shm->shm_fileset_lock);
+ return (NULL);
+ }
+ } else if (flags & FILESET_PICKNOEXIST) {
+ if (fileset->fs_num_act_files == fileset->fs_realfiles) {
+ (void) ipc_mutex_unlock(&fileset->fs_num_files_lock);
+ (void) ipc_mutex_unlock(
+ &filebench_shm->shm_fileset_lock);
+ return (NULL);
+ }
+ }
+ (void) ipc_mutex_unlock(&fileset->fs_num_files_lock);
+
while (entry == NULL) {
if ((flags & FILESET_PICKDIR) && (flags & FILESET_PICKRESET)) {
@@ -609,6 +657,9 @@ fileset_create(fileset_t *fileset)
return (-1);
}
+ /* declare all files currently non existant (single threaded code) */
+ fileset->fs_num_act_files = 0;
+
#ifdef HAVE_RAW_SUPPORT
/* treat raw device as special case */
if (fileset->fs_attrs & FILESET_IS_RAW_DEV)
@@ -1002,6 +1053,7 @@ exists:
fileset->fs_meandepth,
(u_longlong_t)(fileset->fs_bytes / 1024UL / 1024UL));
}
+
return (0);
}
@@ -1010,6 +1062,10 @@ exists:
* 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)
@@ -1028,6 +1084,10 @@ fileset_define(avd_t name)
filebench_log(LOG_DEBUG_IMPL,
"Defining file %s", avd_get_str(name));
+ /* initialize fs_num_act_files lock */
+ (void) pthread_mutex_init(&fileset->fs_num_files_lock,
+ ipc_mutexattr());
+
(void) ipc_mutex_lock(&filebench_shm->shm_fileset_lock);
fileset->fs_dirgamma = avd_int_alloc(1500);
diff --git a/usr/src/cmd/filebench/common/fileset.h b/usr/src/cmd/filebench/common/fileset.h
index 3ad69a61c9..c20bf28bf5 100644
--- a/usr/src/cmd/filebench/common/fileset.h
+++ b/usr/src/cmd/filebench/common/fileset.h
@@ -118,6 +118,10 @@ typedef struct fileset {
double fs_meansize; /* Specified mean file size */
int fs_realfiles; /* Actual files */
off64_t fs_bytes; /* Total space consumed by files */
+ fbint_t fs_num_act_files; /* total number of files */
+ /* actually existing in the */
+ /* host or server's file system */
+ pthread_mutex_t fs_num_files_lock; /* lock for fs_num_act_files */
filesetentry_t *fs_filelist; /* List of files */
filesetentry_t *fs_dirlist; /* List of directories */
filesetentry_t *fs_filefree; /* Ptr to next free file */
diff --git a/usr/src/cmd/filebench/common/flowop.c b/usr/src/cmd/filebench/common/flowop.c
index 4aa46166c3..b75222cb23 100644
--- a/usr/src/cmd/filebench/common/flowop.c
+++ b/usr/src/cmd/filebench/common/flowop.c
@@ -324,6 +324,9 @@ 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 */
@@ -459,7 +462,7 @@ flowop_start(threadflow_t *threadflow)
}
/* Take it easy until everyone is ready to go */
- if (!filebench_shm->shm_running) {
+ if (!filebench_shm->shm_procs_running) {
(void) sleep(1);
continue;
}
@@ -896,7 +899,7 @@ flowop_find(char *name)
/*
* Returns a pointer to the specified instance of flowop
- * "name" from the supplied list.
+ * "name" from the global list.
*/
flowop_t *
flowop_find_one(char *name, int instance)
@@ -923,6 +926,86 @@ flowop_find_one(char *name, int instance)
}
/*
+ * 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.
*/
diff --git a/usr/src/cmd/filebench/common/flowop.h b/usr/src/cmd/filebench/common/flowop.h
index 5d6c83810e..f04e9c55e6 100644
--- a/usr/src/cmd/filebench/common/flowop.h
+++ b/usr/src/cmd/filebench/common/flowop.h
@@ -145,6 +145,7 @@ 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);
void flowoplib_usage(void);
void flowoplib_init(void);
void flowop_delete_all(flowop_t **threadlist);
diff --git a/usr/src/cmd/filebench/common/flowop_library.c b/usr/src/cmd/filebench/common/flowop_library.c
index d884e48b24..5baf108f19 100644
--- a/usr/src/cmd/filebench/common/flowop_library.c
+++ b/usr/src/cmd/filebench/common/flowop_library.c
@@ -1021,6 +1021,29 @@ flowoplib_eventlimit(threadflow_t *threadflow, flowop_t *flowop)
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
@@ -1042,12 +1065,33 @@ flowoplib_iopslimit(threadflow_t *threadflow, flowop_t *flowop)
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);
+ }
}
- (void) ipc_mutex_lock(&controlstats_lock);
- iops = (controlstats.fs_rcount +
- controlstats.fs_wcount);
- (void) ipc_mutex_unlock(&controlstats_lock);
+ 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) {
@@ -1109,11 +1153,19 @@ flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop)
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);
}
- (void) ipc_mutex_lock(&controlstats_lock);
- ops = controlstats.fs_count;
- (void) ipc_mutex_unlock(&controlstats_lock);
+ 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) {
@@ -1176,14 +1228,36 @@ flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop)
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);
+ }
}
- (void) ipc_mutex_lock(&controlstats_lock);
- bytes = (controlstats.fs_rbytes +
- controlstats.fs_wbytes);
- (void) ipc_mutex_unlock(&controlstats_lock);
+ 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 */
+ /* Is this the first time around? */
if (flowop->fo_tputlast == 0) {
flowop->fo_tputlast = bytes;
return (FILEBENCH_OK);
@@ -1240,15 +1314,40 @@ flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop)
static int
flowoplib_finishonbytes(threadflow_t *threadflow, flowop_t *flowop)
{
- uint64_t b;
- uint64_t bytes = flowop->fo_constvalue; /* use constant value */
+ 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);
+ }
+ }
- (void) ipc_mutex_lock(&controlstats_lock);
- b = controlstats.fs_bytes;
- (void) ipc_mutex_unlock(&controlstats_lock);
+ 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 (b > bytes) {
+ if (bytes_io > byte_lim) {
flowop_endop(threadflow, flowop, 0);
return (FILEBENCH_DONE);
}
@@ -1269,9 +1368,23 @@ flowoplib_finishoncount(threadflow_t *threadflow, flowop_t *flowop)
uint64_t ops;
uint64_t count = flowop->fo_constvalue; /* use constant value */
- (void) ipc_mutex_lock(&controlstats_lock);
- ops = controlstats.fs_count;
- (void) ipc_mutex_unlock(&controlstats_lock);
+ 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) {
@@ -1875,6 +1988,9 @@ flowoplib_deletefile(threadflow_t *threadflow, flowop_t *flowop)
(void) unlink(path);
flowop_endop(threadflow, flowop, 0);
file->fse_flags &= ~FSE_EXISTS;
+ (void) ipc_mutex_lock(&fileset->fs_num_files_lock);
+ fileset->fs_num_act_files--;
+ (void) ipc_mutex_unlock(&fileset->fs_num_files_lock);
(void) ipc_mutex_unlock(&file->fse_lock);
filebench_log(LOG_DEBUG_SCRIPT, "deleted file %s", file->fse_path);
diff --git a/usr/src/cmd/filebench/common/ipc.c b/usr/src/cmd/filebench/common/ipc.c
index e7593787b8..577bda7eec 100644
--- a/usr/src/cmd/filebench/common/ipc.c
+++ b/usr/src/cmd/filebench/common/ipc.c
@@ -336,6 +336,8 @@ ipc_init(void)
ipc_mutexattr());
(void) pthread_mutex_init(&filebench_shm->shm_procflow_lock,
ipc_mutexattr());
+ (void) pthread_mutex_init(&filebench_shm->shm_procs_running_lock,
+ ipc_mutexattr());
(void) pthread_mutex_init(&filebench_shm->shm_threadflow_lock,
ipc_mutexattr());
(void) pthread_mutex_init(&filebench_shm->shm_flowop_lock,
diff --git a/usr/src/cmd/filebench/common/ipc.h b/usr/src/cmd/filebench/common/ipc.h
index 38d3a01202..9ce44394d5 100644
--- a/usr/src/cmd/filebench/common/ipc.h
+++ b/usr/src/cmd/filebench/common/ipc.h
@@ -87,6 +87,7 @@ typedef struct filebench_shm {
pthread_mutex_t shm_msg_lock;
pthread_mutex_t shm_malloc_lock;
pthread_mutex_t shm_ism_lock;
+ pthread_mutex_t shm_procs_running_lock; /* protects shm_procs_running */
pthread_rwlock_t shm_run_lock;
pthread_rwlock_t shm_flowop_find_lock;
@@ -119,7 +120,7 @@ typedef struct filebench_shm {
size_t shm_allocated;
caddr_t shm_addr;
char *shm_ptr;
- int shm_running;
+ int shm_procs_running;
int shm_f_abort;
int shm_rmode;
int shm_1st_err;
diff --git a/usr/src/cmd/filebench/common/misc.c b/usr/src/cmd/filebench/common/misc.c
index 8d834f4cc4..553d28bcee 100644
--- a/usr/src/cmd/filebench/common/misc.c
+++ b/usr/src/cmd/filebench/common/misc.c
@@ -341,8 +341,7 @@ filebench_shutdown(int error) {
filebench_log(LOG_DEBUG_IMPL, "Shutdown");
}
- if (filebench_shm->shm_running)
- procflow_shutdown();
+ procflow_shutdown();
(void) unlink("/tmp/filebench_shm");
ipc_ismdelete();
diff --git a/usr/src/cmd/filebench/common/procflow.c b/usr/src/cmd/filebench/common/procflow.c
index 0209871359..5cfe559802 100644
--- a/usr/src/cmd/filebench/common/procflow.c
+++ b/usr/src/cmd/filebench/common/procflow.c
@@ -332,10 +332,10 @@ procflow_exec(char *name, int instance)
"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;
- (void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
- filebench_shm->shm_running --;
- (void) ipc_mutex_unlock(&filebench_shm->shm_procflow_lock);
return (ret);
}
@@ -371,9 +371,21 @@ procflow_createnwait(void *nothing)
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 */
@@ -391,11 +403,6 @@ procflow_createnwait(void *nothing)
filebench_shutdown(1);
}
- /* nothing running, exit */
- if (filebench_shm->shm_running == 0) {
- filebench_shm->shm_f_abort = FILEBENCH_ABORT_RSRC;
- pthread_exit(0);
- }
}
/* NOTREACHED */
return (NULL);
@@ -507,7 +514,7 @@ procflow_delete(procflow_t *procflow, int wait_cnt)
#ifdef USE_PROCESS_MODEL
(void) kill(procflow->pf_pid, SIGKILL);
filebench_log(LOG_DEBUG_SCRIPT,
- "Had to kill process %s-%d %d!",
+ "procflow_delete: Had to kill process %s-%d %d!",
procflow->pf_name,
procflow->pf_instance,
procflow->pf_pid);
@@ -605,7 +612,9 @@ procflow_allstarted()
procflow = procflow->pf_next;
}
- filebench_shm->shm_running = running_procs;
+ (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);
@@ -620,6 +629,7 @@ procflow_allstarted()
* 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)
@@ -627,8 +637,16 @@ procflow_shutdown(void)
procflow_t *procflow = filebench_shm->shm_proclist;
int wait_cnt;
+ (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;
+ }
+ filebench_shm->shm_procs_running = 0;
+ (void) ipc_mutex_unlock(&filebench_shm->shm_procs_running_lock);
+
(void) ipc_mutex_lock(&filebench_shm->shm_procflow_lock);
- filebench_shm->shm_running = 0;
filebench_shm->shm_f_abort = 1;
wait_cnt = SHUTDOWN_WAIT_SECONDS;
diff --git a/usr/src/cmd/filebench/workloads/Makefile b/usr/src/cmd/filebench/workloads/Makefile
index d4a920c0f9..a056d540aa 100644
--- a/usr/src/cmd/filebench/workloads/Makefile
+++ b/usr/src/cmd/filebench/workloads/Makefile
@@ -58,6 +58,7 @@ WORKLOADS = \
randomread.f \
randomrw.f \
randomwrite.f \
+ ratelimcopyfiles.f \
singlestreamread.f \
singlestreamreaddirect.f \
singlestreamwrite.f \
diff --git a/usr/src/cmd/filebench/workloads/bringover.f b/usr/src/cmd/filebench/workloads/bringover.f
index a889cb49ad..6e1aaff7c2 100644
--- a/usr/src/cmd/filebench/workloads/bringover.f
+++ b/usr/src/cmd/filebench/workloads/bringover.f
@@ -32,9 +32,9 @@ set $filesize=16k
set $iosize=1m
set $nthreads=1
-set mode quit alldone
+set mode quit firstdone
-define fileset name=srcfiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc
+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
@@ -50,8 +50,8 @@ define process name=filereader,instances=1
}
}
-echo "Bringover Version 2.3 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
+echo "Bringover Version 2.4 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"
diff --git a/usr/src/cmd/filebench/workloads/copyfiles.f b/usr/src/cmd/filebench/workloads/copyfiles.f
index a47cb8f46f..fa77ddd3f6 100644
--- a/usr/src/cmd/filebench/workloads/copyfiles.f
+++ b/usr/src/cmd/filebench/workloads/copyfiles.f
@@ -31,9 +31,9 @@ set $filesize=16k
set $iosize=1m
set $nthreads=1
-set mode quit alldone
+set mode quit firstdone
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc=100
+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
@@ -49,8 +49,8 @@ define process name=filereader,instances=1
}
}
-echo "CopyFiles Version 2.3 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
+echo "CopyFiles Version 2.4 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"
diff --git a/usr/src/cmd/filebench/workloads/createfiles.f b/usr/src/cmd/filebench/workloads/createfiles.f
index 198ecf3bfe..5905f6308e 100644
--- a/usr/src/cmd/filebench/workloads/createfiles.f
+++ b/usr/src/cmd/filebench/workloads/createfiles.f
@@ -31,7 +31,7 @@ set $filesize=16k
set $iosize=1m
set $nthreads=16
-set mode quit alldone
+set mode quit firstdone
define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth
@@ -46,8 +46,8 @@ define process name=filecreate,instances=1
}
}
-echo "Createfiles Version 2.3 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
+echo "Createfiles Version 2.4 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"
diff --git a/usr/src/cmd/filebench/workloads/deletefiles.f b/usr/src/cmd/filebench/workloads/deletefiles.f
index 5a75d1d2f8..4870c4732c 100644
--- a/usr/src/cmd/filebench/workloads/deletefiles.f
+++ b/usr/src/cmd/filebench/workloads/deletefiles.f
@@ -30,9 +30,9 @@ set $meandirwidth=100
set $filesize=16k
set $nthreads=16
-set mode quit alldone
+set mode quit firstdone
-define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100
+define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100,paralloc
define process name=filedelete,instances=1
{
@@ -43,8 +43,8 @@ define process name=filedelete,instances=1
}
}
-echo "Deletefiles Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
+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"
diff --git a/usr/src/cmd/filebench/workloads/filemicro_delete.f b/usr/src/cmd/filebench/workloads/filemicro_delete.f
index c9cceabf11..206710fd11 100644
--- a/usr/src/cmd/filebench/workloads/filemicro_delete.f
+++ b/usr/src/cmd/filebench/workloads/filemicro_delete.f
@@ -36,7 +36,7 @@ set $nfiles=5000
set $meandirwidth=100
set $nthreads=16
-set mode quit alldone
+set mode quit firstdone
define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100,paralloc
@@ -50,8 +50,8 @@ define process name=filedelete,instances=1
}
}
-echo "FileMicro-Delete Version 2.3 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
+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"
diff --git a/usr/src/cmd/filebench/workloads/mongo.f b/usr/src/cmd/filebench/workloads/mongo.f
index fd9907de1f..f6d7ec6f2d 100644
--- a/usr/src/cmd/filebench/workloads/mongo.f
+++ b/usr/src/cmd/filebench/workloads/mongo.f
@@ -32,10 +32,10 @@ set $nthreads=1
set $meaniosize=16k
set $readiosize=1m
-set mode quit alldone
+set mode quit firstdone
-define fileset name=postset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc
-define fileset name=postsetdel,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc
+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
{
@@ -51,8 +51,8 @@ define process name=filereader,instances=1
}
}
-echo "Mongo-like Version 2.2 personality successfully loaded"
-usage "Usage: set \$dir=<dir>"
+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"
diff --git a/usr/src/cmd/filebench/workloads/ratelimcopyfiles.f b/usr/src/cmd/filebench/workloads/ratelimcopyfiles.f
new file mode 100644
index 0000000000..1b23cbd583
--- /dev/null
+++ b/usr/src/cmd/filebench/workloads/ratelimcopyfiles.f
@@ -0,0 +1,72 @@
+#
+# 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"
+
+# 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. Note that you do have to enable the event
+# generator for any of the rate limiting flowops to take effect, for example
+# by typing:
+# eventget rate=10
+# at the go_filebench prompt to get ten events per second.
+#
+set $dir=/tmp
+set $dirwidth=20
+set $filesize=16k
+set $iosize=1m
+set $nfiles=1000
+set $nthreads=1
+
+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.0 personality successfully loaded"
+usage "Usage: set \$dir=<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/pkgdefs/SUNWfilebench/prototype_com b/usr/src/pkgdefs/SUNWfilebench/prototype_com
index 8415be41e5..d6d4d67ee6 100644
--- a/usr/src/pkgdefs/SUNWfilebench/prototype_com
+++ b/usr/src/pkgdefs/SUNWfilebench/prototype_com
@@ -80,6 +80,7 @@ f none usr/benchmarks/filebench/workloads/oltp.f 444 root bin
f none usr/benchmarks/filebench/workloads/randomread.f 444 root bin
f none usr/benchmarks/filebench/workloads/randomrw.f 444 root bin
f none usr/benchmarks/filebench/workloads/randomwrite.f 444 root bin
+f none usr/benchmarks/filebench/workloads/ratelimcopyfiles.f 444 root bin
f none usr/benchmarks/filebench/workloads/singlestreamread.f 444 root bin
f none usr/benchmarks/filebench/workloads/singlestreamreaddirect.f 444 root bin
f none usr/benchmarks/filebench/workloads/singlestreamwrite.f 444 root bin