diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/filebench/common/filebench.h | 13 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/flowop.c | 144 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/flowop.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/flowop_library.c | 407 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/ipc.c | 5 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/ipc.h | 14 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/misc.c | 22 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/misc.h | 11 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/parser_gram.y | 134 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/parser_lex.l | 6 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/procflow.c | 74 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/stats.c | 17 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/threadflow.c | 56 | ||||
-rw-r--r-- | usr/src/cmd/filebench/common/threadflow.h | 4 | ||||
-rw-r--r-- | usr/src/cmd/filebench/workloads/bringover.f | 9 | ||||
-rw-r--r-- | usr/src/cmd/filebench/workloads/copyfiles.f | 9 | ||||
-rw-r--r-- | usr/src/cmd/filebench/workloads/createfiles.f | 8 | ||||
-rw-r--r-- | usr/src/cmd/filebench/workloads/deletefiles.f | 8 |
18 files changed, 577 insertions, 367 deletions
diff --git a/usr/src/cmd/filebench/common/filebench.h b/usr/src/cmd/filebench/common/filebench.h index 2dda765234..ae710b587b 100644 --- a/usr/src/cmd/filebench/common/filebench.h +++ b/usr/src/cmd/filebench/common/filebench.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,7 +66,8 @@ extern "C" { #endif -extern pid_t pid; +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 int noproc; @@ -102,11 +103,17 @@ int filebench_randomno64(uint64_t *, uint64_t, uint64_t); #define MIN(x, y) ((x) < (y) ? (x) : (y)) #endif -#define FILEBENCH_VERSION "1.1.0" +#define FILEBENCH_VERSION "1.1.1" #define FILEBENCHDIR "/usr/benchmarks/filebench" #define FILEBENCH_PROMPT "filebench> " #define MAX_LINE_LEN 1024 #define MAX_CMD_HIST 128 +#define SHUTDOWN_WAIT_SECONDS 5 /* 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 diff --git a/usr/src/cmd/filebench/common/flowop.c b/usr/src/cmd/filebench/common/flowop.c index 9f4c7e00c4..4140234377 100644 --- a/usr/src/cmd/filebench/common/flowop.c +++ b/usr/src/cmd/filebench/common/flowop.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -87,7 +87,7 @@ flowop_beginop(threadflow_t *threadflow, flowop_t *flowop) char procname[128]; (void) snprintf(procname, sizeof (procname), - "/proc/%d/lwp/%d/lwpusage", pid, _lwp_self()); + "/proc/%d/lwp/%d/lwpusage", my_pid, _lwp_self()); threadflow->tf_lwpusagefd = open(procname, O_RDONLY); } @@ -192,6 +192,45 @@ flowop_initflow(flowop_t *flowop) } /* + * 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; + + (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_ops; + threadflow->tf_running = 0; + (void) ipc_mutex_unlock(&threadflow->tf_lock); + + while (flowop) { + flowop_destructflow(flowop); + flowop = flowop->fo_threadnext; + } +} + +/* * 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 @@ -210,8 +249,6 @@ flowop_start(threadflow_t *threadflow) size_t memsize; int ret = 0; - pid = getpid(); - #ifdef HAVE_PROCFS if (noproc == 0) { char procname[128]; @@ -219,7 +256,7 @@ flowop_start(threadflow_t *threadflow) int pfd; (void) snprintf(procname, sizeof (procname), - "/proc/%d/lwp/%d/lwpctl", pid, _lwp_self()); + "/proc/%d/lwp/%d/lwpctl", my_pid, _lwp_self()); pfd = open(procname, O_WRONLY); (void) pwrite(pfd, &ctl, sizeof (ctl), 0); (void) close(pfd); @@ -303,12 +340,8 @@ flowop_start(threadflow_t *threadflow) int i; /* Abort if asked */ - if (threadflow->tf_abort || filebench_shm->f_abort) { - (void) ipc_mutex_lock(&threadflow->tf_lock); - threadflow->tf_running = 0; - (void) ipc_mutex_unlock(&threadflow->tf_lock); + if (threadflow->tf_abort || filebench_shm->f_abort) break; - } /* Be quiet while stats are gathered */ if (filebench_shm->bequiet) { @@ -317,7 +350,7 @@ flowop_start(threadflow_t *threadflow) } /* Take it easy until everyone is ready to go */ - if (!filebench_shm->allrunning) + if (!filebench_shm->shm_running) (void) sleep(1); if (flowop->fo_stats.fs_stime == 0) @@ -328,13 +361,6 @@ flowop_start(threadflow_t *threadflow) return; } - if (threadflow->tf_memsize == 0) { - filebench_log(LOG_ERROR, - "Zero memory size for thread %s", - threadflow->tf_name); - return; - } - filebench_log(LOG_DEBUG_SCRIPT, "%s: executing flowop %s-%d", threadflow->tf_name, flowop->fo_name, flowop->fo_instance); @@ -348,30 +374,62 @@ flowop_start(threadflow_t *threadflow) "%s-%d", threadflow->tf_name, flowop->fo_name, flowop->fo_instance); - /* Return value > 0 means "stop the filebench run" */ - if (ret > 0) { - filebench_log(LOG_VERBOSE, - "%s: exiting flowop %s-%d", - threadflow->tf_name, flowop->fo_name, + /* + * 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->f_abort = 1; - threadflow->tf_running = 0; + filebench_shm->f_abort = FILEBENCH_ABORT_ERROR; (void) ipc_mutex_unlock(&threadflow->tf_lock); break; } + /* - * Return value < 0 means "flowop failed, stop the - * filebench run" + * Return value of FILEBENCH_NORSC means "stop + * the filebench run" if in "end on no work mode", + * otherwise it indicates an error */ - if (ret < 0) { - filebench_log(LOG_ERROR, "flowop %s failed", - flowop->fo_name); + if (ret == FILEBENCH_NORSC) { (void) ipc_mutex_lock(&threadflow->tf_lock); - threadflow->tf_abort = 1; - filebench_shm->f_abort = 1; - threadflow->tf_running = 0; + threadflow->tf_abort = FILEBENCH_DONE; + if (filebench_shm->shm_rmode == + FILEBENCH_MODE_Q1STDONE) { + filebench_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->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->f_abort = FILEBENCH_ABORT_DONE; (void) ipc_mutex_unlock(&threadflow->tf_lock); break; } @@ -392,7 +450,10 @@ flowop_start(threadflow_t *threadflow) _lwp_self()); #endif - pthread_exit(&ret); + /* Tell flowops to destroy locally acquired state */ + flowop_destruct_all_flows(threadflow); + + pthread_exit(&threadflow->tf_abort); } void @@ -402,19 +463,7 @@ flowop_init(void) } /* - * Calls the flowop's destruct function, pointed to by - * flowop->fo_destruct. - */ -static void -flowop_destructflow(flowop_t *flowop) -{ - (*flowop->fo_destruct)(flowop); -} - -/* * Delete the designated flowop from the thread's flowop list. - * After removal from the list, the flowop is destroyed with - * flowop_destructflow(). */ static void flowop_delete(flowop_t **flowoplist, flowop_t *flowop) @@ -457,9 +506,6 @@ flowop_delete(flowop_t **flowoplist, flowop_t *flowop) } } - /* Call destructor */ - flowop_destructflow(flowop); - #ifdef HAVE_PROCFS /* Close /proc stats */ if (flowop->fo_thread) diff --git a/usr/src/cmd/filebench/common/flowop.h b/usr/src/cmd/filebench/common/flowop.h index eeb31d1d99..8aa9b33440 100644 --- a/usr/src/cmd/filebench/common/flowop.h +++ b/usr/src/cmd/filebench/common/flowop.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -136,6 +136,7 @@ void flowoplib_init(void); 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); #ifdef __cplusplus } diff --git a/usr/src/cmd/filebench/common/flowop_library.c b/usr/src/cmd/filebench/common/flowop_library.c index 15c6fc003e..3124be54b9 100644 --- a/usr/src/cmd/filebench/common/flowop_library.c +++ b/usr/src/cmd/filebench/common/flowop_library.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -99,6 +99,7 @@ static int flowoplib_init_generic(flowop_t *flowop); static void flowoplib_destruct_generic(flowop_t *flowop); +static void flowoplib_destruct_noop(flowop_t *flowop); static int flowoplib_fdnum(threadflow_t *threadflow, flowop_t *flowop); static int flowoplib_write(threadflow_t *threadflow, flowop_t *flowop); #ifdef HAVE_AIO @@ -162,7 +163,7 @@ static flowoplib_t flowoplib_funcs[] = { 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_generic, + flowoplib_sempost, flowoplib_destruct_noop, FLOW_TYPE_OTHER, 0, "hog", flowoplib_init_generic, flowoplib_hog, flowoplib_destruct_generic, FLOW_TYPE_OTHER, 0, "delay", flowoplib_init_generic, @@ -242,16 +243,31 @@ static int flowoplib_init_generic(flowop_t *flowop) { (void) ipc_mutex_unlock(&flowop->fo_lock); - return (0); + return (FILEBENCH_OK); } -/* ARGSUSED */ static void flowoplib_destruct_generic(flowop_t *flowop) { - /* release any resources held by the flowop */ - if (flowop->fo_buf) - free(flowop->fo_buf); + 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); +} + +/* + * Special total noop destruct + */ +/* ARGSUSED */ +static void +flowoplib_destruct_noop(flowop_t *flowop) +{ } /* @@ -309,7 +325,7 @@ flowoplib_fdnum(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "Out of file descriptors in flowop %s" " (too many files : %d", flowop->fo_name, *(flowop->fo_fileset->fs_entries)); - return (-1); + return (FILEBENCH_ERROR); } /* First time around */ @@ -331,7 +347,9 @@ flowoplib_fdnum(threadflow_t *threadflow, flowop_t *flowop) /* * Determines the file descriptor to use, and attempts to open * the file if it is not already open. Also determines the wss - * value. Returns -1 on errors, 0 otherwise. + * 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, @@ -340,12 +358,14 @@ flowoplib_filesetup(threadflow_t *threadflow, flowop_t *flowop, int fd = flowoplib_fdnum(threadflow, flowop); if (fd == -1) - return (-1); + return (FILEBENCH_ERROR); if (threadflow->tf_fd[fd] == 0) { - if (flowoplib_openfile_common( - threadflow, flowop, fd) == -1) - return (-1); + 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", @@ -369,12 +389,12 @@ flowoplib_filesetup(threadflow_t *threadflow, flowop_t *flowop, *wssp = *flowop->fo_wss; } - return (0); + return (FILEBENCH_OK); } /* * Determines the io buffer or random offset into tf_mem for - * the IO operation. Returns -1 on errors, 0 otherwise. + * the IO operation. Returns FILEBENCH_ERROR on errors, FILEBENCH_OK otherwise. */ static int flowoplib_iobufsetup(threadflow_t *threadflow, flowop_t *flowop, @@ -386,7 +406,7 @@ flowoplib_iobufsetup(threadflow_t *threadflow, flowop_t *flowop, if (iosize == 0) { filebench_log(LOG_ERROR, "zero iosize for thread %s", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } if ((memsize = *threadflow->tf_memsize) != 0) { @@ -396,7 +416,7 @@ flowoplib_iobufsetup(threadflow_t *threadflow, flowop_t *flowop, filebench_log(LOG_ERROR, "tf_memsize smaller than IO size for thread %s", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } *iobufp = threadflow->tf_mem + memoffset; @@ -409,30 +429,34 @@ flowoplib_iobufsetup(threadflow_t *threadflow, flowop_t *flowop, } if ((flowop->fo_buf == NULL) && ((flowop->fo_buf = (char *)malloc(iosize)) == NULL)) - return (-1); + return (FILEBENCH_ERROR); flowop->fo_buf_size = iosize; *iobufp = flowop->fo_buf; } - return (0); + 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 -1 on errors, 0 otherwise. + * value. Returns FILEBENCH_ERROR on errors, FILEBENCH_OK otherwise. */ static int flowoplib_iosetup(threadflow_t *threadflow, flowop_t *flowop, vinteger_t *wssp, caddr_t *iobufp, int *filedescp, vinteger_t iosize) { - if (flowoplib_filesetup(threadflow, flowop, wssp, filedescp) == -1) - return (-1); + int ret; + + if ((ret = flowoplib_filesetup(threadflow, flowop, wssp, filedescp)) != + FILEBENCH_OK) + return (ret); - if (flowoplib_iobufsetup(threadflow, flowop, iobufp, iosize) == -1) - return (-1); + if ((ret = flowoplib_iobufsetup(threadflow, flowop, iobufp, iosize)) != + FILEBENCH_OK) + return (ret); - return (0); + return (FILEBENCH_OK); } /* @@ -440,15 +464,16 @@ flowoplib_iosetup(threadflow_t *threadflow, flowop_t *flowop, * 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 -1 + * 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, -1 is returned, if successful, - * 0 is returned. + * 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) @@ -458,9 +483,9 @@ flowoplib_read(threadflow_t *threadflow, flowop_t *flowop) int filedesc; int ret; - if (flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, - &filedesc, *flowop->fo_iosize) != 0) - return (-1); + if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, + &filedesc, *flowop->fo_iosize)) != FILEBENCH_OK) + return (ret); if (*flowop->fo_random) { uint64_t fileoffset; @@ -470,7 +495,7 @@ flowoplib_read(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "file size smaller than IO size for thread %s", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } (void) flowop_beginop(threadflow, flowop); @@ -483,7 +508,7 @@ flowoplib_read(threadflow_t *threadflow, flowop_t *flowop) flowop->fo_fileset->fs_name, fileoffset, iobuf, strerror(errno)); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } (void) flowop_endop(threadflow, flowop, ret); @@ -499,7 +524,7 @@ flowoplib_read(threadflow_t *threadflow, flowop_t *flowop) flowop->fo_fileset->fs_name, iobuf, strerror(errno)); (void) flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } (void) flowop_endop(threadflow, flowop, ret); @@ -507,7 +532,7 @@ flowoplib_read(threadflow_t *threadflow, flowop_t *flowop) (void) lseek64(filedesc, 0, SEEK_SET); } - return (0); + return (FILEBENCH_OK); } #ifdef HAVE_AIO @@ -551,9 +576,9 @@ aio_allocate(flowop_t *flowop) /* * Searches for the aiolist element that has a matching - * completion block, aiocb. If none found returns -1. If + * completion block, aiocb. If none found returns FILEBENCH_ERROR. If * found, removes the aiolist element from flowop thread's - * list and returns 0. + * list and returns FILEBENCH_OK. */ static int aio_deallocate(flowop_t *flowop, struct aiocb64 *aiocb) @@ -564,7 +589,7 @@ aio_deallocate(flowop_t *flowop, struct aiocb64 *aiocb) if (aiocb == NULL) { filebench_log(LOG_ERROR, "null aiocb deallocate"); - return (0); + return (FILEBENCH_OK); } while (aiolist) { @@ -577,7 +602,7 @@ aio_deallocate(flowop_t *flowop, struct aiocb64 *aiocb) } if (match == NULL) - return (-1); + return (FILEBENCH_ERROR); /* Remove from the list */ if (previous) @@ -585,7 +610,7 @@ aio_deallocate(flowop_t *flowop, struct aiocb64 *aiocb) else flowop->fo_thread->tf_aiolist = match->al_next; - return (0); + return (FILEBENCH_OK); } /* @@ -594,8 +619,10 @@ aio_deallocate(flowop_t *flowop, struct aiocb64 *aiocb) * 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 0 - * on success, -1 on any encountered error. + * 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 flowoplib_aiowrite(threadflow_t *threadflow, flowop_t *flowop) @@ -603,10 +630,11 @@ flowoplib_aiowrite(threadflow_t *threadflow, flowop_t *flowop) caddr_t iobuf; vinteger_t wss; int filedesc; + int ret; - if (flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, - &filedesc, *flowop->fo_iosize) != 0) - return (-1); + if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, + &filedesc, *flowop->fo_iosize)) != FILEBENCH_OK) + return (ret); if (*flowop->fo_random) { uint64_t fileoffset; @@ -618,7 +646,7 @@ flowoplib_aiowrite(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "file size smaller than IO size for thread %s", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } aiolist = aio_allocate(flowop); @@ -643,10 +671,10 @@ flowoplib_aiowrite(threadflow_t *threadflow, flowop_t *flowop) } flowop_endop(threadflow, flowop, *flowop->fo_iosize); } else { - return (-1); + return (FILEBENCH_ERROR); } - return (0); + return (FILEBENCH_OK); } @@ -720,7 +748,7 @@ flowoplib_aiowait(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "Could not remove " "aio from list "); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } } @@ -752,7 +780,7 @@ flowoplib_aiowait(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "Could not remove aio " "from list "); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } } @@ -769,7 +797,7 @@ flowoplib_aiowait(threadflow_t *threadflow, flowop_t *flowop) free(worklist); - return (0); + return (FILEBENCH_OK); } #endif /* HAVE_AIO */ @@ -786,7 +814,7 @@ flowoplib_block_init(flowop_t *flowop) (void) pthread_cond_init(&flowop->fo_cv, ipc_condattr()); (void) ipc_mutex_unlock(&flowop->fo_lock); - return (0); + return (FILEBENCH_OK); } /* @@ -809,7 +837,7 @@ flowoplib_block(threadflow_t *threadflow, flowop_t *flowop) (void) ipc_mutex_unlock(&flowop->fo_lock); - return (0); + return (FILEBENCH_OK); } /* @@ -820,7 +848,7 @@ flowoplib_block(threadflow_t *threadflow, flowop_t *flowop) * 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 0. + * are found. Otherwise the routine always returns FILEBENCH_OK. */ static int flowoplib_wakeup(threadflow_t *threadflow, flowop_t *flowop) @@ -869,7 +897,7 @@ flowoplib_wakeup(threadflow_t *threadflow, flowop_t *flowop) target = target->fo_targetnext; } - return (0); + return (FILEBENCH_OK); } /* @@ -898,7 +926,7 @@ flowoplib_hog(threadflow_t *threadflow, flowop_t *flowop) } flowop_endop(threadflow, flowop, 0); filebench_log(LOG_DEBUG_IMPL, "hog exit"); - return (0); + return (FILEBENCH_OK); } @@ -913,7 +941,7 @@ flowoplib_delay(threadflow_t *threadflow, flowop_t *flowop) flowop_beginop(threadflow, flowop); (void) sleep(value); flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } /* @@ -938,7 +966,7 @@ flowoplib_eventlimit(threadflow_t *threadflow, flowop_t *flowop) { /* Immediately bail if not set/enabled */ if (filebench_shm->eventgen_hz == 0) - return (0); + return (FILEBENCH_OK); if (flowop->fo_initted == 0) { filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking", @@ -959,14 +987,14 @@ flowoplib_eventlimit(threadflow_t *threadflow, flowop_t *flowop) (void) ipc_mutex_unlock(&filebench_shm->eventgen_lock); } flowop_endop(threadflow, flowop, 0); - return (0); + 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 0. + * specified by eventgen_hz. Always returns FILEBENCH_OK. */ static int flowoplib_iopslimit(threadflow_t *threadflow, flowop_t *flowop) @@ -977,7 +1005,7 @@ flowoplib_iopslimit(threadflow_t *threadflow, flowop_t *flowop) /* Immediately bail if not set/enabled */ if (filebench_shm->eventgen_hz == 0) - return (0); + return (FILEBENCH_OK); if (flowop->fo_initted == 0) { filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking", @@ -991,7 +1019,7 @@ flowoplib_iopslimit(threadflow_t *threadflow, flowop_t *flowop) /* Is this the first time around */ if (flowop->fo_tputlast == 0) { flowop->fo_tputlast = iops; - return (0); + return (FILEBENCH_OK); } delta = iops - flowop->fo_tputlast; @@ -1001,7 +1029,7 @@ flowoplib_iopslimit(threadflow_t *threadflow, flowop_t *flowop) /* No need to block if the q isn't empty */ if (flowop->fo_tputbucket >= 0LL) { flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } iops = flowop->fo_tputbucket * -1; @@ -1023,14 +1051,14 @@ flowoplib_iopslimit(threadflow_t *threadflow, flowop_t *flowop) } flowop_endop(threadflow, flowop, 0); - return (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 0. + * eventgen_hz. Always returns FILEBENCH_OK. */ static int flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop) @@ -1041,7 +1069,7 @@ flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop) /* Immediately bail if not set/enabled */ if (filebench_shm->eventgen_hz == 0) - return (0); + return (FILEBENCH_OK); if (flowop->fo_initted == 0) { filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking", @@ -1054,7 +1082,7 @@ flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop) /* Is this the first time around */ if (flowop->fo_tputlast == 0) { flowop->fo_tputlast = ops; - return (0); + return (FILEBENCH_OK); } delta = ops - flowop->fo_tputlast; @@ -1064,7 +1092,7 @@ flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop) /* No need to block if the q isn't empty */ if (flowop->fo_tputbucket >= 0LL) { flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } ops = flowop->fo_tputbucket * -1; @@ -1085,7 +1113,7 @@ flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop) } flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } @@ -1094,7 +1122,7 @@ flowoplib_opslimit(threadflow_t *threadflow, flowop_t *flowop) * 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 0. + * Always retuns FILEBENCH_OK. */ static int flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop) @@ -1105,7 +1133,7 @@ flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop) /* Immediately bail if not set/enabled */ if (filebench_shm->eventgen_hz == 0) - return (0); + return (FILEBENCH_OK); if (flowop->fo_initted == 0) { filebench_log(LOG_DEBUG_IMPL, "rate %zx %s-%d locking", @@ -1119,7 +1147,7 @@ flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop) /* Is this the first time around */ if (flowop->fo_tputlast == 0) { flowop->fo_tputlast = bytes; - return (0); + return (FILEBENCH_OK); } delta = bytes - flowop->fo_tputlast; @@ -1129,7 +1157,7 @@ flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop) /* No need to block if the q isn't empty */ if (flowop->fo_tputbucket >= 0LL) { flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } bytes = flowop->fo_tputbucket * -1; @@ -1153,7 +1181,7 @@ flowoplib_bwlimit(threadflow_t *threadflow, flowop_t *flowop) } flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } /* @@ -1180,18 +1208,18 @@ flowoplib_finishonbytes(threadflow_t *threadflow, flowop_t *flowop) flowop_beginop(threadflow, flowop); if (b > bytes) { flowop_endop(threadflow, flowop, 0); - return (1); + return (FILEBENCH_DONE); } flowop_endop(threadflow, flowop, 0); - return (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 0 to - * continue running. + * 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) @@ -1202,13 +1230,13 @@ flowoplib_finishoncount(threadflow_t *threadflow, flowop_t *flowop) ops = controlstats.fs_count; flowop_beginop(threadflow, flowop); - if (ops > count) { + if (ops >= count) { flowop_endop(threadflow, flowop, 0); - return (1); + return (FILEBENCH_DONE); } flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } /* @@ -1225,8 +1253,8 @@ flowoplib_finishoncount(threadflow_t *threadflow, flowop_t *flowop) * 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 -1 if it cannot acquire a set of System V semphores - * or if the initial post to the semaphore set fails. Returns 0 + * 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 @@ -1254,7 +1282,7 @@ flowoplib_semblock_init(flowop_t *flowop) filebench_log(LOG_ERROR, "semblock init lookup %x failed: %s", filebench_shm->semkey, strerror(errno)); - return (-1); + return (FILEBENCH_ERROR); } if ((highwater = flowop->fo_semid_hw) == 0) @@ -1268,7 +1296,7 @@ flowoplib_semblock_init(flowop_t *flowop) if ((semop(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 (-1); + return (FILEBENCH_ERROR); } #else filebench_log(LOG_DEBUG_IMPL, @@ -1281,13 +1309,13 @@ flowoplib_semblock_init(flowop_t *flowop) if (!(*flowop->fo_blocking)) (void) ipc_mutex_unlock(&flowop->fo_lock); - return (0); + 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. Always returns 0. + * it is effectively just a no-op. */ static void flowoplib_semblock_destruct(flowop_t *flowop) @@ -1302,9 +1330,9 @@ flowoplib_semblock_destruct(flowop_t *flowop) /* * Attempts to pass a System V or posix semaphore as appropriate, - * and blocks if necessary. Returns -1 if a set of System V + * 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 0 on success. + * post to the semaphore set fails. Returns FILEBENCH_OK on success. */ static int flowoplib_semblock(threadflow_t *threadflow, flowop_t *flowop) @@ -1320,7 +1348,7 @@ flowoplib_semblock(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "lookup semop %x failed: %s", filebench_shm->semkey, strerror(errno)); - return (-1); + return (FILEBENCH_ERROR); } filebench_log(LOG_DEBUG_IMPL, @@ -1368,7 +1396,7 @@ flowoplib_semblock(threadflow_t *threadflow, flowop_t *flowop) for (i = 0; i < value; i++) { if (sem_wait(&flowop->fo_sem) == -1) { filebench_log(LOG_ERROR, "semop wait failed"); - return (-1); + return (FILEBENCH_ERROR); } } @@ -1376,13 +1404,11 @@ flowoplib_semblock(threadflow_t *threadflow, flowop_t *flowop) flowop->fo_name, flowop->fo_instance); #endif /* HAVE_SYSV_SEM */ - return (0); + return (FILEBENCH_OK); } /* - * Calls ipc_seminit(), and does so whether System V semaphores - * are available or not. Hence it will cause ipc_seminit to log errors - * if they are not. Always returns 0. + * Calls ipc_seminit(). Always returns FILEBENCH_OK. */ /* ARGSUSED */ static int @@ -1391,7 +1417,7 @@ flowoplib_sempost_init(flowop_t *flowop) #ifdef HAVE_SYSV_SEM ipc_seminit(); #endif /* HAVE_SYSV_SEM */ - return (0); + return (FILEBENCH_OK); } /* @@ -1467,7 +1493,7 @@ flowoplib_sempost(threadflow_t *threadflow, flowop_t *flowop) "lookup semop %x failed: %s", filebench_shm->semkey, strerror(errno)); - return (-1); + return (FILEBENCH_ERROR); } sbuf[0].sem_num = target->fo_semid_lw; @@ -1493,7 +1519,7 @@ flowoplib_sempost(threadflow_t *threadflow, flowop_t *flowop) #endif /* HAVE_SEMTIMEDOP */ filebench_log(LOG_ERROR, "semop post failed: %s", strerror(errno)); - return (-1); + return (FILEBENCH_ERROR); } filebench_log(LOG_DEBUG_IMPL, @@ -1509,7 +1535,7 @@ flowoplib_sempost(threadflow_t *threadflow, flowop_t *flowop) for (i = 0; i < value; i++) { if (sem_post(&target->fo_sem) == -1) { filebench_log(LOG_ERROR, "semop post failed"); - return (-1); + return (FILEBENCH_ERROR); } } @@ -1521,7 +1547,7 @@ flowoplib_sempost(threadflow_t *threadflow, flowop_t *flowop) } flowop_endop(threadflow, flowop, 0); - return (0); + return (FILEBENCH_OK); } @@ -1547,9 +1573,10 @@ flowoplib_sempost(threadflow_t *threadflow, flowop_t *flowop) /* * Emulates (and actually does) file open. Obtains a file descriptor - * index, then calls flowoplib_openfile_common() to open. Returns -1 - * if not file descriptor is found or flowoplib_openfile_common - * encounters an error, otherwise 0. + * 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) @@ -1557,7 +1584,7 @@ flowoplib_openfile(threadflow_t *threadflow, flowop_t *flowop) int fd = flowoplib_fdnum(threadflow, flowop); if (fd == -1) - return (-1); + return (FILEBENCH_ERROR); return (flowoplib_openfile_common(threadflow, flowop, fd)); } @@ -1570,7 +1597,9 @@ flowoplib_openfile(threadflow_t *threadflow, flowop_t *flowop) * 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 -1 on error, 0 on success. + * 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) @@ -1589,12 +1618,12 @@ flowoplib_openfile_common(threadflow_t *threadflow, flowop_t *flowop, int fd) filebench_log(LOG_ERROR, "flowop %s attempted to open without closing on fd %d", flowop->fo_name, fd); - return (-1); + return (FILEBENCH_ERROR); } if (flowop->fo_fileset == NULL) { filebench_log(LOG_ERROR, "flowop NULL file"); - return (-1); + return (FILEBENCH_ERROR); } #ifdef HAVE_RAW_SUPPORT @@ -1624,7 +1653,7 @@ flowoplib_openfile_common(threadflow_t *threadflow, flowop_t *flowop, int fd) filebench_log(LOG_ERROR, "Failed to open raw device %s: %s", name, strerror(errno)); - return (-1); + return (FILEBENCH_ERROR); } /* if running on Solaris, use un-buffered io */ @@ -1634,17 +1663,17 @@ flowoplib_openfile_common(threadflow_t *threadflow, flowop_t *flowop, int fd) threadflow->tf_fse[fd] = NULL; - return (0); + return (FILEBENCH_OK); } #endif /* HAVE_RAW_SUPPORT */ if ((file = fileset_pick(flowop->fo_fileset, FILESET_PICKEXISTS, tid)) == NULL) { - filebench_log(LOG_ERROR, + filebench_log(LOG_DEBUG_SCRIPT, "flowop %s failed to pick file from %s on fd %d", flowop->fo_name, flowop->fo_fileset->fs_name, fd); - return (-1); + return (FILEBENCH_NORSC); } threadflow->tf_fse[fd] = file; @@ -1657,14 +1686,14 @@ flowoplib_openfile_common(threadflow_t *threadflow, flowop_t *flowop, int fd) if (threadflow->tf_fd[fd] < 0) { filebench_log(LOG_ERROR, "failed to open file %s", flowop->fo_name); - return (-1); + 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 (0); + return (FILEBENCH_OK); } /* @@ -1674,10 +1703,10 @@ flowoplib_openfile_common(threadflow_t *threadflow, flowop_t *flowop, int fd) * 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 -1 if the array index specified by fdnumber is + * 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 0 on success. + * nonexistent file cannot be found. Returns FILEBENCH_OK on success. */ static int flowoplib_createfile(threadflow_t *threadflow, flowop_t *flowop) @@ -1689,12 +1718,12 @@ flowoplib_createfile(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "flowop %s attempted to create without closing on fd %d", flowop->fo_name, fd); - return (-1); + return (FILEBENCH_ERROR); } if (flowop->fo_fileset == NULL) { filebench_log(LOG_ERROR, "flowop NULL file"); - return (-1); + return (FILEBENCH_ERROR); } #ifdef HAVE_RAW_SUPPORT @@ -1703,15 +1732,16 @@ flowoplib_createfile(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "flowop %s attempted to a createfile on RAW device", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } #endif /* HAVE_RAW_SUPPORT */ if ((file = fileset_pick(flowop->fo_fileset, FILESET_PICKNOEXIST, 0)) == NULL) { - filebench_log(LOG_DEBUG_SCRIPT, "flowop %s failed to pick file", - flowop->fo_name); - return (1); + filebench_log(LOG_DEBUG_SCRIPT, + "flowop %s failed to pick file from fileset %s", + flowop->fo_name, flowop->fo_fileset->fs_name); + return (FILEBENCH_NORSC); } threadflow->tf_fse[fd] = file; @@ -1724,22 +1754,22 @@ flowoplib_createfile(threadflow_t *threadflow, flowop_t *flowop) if (threadflow->tf_fd[fd] < 0) { filebench_log(LOG_ERROR, "failed to create file %s", flowop->fo_name); - return (-1); + 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 (0); + return (FILEBENCH_OK); } /* * Emulates delete of a file. Picks an arbitrary filesetentry * whose file exists and uses unlink() to delete it. Clears - * the FSE_EXISTS flag for the filesetentry. Returns -1 if the - * flowop has no associated fileset. Returns 1 if an appropriate - * filesetentry cannot be found, and 0 on success. + * 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) @@ -1751,7 +1781,7 @@ flowoplib_deletefile(threadflow_t *threadflow, flowop_t *flowop) if (flowop->fo_fileset == NULL) { filebench_log(LOG_ERROR, "flowop NULL file"); - return (-1); + return (FILEBENCH_ERROR); } fileset = flowop->fo_fileset; @@ -1762,7 +1792,7 @@ flowoplib_deletefile(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "flowop %s attempted a deletefile on RAW device", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } #endif /* HAVE_RAW_SUPPORT */ @@ -1770,7 +1800,7 @@ flowoplib_deletefile(threadflow_t *threadflow, flowop_t *flowop) FILESET_PICKEXISTS, 0)) == NULL) { filebench_log(LOG_DEBUG_SCRIPT, "flowop %s failed to pick file", flowop->fo_name); - return (1); + return (FILEBENCH_NORSC); } *path = 0; @@ -1789,15 +1819,15 @@ flowoplib_deletefile(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_DEBUG_SCRIPT, "deleted file %s", file->fse_path); - return (0); + 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 -1 - * if the file no longer is open, 0 otherwise. + * 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) @@ -1809,7 +1839,7 @@ flowoplib_fsync(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "flowop %s attempted to fsync a closed fd %d", flowop->fo_name, fd); - return (-1); + return (FILEBENCH_ERROR); } file = threadflow->tf_fse[fd]; @@ -1819,7 +1849,7 @@ flowoplib_fsync(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "flowop %s attempted to a fsync a RAW device", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } /* Measure time to fsync */ @@ -1829,14 +1859,14 @@ flowoplib_fsync(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_DEBUG_SCRIPT, "fsync file %s", file->fse_path); - return (0); + 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 0. + * returns FILEBENCH_OK. */ static int flowoplib_fsyncset(threadflow_t *threadflow, flowop_t *flowop) @@ -1862,7 +1892,7 @@ flowoplib_fsyncset(threadflow_t *threadflow, flowop_t *flowop) file->fse_path); } - return (0); + return (FILEBENCH_OK); } /* @@ -1871,8 +1901,8 @@ flowoplib_fsyncset(threadflow_t *threadflow, flowop_t *flowop) * 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 -1 if the file was not open, - * 0 otherwise. + * 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) @@ -1884,7 +1914,7 @@ flowoplib_closefile(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "flowop %s attempted to close an already closed fd %d", flowop->fo_name, fd); - return (-1); + return (FILEBENCH_ERROR); } /* Measure time to close */ @@ -1899,15 +1929,15 @@ flowoplib_closefile(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_DEBUG_SCRIPT, "closed file %s", file->fse_path); - return (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 -1 if the flowop has no - * associated fileset. Returns 1 if an appropriate filesetentry - * cannot be found, and 0 on success. + * 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) @@ -1919,7 +1949,7 @@ flowoplib_statfile(threadflow_t *threadflow, flowop_t *flowop) if (flowop->fo_fileset == NULL) { filebench_log(LOG_ERROR, "flowop NULL file"); - return (-1); + return (FILEBENCH_ERROR); } fileset = flowop->fo_fileset; @@ -1928,7 +1958,7 @@ flowoplib_statfile(threadflow_t *threadflow, flowop_t *flowop) FILESET_PICKEXISTS, 0)) == NULL) { filebench_log(LOG_DEBUG_SCRIPT, "flowop %s failed to pick file", flowop->fo_name); - return (1); + return (FILEBENCH_NORSC); } *path = 0; @@ -1944,7 +1974,7 @@ flowoplib_statfile(threadflow_t *threadflow, flowop_t *flowop) (void) ipc_mutex_unlock(&file->fse_lock); - return (0); + return (FILEBENCH_OK); } @@ -1963,7 +1993,8 @@ flowoplib_statfile(threadflow_t *threadflow, flowop_t *flowop) * 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 -1 on error, 0 on success. + * 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) @@ -1977,15 +2008,16 @@ flowoplib_readwholefile(threadflow_t *threadflow, flowop_t *flowop) vinteger_t iosize = *flowop->fo_iosize; /* get the file to use */ - if (flowoplib_filesetup(threadflow, flowop, &wss, &filedesc) != 0) - return (-1); + if ((ret = flowoplib_filesetup(threadflow, flowop, &wss, + &filedesc)) != FILEBENCH_OK) + return (ret); /* an I/O size of zero means read entire working set with one I/O */ if (iosize == 0) iosize = wss; if (flowoplib_iobufsetup(threadflow, flowop, &iobuf, iosize) != 0) - return (-1); + return (FILEBENCH_ERROR); /* Measure time to read bytes */ flowop_beginop(threadflow, flowop); @@ -1999,10 +2031,10 @@ flowoplib_readwholefile(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "Failed to read fd %d: %s", fd, strerror(errno)); - return (-1); + return (FILEBENCH_ERROR); } - return (0); + return (FILEBENCH_OK); } /* @@ -2016,8 +2048,9 @@ flowoplib_readwholefile(threadflow_t *threadflow, flowop_t *flowop) * 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 1 on - * errors, 0 on success. + * 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) @@ -2025,10 +2058,11 @@ flowoplib_write(threadflow_t *threadflow, flowop_t *flowop) caddr_t iobuf; vinteger_t wss; int filedesc; + int ret; - if (flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, - &filedesc, *flowop->fo_iosize) != 0) - return (-1); + if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, + &filedesc, *flowop->fo_iosize)) != FILEBENCH_OK) + return (ret); if (*flowop->fo_random) { uint64_t fileoffset; @@ -2038,7 +2072,7 @@ flowoplib_write(threadflow_t *threadflow, flowop_t *flowop) filebench_log(LOG_ERROR, "file size smaller than IO size for thread %s", flowop->fo_name); - return (-1); + return (FILEBENCH_ERROR); } flowop_beginop(threadflow, flowop); if (pwrite64(filedesc, iobuf, @@ -2047,7 +2081,7 @@ flowoplib_write(threadflow_t *threadflow, flowop_t *flowop) "offset %lld io buffer %zd: %s", fileoffset, iobuf, strerror(errno)); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } flowop_endop(threadflow, flowop, *flowop->fo_iosize); } else { @@ -2058,12 +2092,12 @@ flowoplib_write(threadflow_t *threadflow, flowop_t *flowop) "write failed, io buffer %zd: %s", iobuf, strerror(errno)); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } flowop_endop(threadflow, flowop, *flowop->fo_iosize); } - return (0); + return (FILEBENCH_OK); } /* @@ -2071,8 +2105,8 @@ flowoplib_write(threadflow_t *threadflow, flowop_t *flowop) * 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 -1 on - * error, 0 on success. + * 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) @@ -2089,21 +2123,22 @@ flowoplib_writewholefile(threadflow_t *threadflow, flowop_t *flowop) vinteger_t iosize = *flowop->fo_iosize; /* get the file to use */ - if (flowoplib_filesetup(threadflow, flowop, &wss, &filedesc) != 0) - return (-1); + if ((ret = flowoplib_filesetup(threadflow, flowop, &wss, + &filedesc)) != FILEBENCH_OK) + return (ret); /* an I/O size of zero means read entire working set with one I/O */ if (iosize == 0) iosize = wss; if (flowoplib_iobufsetup(threadflow, flowop, &iobuf, iosize) != 0) - return (-1); + 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 (-1); + return (FILEBENCH_ERROR); } if (file) @@ -2120,14 +2155,14 @@ flowoplib_writewholefile(threadflow_t *threadflow, flowop_t *flowop) "Failed to write %d bytes on fd %d: %s", wsize, filedesc, strerror(errno)); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } wsize = (int)MIN(wss - seek, iosize); bytes += ret; } flowop_endop(threadflow, flowop, bytes); - return (0); + return (FILEBENCH_OK); } @@ -2144,7 +2179,8 @@ flowoplib_writewholefile(threadflow_t *threadflow, flowop_t *flowop) * 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 -1 on error, 0 on success. + * 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) @@ -2155,9 +2191,9 @@ flowoplib_appendfile(threadflow_t *threadflow, flowop_t *flowop) vinteger_t iosize = *flowop->fo_iosize; int ret; - if (flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, - &filedesc, iosize) != 0) - return (-1); + if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, + &filedesc, iosize)) != FILEBENCH_OK) + return (ret); /* XXX wss is not being used */ @@ -2170,11 +2206,11 @@ flowoplib_appendfile(threadflow_t *threadflow, flowop_t *flowop) "Failed to write %d bytes on fd %d: %s", iosize, filedesc, strerror(errno)); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } flowop_endop(threadflow, flowop, iosize); - return (0); + return (FILEBENCH_OK); } /* @@ -2190,7 +2226,8 @@ flowoplib_appendfile(threadflow_t *threadflow, flowop_t *flowop) * 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 -1 on error, 0 on success. + * 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) @@ -2199,21 +2236,21 @@ flowoplib_appendfilerand(threadflow_t *threadflow, flowop_t *flowop) uint64_t appendsize; int filedesc; vinteger_t wss; - int ret = 0; + int ret; if (filebench_randomno64(&appendsize, *flowop->fo_iosize, 1LL) != 0) - return (-1); + return (FILEBENCH_ERROR); /* skip if attempting zero length append */ if (appendsize == 0) { flowop_beginop(threadflow, flowop); flowop_endop(threadflow, flowop, 0LL); - return (0); + return (FILEBENCH_OK); } - if (flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, - &filedesc, appendsize) != 0) - return (-1); + if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf, + &filedesc, appendsize)) != FILEBENCH_OK) + return (ret); /* XXX wss is not being used */ @@ -2227,12 +2264,12 @@ flowoplib_appendfilerand(threadflow_t *threadflow, flowop_t *flowop) "Failed to write %d bytes on fd %d: %s", appendsize, filedesc, strerror(errno)); flowop_endop(threadflow, flowop, 0); - return (-1); + return (FILEBENCH_ERROR); } flowop_endop(threadflow, flowop, appendsize); - return (0); + return (FILEBENCH_OK); } diff --git a/usr/src/cmd/filebench/common/ipc.c b/usr/src/cmd/filebench/common/ipc.c index 19eeee5624..1311b4ab51 100644 --- a/usr/src/cmd/filebench/common/ipc.c +++ b/usr/src/cmd/filebench/common/ipc.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -322,7 +322,8 @@ ipc_init(void) (void) memset(filebench_shm, 0, c2 - c1); filebench_shm->epoch = gethrtime(); - filebench_shm->debug_level = 2; + filebench_shm->debug_level = LOG_VERBOSE; + filebench_shm->shm_rmode = FILEBENCH_MODE_TIMEOUT; filebench_shm->string_ptr = &filebench_shm->strings[0]; filebench_shm->shm_ptr = (char *)filebench_shm->shm_addr; filebench_shm->path_ptr = &filebench_shm->filesetpaths[0]; diff --git a/usr/src/cmd/filebench/common/ipc.h b/usr/src/cmd/filebench/common/ipc.h index 31a37b2005..8eed540c66 100644 --- a/usr/src/cmd/filebench/common/ipc.h +++ b/usr/src/cmd/filebench/common/ipc.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -69,6 +69,14 @@ extern "C" { #define FILEBENCH_NSEMS 128 +#define FILEBENCH_ABORT_ERROR 1 +#define FILEBENCH_ABORT_DONE 2 +#define FILEBENCH_ABORT_RSRC 3 + +#define FILEBENCH_MODE_TIMEOUT 0x0 +#define FILEBENCH_MODE_Q1STDONE 0x1 +#define FILEBENCH_MODE_QALLDONE 0x2 + typedef struct filebench_shm { pthread_mutex_t fileset_lock; pthread_mutex_t procflow_lock; @@ -108,8 +116,10 @@ typedef struct filebench_shm { size_t shm_allocated; caddr_t shm_addr; char *shm_ptr; - int allrunning; + int shm_running; int f_abort; + int shm_rmode; + int shm_1st_err; int marker; diff --git a/usr/src/cmd/filebench/common/misc.c b/usr/src/cmd/filebench/common/misc.c index 8c5b7e4a2f..e611e1e468 100644 --- a/usr/src/cmd/filebench/common/misc.c +++ b/usr/src/cmd/filebench/common/misc.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -331,6 +331,19 @@ __V((int level, const char *fmt, ...)) 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->debug_level)) @@ -376,7 +389,7 @@ fatal: } else if (filebench_shm->debug_level > LOG_INFO) { (void) fprintf(stdout, "%5d: %4.3f: %s", - (int)pid, (now - filebench_shm->epoch) / FSECS, + (int)my_pid, (now - filebench_shm->epoch) / FSECS, line); } else { (void) fprintf(stdout, "%4.3f: %s", @@ -385,7 +398,8 @@ fatal: } if (level == LOG_ERROR) { - (void) fprintf(stdout, " on line %d", lex_lineno); + if (my_procflow == NULL) + (void) fprintf(stdout, " on line %d", lex_lineno); } if ((level != LOG_LOG) && (level != LOG_DUMP)) { @@ -405,7 +419,7 @@ void filebench_shutdown(int error) { filebench_log(LOG_DEBUG_IMPL, "Shutdown"); (void) unlink("/tmp/filebench_shm"); - if (filebench_shm->allrunning) + if (filebench_shm->shm_running) procflow_shutdown(); filebench_shm->f_abort = 1; ipc_ismdelete(); diff --git a/usr/src/cmd/filebench/common/misc.h b/usr/src/cmd/filebench/common/misc.h index e330c0318f..31d64e2ec9 100644 --- a/usr/src/cmd/filebench/common/misc.h +++ b/usr/src/cmd/filebench/common/misc.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -51,15 +51,16 @@ uint64_t gethrtime(); #endif #define FSECS (double)1000000000.0 -#define LOG_INFO 1 -#define LOG_VERBOSE 2 -#define LOG_DEBUG_SCRIPT 3 -#define LOG_DEBUG_IMPL 5 +#define LOG_INFO 2 +#define LOG_VERBOSE 3 +#define LOG_DEBUG_SCRIPT 4 +#define LOG_DEBUG_IMPL 6 #define LOG_DEBUG_NEVER 10 #define LOG_LOG 1000 #define LOG_DUMP 1001 #define LOG_FATAL 999 #define LOG_ERROR 0 +#define LOG_ERROR1 1 var_t *date_var(var_t *var); var_t *script_var(var_t *var); diff --git a/usr/src/cmd/filebench/common/parser_gram.y b/usr/src/cmd/filebench/common/parser_gram.y index c1792e20f0..4a8a80de57 100644 --- a/usr/src/cmd/filebench/common/parser_gram.y +++ b/usr/src/cmd/filebench/common/parser_gram.y @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -157,7 +157,7 @@ static void parser_abort(int arg); %token FSV_STRING FSV_VAL_INT FSV_VAL_BOOLEAN FSV_VARIABLE FSV_WHITESTRING %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 +%token FSE_DIRECTORY FSE_COMMAND FSE_FILESET FSE_XMLDUMP FSE_MODE %token FSK_SEPLST FSK_OPENLST FSK_CLOSELST FSK_ASSIGN FSK_IN FSK_QUOTE %token FSK_DIRSEPLST %token FSA_SIZE FSA_PREALLOC FSA_PARALLOC FSA_PATH FSA_REUSE @@ -166,7 +166,7 @@ static void parser_abort(int arg); %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 -%token FSA_DIRGAMMA FSA_USEISM +%token FSA_DIRGAMMA FSA_USEISM FSA_ALLDONE FSA_FIRSTDONE FSA_TIMEOUT %type <ival> FSV_VAL_INT %type <bval> FSV_VAL_BOOLEAN @@ -684,6 +684,24 @@ set_command: FSC_SET FSV_VARIABLE FSK_ASSIGN FSV_VAL_INT 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; }; stats_command: FSC_STATS FSE_SNAP @@ -1180,26 +1198,26 @@ main(int argc, char *argv[]) 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) { - pid = getpid(); - + /* A child FileBench instance */ if (ipc_attach(shmaddr) < 0) { filebench_log(LOG_ERROR, "Cannot attach shm for %s", procname); exit(1); } - if (procflow_exec(procname, instance) < 0) { - filebench_log(LOG_ERROR, "Cannot startup process %s", - procname); + if (procflow_exec(procname, instance) < 0) exit(1); - } - exit(1); + + exit(0); } #endif - pid = getpid(); + /* master (or only) process */ ipc_init(); if (fscriptname) @@ -1917,6 +1935,7 @@ parser_fileset_define(cmd_t *cmd) static void parser_proc_create(cmd_t *cmd) { + filebench_shm->shm_1st_err = 0; if (procflow_init() != 0) { filebench_log(LOG_ERROR, "Failed to create processes\n"); filebench_shutdown(1); @@ -1993,27 +2012,36 @@ parser_filebench_shutdown(cmd_t *cmd) } /* - * Sleeps for cmd->cmd_qty seconds, one second at a time. + * 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 void -parser_sleep(cmd_t *cmd) +parser_pause(int ptime) { - int sleeptime; + int timeslept = 0; - /* check for startup errors */ - if (filebench_shm->f_abort) - return; - - sleeptime = cmd->cmd_qty; - filebench_log(LOG_INFO, "Running..."); - while (sleeptime) { - (void) sleep(1); - sleeptime--; - if (filebench_shm->f_abort) - break; + if ((filebench_shm->shm_rmode == FILEBENCH_MODE_TIMEOUT) && + (ptime > 0)) { + while (timeslept < ptime) { + (void) sleep(1); + timeslept++; + if (filebench_shm->f_abort) + break; + } + } else { + /* initial runtime of 0 means run till abort */ + /* CONSTCOND */ + while (1) { + (void) sleep(1); + timeslept++; + if (filebench_shm->f_abort) + break; + } } - filebench_log(LOG_INFO, "Run took %lld seconds...", - cmd->cmd_qty - sleeptime); + + filebench_log(LOG_INFO, "Run took %lld seconds...", timeslept); } /* @@ -2029,6 +2057,7 @@ parser_run(cmd_t *cmd) int runtime; runtime = cmd->cmd_qty; + parser_fileset_create(cmd); parser_proc_create(cmd); @@ -2038,14 +2067,9 @@ parser_run(cmd_t *cmd) filebench_log(LOG_INFO, "Running..."); stats_clear(); - while (runtime) { - (void) sleep(1); - runtime--; - if (filebench_shm->f_abort) - break; - } - filebench_log(LOG_INFO, "Run took %lld seconds...", - cmd->cmd_qty - runtime); + + parser_pause(runtime); + parser_statssnap(cmd); parser_proc_shutdown(cmd); } @@ -2074,15 +2098,11 @@ parser_run_variable(cmd_t *cmd) filebench_log(LOG_INFO, "Running..."); stats_clear(); - while (runtime) { - (void) sleep(1); - runtime--; - if (filebench_shm->f_abort) - break; - } - filebench_log(LOG_INFO, "Run took %lld seconds...", - *integer - runtime); + + parser_pause(runtime); + parser_statssnap(cmd); + parser_proc_shutdown(cmd); } char *usagestr = NULL; @@ -2161,6 +2181,24 @@ parser_vars(cmd_t *cmd) } /* + * Sleeps for cmd->cmd_qty seconds, one second at a time. + */ +static void +parser_sleep(cmd_t *cmd) +{ + int sleeptime; + + /* check for startup errors */ + if (filebench_shm->f_abort) + return; + + sleeptime = cmd->cmd_qty; + filebench_log(LOG_INFO, "Running..."); + + 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. */ @@ -2183,14 +2221,8 @@ parser_sleep_variable(cmd_t *cmd) return; filebench_log(LOG_INFO, "Running..."); - while (sleeptime) { - (void) sleep(1); - sleeptime--; - if (filebench_shm->f_abort) - break; - } - filebench_log(LOG_INFO, "Run took %lld seconds...", - *integer - sleeptime); + + parser_pause(sleeptime); } /* diff --git a/usr/src/cmd/filebench/common/parser_lex.l b/usr/src/cmd/filebench/common/parser_lex.l index 586179774e..78b3a94718 100644 --- a/usr/src/cmd/filebench/common/parser_lex.l +++ b/usr/src/cmd/filebench/common/parser_lex.l @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -97,6 +97,7 @@ snap { return FSE_SNAP; } dump { return FSE_DUMP; } xmldump { return FSE_XMLDUMP; } all { return FSE_ALL; } +mode { return FSE_MODE; } cached { return FSA_CACHED; } dirwidth { return FSA_DIRWIDTH; } @@ -132,6 +133,9 @@ value { return FSA_VALUE;} workingset { return FSA_WSS; } blocking { return FSA_BLOCKING; } highwater { return FSA_HIGHWATER; } +alldone { return FSA_ALLDONE; } +firstdone { return FSA_FIRSTDONE; } +timeout { return FSA_TIMEOUT; } <INITIAL>\" { BEGIN WHITESTRINGSTATE; diff --git a/usr/src/cmd/filebench/common/procflow.c b/usr/src/cmd/filebench/common/procflow.c index 0fd2700f0c..2a7e412c58 100644 --- a/usr/src/cmd/filebench/common/procflow.c +++ b/usr/src/cmd/filebench/common/procflow.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,8 +35,9 @@ #include "flowop.h" #include "ipc.h" -pid_t pid; -static int procflow_delete_wait_cnt = 0; +/* 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); @@ -135,6 +136,7 @@ procflow_createproc(procflow_t *procflow) } #endif /* HAVE_FORK1 */ + /* if child, start up new copy of filebench */ if (pid == 0) { #ifdef USE_SYSTEM char syscmd[1024]; @@ -170,6 +172,7 @@ procflow_createproc(procflow_t *procflow) #endif exit(1); } else { + /* if parent, save pid and return */ procflow->pf_pid = pid; } #else @@ -277,6 +280,7 @@ procflow_exec(char *name, int instance) #ifdef HAVE_SETRLIMIT struct rlimit rlp; #endif + int ret; filebench_log(LOG_DEBUG_IMPL, "procflow_execproc %s-%d", @@ -288,10 +292,15 @@ procflow_exec(char *name, int instance) name, instance); return (-1); } - procflow->pf_pid = pid; + + /* 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, pid); + "Started up %s pid %d", procflow->pf_name, my_pid); filebench_log(LOG_DEBUG_IMPL, "nice = %llx", procflow->pf_nice); @@ -308,18 +317,23 @@ procflow_exec(char *name, int instance) filebench_log(LOG_DEBUG_SCRIPT, "%d file descriptors", rlp.rlim_cur); #endif - if (threadflow_init(procflow) < 0) { - filebench_log(LOG_ERROR, - "Failed to start threads for %s pid %d", - procflow->pf_name, pid); - procflow->pf_running = 0; - exit(1); + 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..."); } - filebench_log(LOG_DEBUG_IMPL, "procflow_createproc exiting..."); + procflow->pf_running = 0; - exit(0); + (void) ipc_mutex_lock(&filebench_shm->procflow_lock); + filebench_shm->shm_running --; + (void) ipc_mutex_unlock(&filebench_shm->procflow_lock); - return (0); + return (ret); } @@ -373,8 +387,11 @@ procflow_createnwait(void *nothing) filebench_shutdown(1); } - if (filebench_shm->allrunning == 0) + /* nothing running, exit */ + if (filebench_shm->shm_running == 0) { + filebench_shm->f_abort = FILEBENCH_ABORT_RSRC; pthread_exit(0); + } } /* NOTREACHED */ return (NULL); @@ -454,11 +471,11 @@ procflow_wait(pid_t pid) * the procflow is not deleted. Otherwise it returns 0. */ static int -procflow_delete(procflow_t *procflow) +procflow_delete(procflow_t *procflow, int wait_cnt) { procflow_t *entry; - threadflow_delete_all(&procflow->pf_threads); + threadflow_delete_all(&procflow->pf_threads, wait_cnt); filebench_log(LOG_DEBUG_SCRIPT, "Deleted proc: (%s-%d) pid %d", @@ -473,11 +490,11 @@ procflow_delete(procflow_t *procflow) procflow->pf_instance, procflow->pf_pid); - if (procflow_delete_wait_cnt < 10) { + if (wait_cnt) { (void) ipc_mutex_unlock(&filebench_shm->procflow_lock); (void) sleep(1); (void) ipc_mutex_lock(&filebench_shm->procflow_lock); - procflow_delete_wait_cnt++; + wait_cnt--; continue; } #ifdef USE_PROCESS_MODEL @@ -534,6 +551,7 @@ int procflow_allstarted() { procflow_t *procflow = filebench_shm->proclist; + int running_procs = 0; int ret = 0; (void) ipc_mutex_lock(&filebench_shm->procflow_lock); @@ -568,16 +586,18 @@ procflow_allstarted() } if (waits == 0) - filebench_log(LOG_INFO, "Failed to start process %s-%d", + 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; } + filebench_shm->shm_running = running_procs; - filebench_shm->allrunning = 1; (void) ipc_mutex_unlock(&filebench_shm->procflow_lock); @@ -586,7 +606,7 @@ procflow_allstarted() /* - * Sets the f_abort flag and clears the allrunning flag to stop + * 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 @@ -596,11 +616,12 @@ void procflow_shutdown(void) { procflow_t *procflow = filebench_shm->proclist; + int wait_cnt; (void) ipc_mutex_lock(&filebench_shm->procflow_lock); - filebench_shm->allrunning = 0; + filebench_shm->shm_running = 0; filebench_shm->f_abort = 1; - procflow_delete_wait_cnt = 0; + wait_cnt = SHUTDOWN_WAIT_SECONDS; while (procflow) { if (procflow->pf_instance && @@ -612,8 +633,11 @@ procflow_shutdown(void) procflow->pf_name, procflow->pf_instance, procflow->pf_pid); - (void) procflow_delete(procflow); + (void) procflow_delete(procflow, wait_cnt); procflow = procflow->pf_next; + /* grow more impatient */ + if (wait_cnt) + wait_cnt--; } filebench_shm->f_abort = 0; diff --git a/usr/src/cmd/filebench/common/stats.c b/usr/src/cmd/filebench/common/stats.c index 985f387b77..1b23bc21c4 100644 --- a/usr/src/cmd/filebench/common/stats.c +++ b/usr/src/cmd/filebench/common/stats.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -402,6 +402,13 @@ stats_snap(void) return; } + /* don't print out if run ended in error */ + if (filebench_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", @@ -544,6 +551,10 @@ stats_dump(char *filename) flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; flowop_t *flowop; + /* don't dump stats if run ended in error */ + if (filebench_shm->f_abort == FILEBENCH_ABORT_ERROR) + return; + (void) strcpy(filebench_shm->dump_filename, filename); filebench_log(LOG_INFO, "in statsdump %s", filename); @@ -616,6 +627,10 @@ stats_xmldump(char *filename) flowstat_t *aiostat = &globalstats[FLOW_TYPE_AIO]; flowop_t *flowop; + /* don't dump stats if run ended in error */ + if (filebench_shm->f_abort == FILEBENCH_ABORT_ERROR) + return; + (void) strcpy(filebench_shm->dump_filename, filename); if (filebench_shm->dump_fd > 0) { diff --git a/usr/src/cmd/filebench/common/threadflow.c b/usr/src/cmd/filebench/common/threadflow.c index 9e6c99a92e..11351fdf17 100644 --- a/usr/src/cmd/filebench/common/threadflow.c +++ b/usr/src/cmd/filebench/common/threadflow.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -82,8 +82,6 @@ threadflow_usage(void) static int threadflow_createthread(threadflow_t *threadflow) { - int fp = 0; - filebench_log(LOG_DEBUG_SCRIPT, "Creating thread %s, memory = %ld", threadflow->tf_name, *threadflow->tf_memsize); @@ -95,15 +93,12 @@ threadflow_createthread(threadflow_t *threadflow) (void *(*)(void*))flowop_start, threadflow) != 0) { filebench_log(LOG_ERROR, "thread create failed"); filebench_shutdown(1); + return (FILEBENCH_ERROR); } - /* XXX */ - return (fp < 0); + return (FILEBENCH_OK); } -#ifndef USE_PROCESS_MODEL -static procflow_t *my_procflow; - /* * Terminates (exits) all the threads of the procflow (process). * The procflow is determined from a process private pointer @@ -113,26 +108,30 @@ static procflow_t *my_procflow; static void threadflow_cancel(int arg1) { - threadflow_t *threadflow = my_procflow->pf_threads; + threadflow_t *threadflow; #ifdef HAVE_LWPS filebench_log(LOG_DEBUG_IMPL, "Thread signal handler on tid %d", _lwp_self()); #endif + threadflow = my_procflow->pf_threads; my_procflow->pf_running = 0; - exit(0); while (threadflow) { if (threadflow->tf_tid) { + /* make sure thread has been cleaned up */ + flowop_destruct_all_flows(threadflow); + (void) pthread_cancel(threadflow->tf_tid); filebench_log(LOG_DEBUG_IMPL, "Thread %d cancelled...", threadflow->tf_tid); } threadflow = threadflow->tf_next; } + + exit(0); } -#endif /* USE_PROCESS_MODEL */ /* * Creates threads for the threadflows associated with a procflow. @@ -157,11 +156,9 @@ threadflow_init(procflow_t *procflow) int ret = 0; (void) ipc_mutex_lock(&filebench_shm->threadflow_lock); -#ifndef USE_PROCESS_MODEL - my_procflow = procflow; (void) signal(SIGUSR1, threadflow_cancel); -#endif + while (threadflow) { threadflow_t *newthread; int i; @@ -178,7 +175,7 @@ threadflow_init(procflow_t *procflow) threadflow->tf_name, threadflow, i + 1); if (newthread == NULL) return (-1); - ret += threadflow_createthread(newthread); + ret |= threadflow_createthread(newthread); } newthread = threadflow_define_common(procflow, @@ -188,8 +185,8 @@ threadflow_init(procflow_t *procflow) if (newthread == NULL) return (-1); - /* Create threads */ - ret += threadflow_createthread(newthread); + /* Create each thread */ + ret |= threadflow_createthread(newthread); threadflow = threadflow->tf_next; } @@ -201,10 +198,11 @@ threadflow_init(procflow_t *procflow) while (threadflow) { void *status; + /* wait for all threads to finish */ if (threadflow->tf_tid) (void) pthread_join(threadflow->tf_tid, &status); - ret += *(int *)status; + ret |= *(int *)status; threadflow = threadflow->tf_next; } @@ -218,11 +216,17 @@ threadflow_init(procflow_t *procflow) * its associated process to end the thread. */ static void -threadflow_kill(threadflow_t *threadflow) +threadflow_kill(threadflow_t *threadflow, int wait_cnt) { /* 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--; + } + #ifdef USE_PROCESS_MODEL #ifdef HAVE_SIGSEND (void) sigsend(P_PID, threadflow->tf_process->pf_pid, SIGUSR1); @@ -244,7 +248,8 @@ threadflow_kill(threadflow_t *threadflow) * returns -1. */ static int -threadflow_delete(threadflow_t **threadlist, threadflow_t *threadflow) +threadflow_delete(threadflow_t **threadlist, threadflow_t *threadflow, + int wait_cnt) { threadflow_t *entry = *threadlist; @@ -262,7 +267,7 @@ threadflow_delete(threadflow_t **threadlist, threadflow_t *threadflow) threadflow->tf_name, threadflow->tf_instance); - threadflow_kill(threadflow); + threadflow_kill(threadflow, wait_cnt); flowop_delete_all(&threadflow->tf_ops); *threadlist = threadflow->tf_next; ipc_free(FILEBENCH_THREADFLOW, (char *)threadflow); @@ -283,7 +288,7 @@ threadflow_delete(threadflow_t **threadlist, threadflow_t *threadflow) "Deleted thread: (%s-%d)", entry->tf_next->tf_name, entry->tf_next->tf_instance); - threadflow_kill(entry->tf_next); + threadflow_kill(entry->tf_next, wait_cnt); flowop_delete_all(&entry->tf_next->tf_ops); ipc_free(FILEBENCH_THREADFLOW, (char *)threadflow); entry->tf_next = entry->tf_next->tf_next; @@ -301,7 +306,7 @@ threadflow_delete(threadflow_t **threadlist, threadflow_t *threadflow) * except the FLOW_MASTER. */ void -threadflow_delete_all(threadflow_t **threadlist) +threadflow_delete_all(threadflow_t **threadlist, int wait_cnt) { threadflow_t *threadflow = *threadlist; @@ -315,8 +320,11 @@ threadflow_delete_all(threadflow_t **threadlist) threadflow = threadflow->tf_next; continue; } - (void) threadflow_delete(threadlist, threadflow); + (void) threadflow_delete(threadlist, threadflow, wait_cnt); threadflow = threadflow->tf_next; + /* grow more impatient */ + if (wait_cnt > 0) + wait_cnt--; } (void) ipc_mutex_unlock(&filebench_shm->threadflow_lock); diff --git a/usr/src/cmd/filebench/common/threadflow.h b/usr/src/cmd/filebench/common/threadflow.h index eeb5331cce..3e5feefe09 100644 --- a/usr/src/cmd/filebench/common/threadflow.h +++ b/usr/src/cmd/filebench/common/threadflow.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -111,7 +111,7 @@ 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); +void threadflow_delete_all(threadflow_t **threadlist, int wait_cnt); #ifdef __cplusplus } diff --git a/usr/src/cmd/filebench/workloads/bringover.f b/usr/src/cmd/filebench/workloads/bringover.f index e71de7ae18..cfa6db360c 100644 --- a/usr/src/cmd/filebench/workloads/bringover.f +++ b/usr/src/cmd/filebench/workloads/bringover.f @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -32,6 +32,8 @@ set $filesize=16k set $iosize=1m set $nthreads=1 +set mode quit alldone + define fileset name=srcfiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth,prealloc define fileset name=destfiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$dirwidth @@ -48,11 +50,12 @@ define process name=filereader,instances=1 } } -echo "Bringover Version 2.1 personality successfully loaded" +echo "Bringover 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 \$iosize=<size> defaults to $iosize" usage " set \$dirwidth=<value> defaults to $dirwidth" usage " set \$nthreads=<value> defaults to $nthreads" -usage " run runtime (e.g. run 60)" +usage " " +usage " run 0" diff --git a/usr/src/cmd/filebench/workloads/copyfiles.f b/usr/src/cmd/filebench/workloads/copyfiles.f index 24cdf28420..58e481a913 100644 --- a/usr/src/cmd/filebench/workloads/copyfiles.f +++ b/usr/src/cmd/filebench/workloads/copyfiles.f @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -31,6 +31,8 @@ set $filesize=16k set $iosize=1m set $nthreads=1 +set mode quit alldone + 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 @@ -47,11 +49,12 @@ define process name=filereader,instances=1 } } -echo "CopyFiles Version 2.1 personality successfully loaded" +echo "CopyFiles 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 \$iosize=<size> defaults to $iosize" usage " set \$dirwidth=<value> defaults to $dirwidth" usage " set \$nthreads=<value> defaults to $nthreads" -usage " run runtime (e.g. run 60)" +usage " " +usage " run 0" diff --git a/usr/src/cmd/filebench/workloads/createfiles.f b/usr/src/cmd/filebench/workloads/createfiles.f index 15d11b5cbf..3dda144edf 100644 --- a/usr/src/cmd/filebench/workloads/createfiles.f +++ b/usr/src/cmd/filebench/workloads/createfiles.f @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -31,6 +31,8 @@ set $filesize=16k set $iosize=1m set $nthreads=16 +set mode quit alldone + define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth define process name=filecreate,instances=1 @@ -44,7 +46,7 @@ define process name=filecreate,instances=1 } } -echo "Createfiles Version 2.1 personality successfully loaded" +echo "Createfiles Version 2.2 personality successfully loaded" usage "Usage: set \$dir=<dir>" usage " set \$filesize=<size> defaults to $filesize" usage " set \$iosize=<size> defaults to $iosize" @@ -53,4 +55,4 @@ 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)" +usage " run 0" diff --git a/usr/src/cmd/filebench/workloads/deletefiles.f b/usr/src/cmd/filebench/workloads/deletefiles.f index 7a3502bcf4..16fde89971 100644 --- a/usr/src/cmd/filebench/workloads/deletefiles.f +++ b/usr/src/cmd/filebench/workloads/deletefiles.f @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -30,6 +30,8 @@ set $meandirwidth=100 set $filesize=16k set $nthreads=16 +set mode quit alldone + define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=100 define process name=filedelete,instances=1 @@ -41,7 +43,7 @@ define process name=filedelete,instances=1 } } -echo "Deletefiles Version 2.0 personality successfully loaded" +echo "Deletefiles 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" @@ -49,4 +51,4 @@ 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)" +usage " run 0" |