The following changes since commit c5103619279883ee9291ed4793bb6ad39b436101:

  eta: use bool for forcing jobs_eta return (2015-12-09 12:44:09 -0700)

are available in the git repository at:

  git://git.kernel.dk/fio.git master

for you to fetch changes up to 408e0b90d74196f173c2008bc0034b70e9b56ddf:

  log: remove log_local_buf() (2015-12-10 15:31:02 -0700)

----------------------------------------------------------------
Jens Axboe (4):
      Add exitall_on_error option
      mutex: fixup fio_mutex_down_timeout()
      Add backend related data
      log: remove log_local_buf()

 HOWTO            |  3 +++
 backend.c        | 18 +++++++++++-------
 cconv.c          |  2 ++
 fio.1            |  4 ++++
 fio.c            |  2 +-
 fio.h            | 11 ++++++++++-
 init.c           |  1 +
 log.c            | 30 ++++++++++++++----------------
 log.h            |  1 -
 mutex.c          | 27 ++++++++++++++++++---------
 options.c        |  9 +++++++++
 server.c         |  6 +++---
 thread_options.h |  3 ++-
 13 files changed, 78 insertions(+), 39 deletions(-)

---

Diff of recent changes:

diff --git a/HOWTO b/HOWTO
index eb9c824..b21d27e 100644
--- a/HOWTO
+++ b/HOWTO
@@ -1227,6 +1227,9 @@ exitall           When one job finishes, terminate the 
rest. The default is
                to wait for each job to finish, sometimes that is not the
                desired action.
 
+exitall_on_error       When one job finishes in error, terminate the rest. The
+               default is to wait for each job to finish.
+
 bwavgtime=int  Average the calculated bandwidth over the given time. Value
                is specified in milliseconds.
 
diff --git a/backend.c b/backend.c
index 425b0ee..c8554bc 100644
--- a/backend.c
+++ b/backend.c
@@ -974,7 +974,7 @@ reap:
 
                if (!in_ramp_time(td) && should_check_rate(td)) {
                        if (check_min_rate(td, &comp_time)) {
-                               if (exitall_on_terminate)
+                               if (exitall_on_terminate || td->o.exitall_error)
                                        fio_terminate_threads(td->groupid);
                                td_verror(td, EIO, "check_min_rate");
                                break;
@@ -1662,7 +1662,7 @@ static void *thread_main(void *data)
        if (o->exec_postrun)
                exec_string(o, o->exec_postrun, (const char *)"postrun");
 
-       if (exitall_on_terminate)
+       if (exitall_on_terminate || (o->exitall_error && td->error))
                fio_terminate_threads(td->groupid);
 
 err:
@@ -2117,7 +2117,7 @@ reap:
                                        *fio_debug_jobp = pid;
                        }
                        dprint(FD_MUTEX, "wait on startup_mutex\n");
-                       if (fio_mutex_down_timeout(startup_mutex, 10)) {
+                       if (fio_mutex_down_timeout(startup_mutex, 10000)) {
                                log_err("fio: job startup hung? exiting.\n");
                                fio_terminate_threads(TERMINATE_ALL);
                                fio_abort = 1;
@@ -2220,8 +2220,12 @@ static void free_disk_util(void)
 
 static void *helper_thread_main(void *data)
 {
+       struct backend_data *d = data;
        int ret = 0;
 
+       if (d)
+               pthread_setspecific(d->key, d->ptr);
+
        fio_mutex_up(startup_mutex);
 
        while (!ret) {
@@ -2255,7 +2259,7 @@ static void *helper_thread_main(void *data)
        return NULL;
 }
 
-static int create_helper_thread(void)
+static int create_helper_thread(struct backend_data *data)
 {
        int ret;
 
@@ -2264,7 +2268,7 @@ static int create_helper_thread(void)
        pthread_cond_init(&helper_cond, NULL);
        pthread_mutex_init(&helper_lock, NULL);
 
-       ret = pthread_create(&helper_thread, NULL, helper_thread_main, NULL);
+       ret = pthread_create(&helper_thread, NULL, helper_thread_main, data);
        if (ret) {
                log_err("Can't create helper thread: %s\n", strerror(ret));
                return 1;
@@ -2276,7 +2280,7 @@ static int create_helper_thread(void)
        return 0;
 }
 
-int fio_backend(void)
+int fio_backend(struct backend_data *data)
 {
        struct thread_data *td;
        int i;
@@ -2306,7 +2310,7 @@ int fio_backend(void)
 
        set_genesis_time();
        stat_init();
-       create_helper_thread();
+       create_helper_thread(data);
 
        cgroup_list = smalloc(sizeof(*cgroup_list));
        INIT_FLIST_HEAD(cgroup_list);
diff --git a/cconv.c b/cconv.c
index c0168c4..a476aad 100644
--- a/cconv.c
+++ b/cconv.c
@@ -167,6 +167,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
        o->fsync_on_close = le32_to_cpu(top->fsync_on_close);
        o->bs_is_seq_rand = le32_to_cpu(top->bs_is_seq_rand);
        o->random_distribution = le32_to_cpu(top->random_distribution);
+       o->exitall_error = le32_to_cpu(top->exitall_error);
        o->zipf_theta.u.f = 
fio_uint64_to_double(le64_to_cpu(top->zipf_theta.u.i));
        o->pareto_h.u.f = fio_uint64_to_double(le64_to_cpu(top->pareto_h.u.i));
        o->gauss_dev.u.f = 
fio_uint64_to_double(le64_to_cpu(top->gauss_dev.u.i));
@@ -353,6 +354,7 @@ void convert_thread_options_to_net(struct 
thread_options_pack *top,
        top->fsync_on_close = cpu_to_le32(o->fsync_on_close);
        top->bs_is_seq_rand = cpu_to_le32(o->bs_is_seq_rand);
        top->random_distribution = cpu_to_le32(o->random_distribution);
+       top->exitall_error = cpu_to_le32(o->exitall_error);
        top->zipf_theta.u.i = 
__cpu_to_le64(fio_double_to_uint64(o->zipf_theta.u.f));
        top->pareto_h.u.i = 
__cpu_to_le64(fio_double_to_uint64(o->pareto_h.u.f));
        top->gauss_dev.u.i = 
__cpu_to_le64(fio_double_to_uint64(o->gauss_dev.u.f));
diff --git a/fio.1 b/fio.1
index eab20d7..4fe1be2 100644
--- a/fio.1
+++ b/fio.1
@@ -1126,6 +1126,10 @@ Should be a multiple of 1MB. Default: 4MB.
 .B exitall
 Terminate all jobs when one finishes.  Default: wait for each job to finish.
 .TP
+.B exitall_on_error \fR=\fPbool
+Terminate all jobs if one job finishes in error.  Default: wait for each job
+to finish.
+.TP
 .BI bwavgtime \fR=\fPint
 Average bandwidth calculations over the given time in milliseconds.  Default:
 500ms.
diff --git a/fio.c b/fio.c
index bafbd48..bd3e260 100644
--- a/fio.c
+++ b/fio.c
@@ -57,7 +57,7 @@ int main(int argc, char *argv[], char *envp[])
                        goto done;
                ret = fio_handle_clients(&fio_client_ops);
        } else
-               ret = fio_backend();
+               ret = fio_backend(NULL);
 
 done:
        deinitialize_fio();
diff --git a/fio.h b/fio.h
index 6f85266..63778b6 100644
--- a/fio.h
+++ b/fio.h
@@ -108,6 +108,15 @@ enum {
 };
 
 /*
+ * Per-thread/process specific data. Only used for the network client
+ * for now.
+ */
+struct backend_data {
+       pthread_key_t key;
+       void *ptr;
+};
+
+/*
  * This describes a single thread/process executing a fio job.
  */
 struct thread_data {
@@ -468,7 +477,7 @@ extern int __must_check fio_init_options(void);
 extern int __must_check parse_options(int, char **);
 extern int parse_jobs_ini(char *, int, int, int);
 extern int parse_cmd_line(int, char **, int);
-extern int fio_backend(void);
+extern int fio_backend(struct backend_data *);
 extern void reset_fio_state(void);
 extern void clear_io_state(struct thread_data *, int);
 extern int fio_options_parse(struct thread_data *, char **, int, int);
diff --git a/init.c b/init.c
index 0100da2..63ba324 100644
--- a/init.c
+++ b/init.c
@@ -47,6 +47,7 @@ static char **job_sections;
 static int nr_job_sections;
 
 int exitall_on_terminate = 0;
+int exitall_on_terminate_error = 0;
 int output_format = FIO_OUTPUT_NORMAL;
 int eta_print = FIO_ETA_AUTO;
 int eta_new_line = 0;
diff --git a/log.c b/log.c
index d508267..4eb4af5 100644
--- a/log.c
+++ b/log.c
@@ -8,9 +8,13 @@
 
 size_t log_info_buf(const char *buf, size_t len)
 {
-       if (is_backend)
-               return fio_server_text_output(FIO_LOG_INFO, buf, len);
-       else if (log_syslog) {
+       if (is_backend) {
+               size_t ret = fio_server_text_output(FIO_LOG_INFO, buf, len);
+               if (ret != -1)
+                       return ret;
+       }
+
+       if (log_syslog) {
                syslog(LOG_INFO, "%s", buf);
                return len;
        } else
@@ -27,16 +31,6 @@ size_t log_valist(const char *str, va_list args)
        return log_info_buf(buffer, min(len, sizeof(buffer) - 1));
 }
 
-size_t log_local_buf(const char *buf, size_t len)
-{
-       if (log_syslog)
-               syslog(LOG_INFO, "%s", buf);
-       else
-               len = fwrite(buf, len, 1, f_out);
-
-       return len;
-}
-
 size_t log_info(const char *format, ...)
 {
        char buffer[1024];
@@ -82,9 +76,13 @@ size_t log_err(const char *format, ...)
        va_end(args);
        len = min(len, sizeof(buffer) - 1);
 
-       if (is_backend)
-               return fio_server_text_output(FIO_LOG_ERR, buffer, len);
-       else if (log_syslog) {
+       if (is_backend) {
+               size_t ret = fio_server_text_output(FIO_LOG_ERR, buffer, len);
+               if (ret != -1)
+                       return ret;
+       }
+
+       if (log_syslog) {
                syslog(LOG_INFO, "%s", buffer);
                return len;
        } else {
diff --git a/log.h b/log.h
index f1cf003..a39dea6 100644
--- a/log.h
+++ b/log.h
@@ -13,7 +13,6 @@ extern size_t log_err(const char *format, ...) __attribute__ 
((__format__ (__pri
 extern size_t log_info(const char *format, ...) __attribute__ ((__format__ 
(__printf__, 1, 2)));
 extern size_t __log_buf(struct buf_output *, const char *format, ...) 
__attribute__ ((__format__ (__printf__, 2, 3)));
 extern size_t log_valist(const char *str, va_list);
-extern size_t log_local_buf(const char *buf, size_t);
 extern size_t log_info_buf(const char *buf, size_t len);
 extern int log_info_flush(void);
 
diff --git a/mutex.c b/mutex.c
index 7612b32..a48e37d 100644
--- a/mutex.c
+++ b/mutex.c
@@ -92,12 +92,15 @@ struct fio_mutex *fio_mutex_init(int value)
        return NULL;
 }
 
-static bool mutex_timed_out(struct timeval *t, unsigned int seconds)
+static bool mutex_timed_out(struct timeval *t, unsigned int msecs)
 {
-       return mtime_since_now(t) >= seconds * 1000;
+       struct timeval now;
+
+       gettimeofday(&now, NULL);
+       return mtime_since(t, &now) >= msecs;
 }
 
-int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int seconds)
+int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int msecs)
 {
        struct timeval tv_s;
        struct timespec t;
@@ -106,30 +109,36 @@ int fio_mutex_down_timeout(struct fio_mutex *mutex, 
unsigned int seconds)
        assert(mutex->magic == FIO_MUTEX_MAGIC);
 
        gettimeofday(&tv_s, NULL);
-       t.tv_sec = tv_s.tv_sec + seconds;
+       t.tv_sec = tv_s.tv_sec;
        t.tv_nsec = tv_s.tv_usec * 1000;
 
+       t.tv_sec += msecs / 1000;
+       t.tv_nsec += ((msecs * 1000000) % 1000000000);
+       if (t.tv_nsec >= 1000000000) {
+               t.tv_nsec -= 1000000000;
+               t.tv_sec++;
+       }
+
        pthread_mutex_lock(&mutex->lock);
 
+       mutex->waiters++;
        while (!mutex->value && !ret) {
-               mutex->waiters++;
-
                /*
                 * Some platforms (FreeBSD 9?) seems to return timed out
                 * way too early, double check.
                 */
                ret = pthread_cond_timedwait(&mutex->cond, &mutex->lock, &t);
-               if (ret == ETIMEDOUT && !mutex_timed_out(&tv_s, seconds))
+               if (ret == ETIMEDOUT && !mutex_timed_out(&tv_s, msecs))
                        ret = 0;
-
-               mutex->waiters--;
        }
+       mutex->waiters--;
 
        if (!ret) {
                mutex->value--;
                pthread_mutex_unlock(&mutex->lock);
        }
 
+       pthread_mutex_unlock(&mutex->lock);
        return ret;
 }
 
diff --git a/options.c b/options.c
index 627029c..46d5fb9 100644
--- a/options.c
+++ b/options.c
@@ -3141,6 +3141,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_PROCESS,
        },
        {
+               .name   = "exitall_on_error",
+               .lname  = "Exit-all on terminate in error",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(unlink),
+               .help   = "Terminate all jobs when one exits in error",
+               .category = FIO_OPT_C_GENERAL,
+               .group  = FIO_OPT_G_PROCESS,
+       },
+       {
                .name   = "stonewall",
                .lname  = "Wait for previous",
                .alias  = "wait_for_previous",
diff --git a/server.c b/server.c
index cf01733..27ea282 100644
--- a/server.c
+++ b/server.c
@@ -601,7 +601,7 @@ static int handle_run_cmd(struct flist_head *job_list, 
struct fio_net_cmd *cmd)
                return 0;
        }
 
-       ret = fio_backend();
+       ret = fio_backend(NULL);
        free_threads_shm();
        _exit(ret);
 }
@@ -1061,7 +1061,7 @@ int fio_server_text_output(int level, const char *buf, 
size_t len)
        struct timeval tv;
 
        if (server_fd == -1)
-               return log_local_buf(buf, len);
+               return -1;
 
        tlen = sizeof(*pdu) + len;
        pdu = malloc(tlen);
@@ -1445,7 +1445,7 @@ int fio_server_get_verify_state(const char *name, int 
threadnumber,
        /*
         * Wait for the backend to receive the reply
         */
-       if (fio_mutex_down_timeout(&rep->lock, 10)) {
+       if (fio_mutex_down_timeout(&rep->lock, 10000)) {
                log_err("fio: timed out waiting for reply\n");
                goto fail;
        }
diff --git a/thread_options.h b/thread_options.h
index 02c867f..6ae0335 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -131,6 +131,7 @@ struct thread_options {
        unsigned int verify_only;
 
        unsigned int random_distribution;
+       unsigned int exitall_error;
 
        fio_fp64_t zipf_theta;
        fio_fp64_t pareto_h;
@@ -376,7 +377,7 @@ struct thread_options_pack {
        uint32_t bs_is_seq_rand;
 
        uint32_t random_distribution;
-       uint32_t pad;
+       uint32_t exitall_error;
 
        fio_fp64_t zipf_theta;
        fio_fp64_t pareto_h;
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to