Get rid of _set variables
[fio.git] / backend.c
index cae4e38de4b9fb3adc871863558dd1230bba32b2..e07ded86886ed5c836324d8fff704d48be0cb046 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -526,6 +526,11 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes)
                                break;
                }
 
+               if (verify_state_should_stop(td, io_u)) {
+                       put_io_u(td, io_u);
+                       break;
+               }
+
                if (td->o.verify_async)
                        io_u->end_io = verify_io_u_async;
                else
@@ -758,6 +763,11 @@ static uint64_t do_io(struct thread_data *td)
                                        io_u->rand_seed *= __rand(&td->verify_state);
                        }
 
+                       if (verify_state_should_stop(td, io_u)) {
+                               put_io_u(td, io_u);
+                               break;
+                       }
+
                        if (td->o.verify_async)
                                io_u->end_io = verify_io_u_async;
                        else
@@ -977,6 +987,9 @@ static void cleanup_io_u(struct thread_data *td)
        io_u_rexit(&td->io_u_requeues);
        io_u_qexit(&td->io_u_freelist);
        io_u_qexit(&td->io_u_all);
+
+       if (td->last_write_comp)
+               sfree(td->last_write_comp);
 }
 
 static int init_io_u(struct thread_data *td)
@@ -1093,6 +1106,14 @@ static int init_io_u(struct thread_data *td)
                p += max_bs;
        }
 
+       if (td->o.verify != VERIFY_NONE) {
+               td->last_write_comp = scalloc(max_units, sizeof(uint64_t));
+               if (!td->last_write_comp) {
+                       log_err("fio: failed to alloc write comp data\n");
+                       return 1;
+               }
+       }
+
        return 0;
 }
 
@@ -1324,7 +1345,7 @@ static void *thread_main(void *data)
         * Set affinity first, in case it has an impact on the memory
         * allocations.
         */
-       if (o->cpumask_set) {
+       if (fio_option_is_set(o, cpumask)) {
                if (o->cpus_allowed_policy == FIO_CPUS_SPLIT) {
                        ret = fio_cpus_split(&o->cpumask, td->thread_number - 1);
                        if (!ret) {
@@ -1343,16 +1364,16 @@ static void *thread_main(void *data)
 
 #ifdef CONFIG_LIBNUMA
        /* numa node setup */
-       if (o->numa_cpumask_set || o->numa_memmask_set) {
+       if (fio_option_is_set(o, numa_cpunodes) ||
+           fio_option_is_set(o, numa_memnodes)) {
                struct bitmask *mask;
-               int ret;
 
                if (numa_available() < 0) {
                        td_verror(td, errno, "Does not support NUMA API\n");
                        goto err;
                }
 
-               if (o->numa_cpumask_set) {
+               if (fio_option_is_set(o, numa_cpunodes)) {
                        mask = numa_parse_nodestring(o->numa_cpunodes);
                        ret = numa_run_on_node_mask(mask);
                        numa_free_nodemask(mask);
@@ -1363,8 +1384,7 @@ static void *thread_main(void *data)
                        }
                }
 
-               if (o->numa_memmask_set) {
-
+               if (fio_option_is_set(o, numa_memnodes)) {
                        mask = NULL;
                        if (o->numa_memnodes)
                                mask = numa_parse_nodestring(o->numa_memnodes);
@@ -1485,18 +1505,21 @@ static void *thread_main(void *data)
 
                clear_state = 1;
 
+               fio_mutex_down(stat_mutex);
                if (td_read(td) && td->io_bytes[DDIR_READ]) {
-                       elapsed = utime_since_now(&td->start);
+                       elapsed = mtime_since_now(&td->start);
                        td->ts.runtime[DDIR_READ] += elapsed;
                }
                if (td_write(td) && td->io_bytes[DDIR_WRITE]) {
-                       elapsed = utime_since_now(&td->start);
+                       elapsed = mtime_since_now(&td->start);
                        td->ts.runtime[DDIR_WRITE] += elapsed;
                }
                if (td_trim(td) && td->io_bytes[DDIR_TRIM]) {
-                       elapsed = utime_since_now(&td->start);
+                       elapsed = mtime_since_now(&td->start);
                        td->ts.runtime[DDIR_TRIM] += elapsed;
                }
+               fio_gettime(&td->start, NULL);
+               fio_mutex_up(stat_mutex);
 
                if (td->error || td->terminate)
                        break;
@@ -1512,21 +1535,33 @@ static void *thread_main(void *data)
 
                do_verify(td, verify_bytes);
 
-               td->ts.runtime[DDIR_READ] += utime_since_now(&td->start);
+               fio_mutex_down(stat_mutex);
+               td->ts.runtime[DDIR_READ] += mtime_since_now(&td->start);
+               fio_gettime(&td->start, NULL);
+               fio_mutex_up(stat_mutex);
 
                if (td->error || td->terminate)
                        break;
        }
 
        update_rusage_stat(td);
-       td->ts.runtime[DDIR_READ] = (td->ts.runtime[DDIR_READ] + 999) / 1000;
-       td->ts.runtime[DDIR_WRITE] = (td->ts.runtime[DDIR_WRITE] + 999) / 1000;
-       td->ts.runtime[DDIR_TRIM] = (td->ts.runtime[DDIR_TRIM] + 999) / 1000;
        td->ts.total_run_time = mtime_since_now(&td->epoch);
        td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ];
        td->ts.io_bytes[DDIR_WRITE] = td->io_bytes[DDIR_WRITE];
        td->ts.io_bytes[DDIR_TRIM] = td->io_bytes[DDIR_TRIM];
 
+       if (td->o.verify_state_save && !(td->flags & TD_F_VSTATE_SAVED) &&
+           (td->o.verify != VERIFY_NONE && td_write(td))) {
+               struct all_io_list *state;
+               size_t sz;
+
+               state = get_all_io_list(td->thread_number, &sz);
+               if (state) {
+                       __verify_save_state(state, "local");
+                       free(state);
+               }
+       }
+
        fio_unpin_memory(td);
 
        fio_writeout_logs(td);
@@ -1552,11 +1587,12 @@ err:
        cleanup_io_u(td);
        close_ioengine(td);
        cgroup_shutdown(td, &cgroup_mnt);
+       verify_free_state(td);
 
-       if (o->cpumask_set) {
-               int ret = fio_cpuset_exit(&o->cpumask);
-
-               td_verror(td, ret, "fio_cpuset_exit");
+       if (fio_option_is_set(o, cpumask)) {
+               ret = fio_cpuset_exit(&o->cpumask);
+               if (ret)
+                       td_verror(td, ret, "fio_cpuset_exit");
        }
 
        /*
@@ -1728,9 +1764,80 @@ reaped:
                fio_terminate_threads(TERMINATE_ALL);
 }
 
+static int __check_trigger_file(void)
+{
+       struct stat sb;
+
+       if (!trigger_file)
+               return 0;
+
+       if (stat(trigger_file, &sb))
+               return 0;
+
+       if (unlink(trigger_file) < 0)
+               log_err("fio: failed to unlink %s: %s\n", trigger_file,
+                                                       strerror(errno));
+
+       return 1;
+}
+
+static int trigger_timedout(void)
+{
+       if (trigger_timeout)
+               return time_since_genesis() >= trigger_timeout;
+
+       return 0;
+}
+
+void exec_trigger(const char *cmd)
+{
+       int ret;
+
+       if (!cmd)
+               return;
+
+       ret = system(cmd);
+       if (ret == -1)
+               log_err("fio: failed executing %s trigger\n", cmd);
+}
+
+void check_trigger_file(void)
+{
+       if (__check_trigger_file() || trigger_timedout()) {
+               if (nr_clients)
+                       fio_clients_send_trigger(trigger_remote_cmd);
+               else {
+                       verify_save_state();
+                       fio_terminate_threads(TERMINATE_ALL);
+                       exec_trigger(trigger_cmd);
+               }
+       }
+}
+
+static int fio_verify_load_state(struct thread_data *td)
+{
+       int ret;
+
+       if (!td->o.verify_state)
+               return 0;
+
+       if (is_backend) {
+               void *data;
+
+               ret = fio_server_get_verify_state(td->o.name,
+                                       td->thread_number - 1, &data);
+               if (!ret)
+                       verify_convert_assign_state(td, data);
+       } else
+               ret = verify_load_state(td, "local");
+
+       return ret;
+}
+
 static void do_usleep(unsigned int usecs)
 {
        check_for_running_stats();
+       check_trigger_file();
        usleep(usecs);
 }
 
@@ -1784,12 +1891,16 @@ static void run_threads(void)
                if (!td->o.create_serialize)
                        continue;
 
+               if (fio_verify_load_state(td))
+                       goto reap;
+
                /*
                 * do file setup here so it happens sequentially,
                 * we don't want X number of threads getting their
                 * client data interspersed on disk
                 */
                if (setup_files(td)) {
+reap:
                        exit_value++;
                        if (td->error)
                                log_err("fio: pid=%d, err=%d/%s\n",
@@ -2092,8 +2203,6 @@ int fio_backend(void)
        if (!fio_abort) {
                __show_run_stats();
                if (write_bw_log) {
-                       int i;
-
                        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
                                struct io_log *log = agg_io_log[i];
 
@@ -2105,8 +2214,10 @@ int fio_backend(void)
 
        for_each_td(td, i) {
                fio_options_free(td);
-               fio_mutex_remove(td->rusage_sem);
-               td->rusage_sem = NULL;
+               if (td->rusage_sem) {
+                       fio_mutex_remove(td->rusage_sem);
+                       td->rusage_sem = NULL;
+               }
        }
 
        free_disk_util();