Endian sanity check
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index 4514840dbb11027da8127a64e379ddb21d7acd4f..61ef88b315eb6da4ace155967d8f1bce19eee716 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -46,6 +46,7 @@
 #include "profile.h"
 #include "lib/rand.h"
 #include "memalign.h"
+#include "server.h"
 
 unsigned long page_mask;
 unsigned long page_size;
@@ -74,7 +75,6 @@ unsigned long arch_flags = 0;
 
 struct io_log *agg_io_log[2];
 
-#define TERMINATE_ALL          (-1)
 #define JOB_START_TIMEOUT      (5 * 1000)
 
 void td_set_runstate(struct thread_data *td, int runstate)
@@ -87,7 +87,7 @@ void td_set_runstate(struct thread_data *td, int runstate)
        td->runstate = runstate;
 }
 
-static void terminate_threads(int group_id)
+void fio_terminate_threads(int group_id)
 {
        struct thread_data *td;
        int i;
@@ -122,9 +122,10 @@ static void sig_int(int sig)
 {
        if (threads) {
                log_info("\nfio: terminating on signal %d\n", sig);
+               exit_backend = 1;
                fflush(stdout);
                exit_value = 128;
-               terminate_threads(TERMINATE_ALL);
+               fio_terminate_threads(TERMINATE_ALL);
        }
 }
 
@@ -137,7 +138,11 @@ static void *disk_thread_main(void *data)
                if (!threads)
                        break;
                update_io_ticks();
-               print_thread_status();
+
+               if (is_backend)
+                       fio_server_send_status();
+               else
+                       print_thread_status();
        }
 
        return NULL;
@@ -178,6 +183,13 @@ static void set_sig_handlers(void)
        act.sa_handler = sig_int;
        act.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &act, NULL);
+
+       if (is_backend) {
+               memset(&act, 0, sizeof(act));
+               act.sa_handler = sig_int;
+               act.sa_flags = SA_RESTART;
+               sigaction(SIGPIPE, &act, NULL);
+       }
 }
 
 /*
@@ -744,7 +756,7 @@ sync_done:
                if (!in_ramp_time(td) && should_check_rate(td, bytes_done)) {
                        if (check_min_rate(td, &comp_time, bytes_done)) {
                                if (exitall_on_terminate)
-                                       terminate_threads(td->groupid);
+                                       fio_terminate_threads(td->groupid);
                                td_verror(td, EIO, "check_min_rate");
                                break;
                        }
@@ -972,7 +984,7 @@ static int keep_running(struct thread_data *td)
 
 static void reset_io_counters(struct thread_data *td)
 {
-       td->ts.stat_io_bytes[0] = td->ts.stat_io_bytes[1] = 0;
+       td->stat_io_bytes[0] = td->stat_io_bytes[1] = 0;
        td->this_io_bytes[0] = td->this_io_bytes[1] = 0;
        td->zone_bytes = 0;
        td->rate_bytes[0] = td->rate_bytes[1] = 0;
@@ -1167,19 +1179,17 @@ static void *thread_main(void *data)
        }
 
        fio_gettime(&td->epoch, NULL);
-       getrusage(RUSAGE_SELF, &td->ts.ru_start);
+       getrusage(RUSAGE_SELF, &td->ru_start);
 
        clear_state = 0;
        while (keep_running(td)) {
                fio_gettime(&td->start, NULL);
-               memcpy(&td->ts.stat_sample_time[0], &td->start,
-                               sizeof(td->start));
-               memcpy(&td->ts.stat_sample_time[1], &td->start,
-                               sizeof(td->start));
+               memcpy(&td->stat_sample_time[0], &td->start, sizeof(td->start));
+               memcpy(&td->stat_sample_time[1], &td->start, sizeof(td->start));
                memcpy(&td->tv_cache, &td->start, sizeof(td->start));
 
                if (td->o.ratemin[0] || td->o.ratemin[1])
-                       memcpy(&td->lastrate, &td->ts.stat_sample_time,
+                       memcpy(&td->lastrate, &td->stat_sample_time,
                                                        sizeof(td->lastrate));
 
                if (clear_state)
@@ -1228,40 +1238,40 @@ static void *thread_main(void *data)
        td->ts.io_bytes[1] = td->io_bytes[1];
 
        fio_mutex_down(writeout_mutex);
-       if (td->ts.bw_log) {
+       if (td->bw_log) {
                if (td->o.bw_log_file) {
-                       finish_log_named(td, td->ts.bw_log,
+                       finish_log_named(td, td->bw_log,
                                                td->o.bw_log_file, "bw");
                } else
-                       finish_log(td, td->ts.bw_log, "bw");
+                       finish_log(td, td->bw_log, "bw");
        }
-       if (td->ts.lat_log) {
+       if (td->lat_log) {
                if (td->o.lat_log_file) {
-                       finish_log_named(td, td->ts.lat_log,
+                       finish_log_named(td, td->lat_log,
                                                td->o.lat_log_file, "lat");
                } else
-                       finish_log(td, td->ts.lat_log, "lat");
+                       finish_log(td, td->lat_log, "lat");
        }
-       if (td->ts.slat_log) {
+       if (td->slat_log) {
                if (td->o.lat_log_file) {
-                       finish_log_named(td, td->ts.slat_log,
+                       finish_log_named(td, td->slat_log,
                                                td->o.lat_log_file, "slat");
                } else
-                       finish_log(td, td->ts.slat_log, "slat");
+                       finish_log(td, td->slat_log, "slat");
        }
-       if (td->ts.clat_log) {
+       if (td->clat_log) {
                if (td->o.lat_log_file) {
-                       finish_log_named(td, td->ts.clat_log,
+                       finish_log_named(td, td->clat_log,
                                                td->o.lat_log_file, "clat");
                } else
-                       finish_log(td, td->ts.clat_log, "clat");
+                       finish_log(td, td->clat_log, "clat");
        }
        fio_mutex_up(writeout_mutex);
        if (td->o.exec_postrun)
                exec_string(td->o.exec_postrun);
 
        if (exitall_on_terminate)
-               terminate_threads(td->groupid);
+               fio_terminate_threads(td->groupid);
 
 err:
        if (td->error)
@@ -1415,7 +1425,7 @@ reaped:
        }
 
        if (*nr_running == cputhreads && !pending && realthreads)
-               terminate_threads(TERMINATE_ALL);
+               fio_terminate_threads(TERMINATE_ALL);
 }
 
 static void *gtod_thread_main(void *data)
@@ -1477,6 +1487,8 @@ static void run_threads(void)
        if (fio_gtod_offload && fio_start_gtod_thread())
                return;
 
+       set_sig_handlers();
+
        if (!terse_output) {
                log_info("Starting ");
                if (nr_thread)
@@ -1492,8 +1504,6 @@ static void run_threads(void)
                fflush(stdout);
        }
 
-       set_sig_handlers();
-
        todo = thread_number;
        nr_running = 0;
        nr_started = 0;
@@ -1502,10 +1512,8 @@ static void run_threads(void)
        for_each_td(td, i) {
                print_status_init(td->thread_number - 1);
 
-               if (!td->o.create_serialize) {
-                       init_disk_util(td);
+               if (!td->o.create_serialize)
                        continue;
-               }
 
                /*
                 * do file setup here so it happens sequentially,
@@ -1533,8 +1541,6 @@ static void run_threads(void)
                                        td_io_close_file(td, f);
                        }
                }
-
-               init_disk_util(td);
        }
 
        set_genesis_time();
@@ -1573,6 +1579,8 @@ static void run_threads(void)
                                break;
                        }
 
+                       init_disk_util(td);
+
                        /*
                         * Set state to created. Thread will transition
                         * to TD_INITIALIZED when it's done setting up.
@@ -1611,7 +1619,7 @@ static void run_threads(void)
                        dprint(FD_MUTEX, "wait on startup_mutex\n");
                        if (fio_mutex_down_timeout(startup_mutex, 10)) {
                                log_err("fio: job startup hung? exiting.\n");
-                               terminate_threads(TERMINATE_ALL);
+                               fio_terminate_threads(TERMINATE_ALL);
                                fio_abort = 1;
                                nr_started--;
                                break;
@@ -1685,42 +1693,21 @@ static void run_threads(void)
 
        while (nr_running) {
                reap_threads(&nr_running, &t_rate, &m_rate);
-               usleep(10000);
+
+               if (is_backend)
+                       fio_server_idle_loop();
+               else
+                       usleep(10000);
        }
 
        update_io_ticks();
        fio_unpin_memory();
 }
 
-int main(int argc, char *argv[], char *envp[])
+int exec_run(void)
 {
-       long ps;
-
-       arch_init(envp);
-
-       sinit();
-
-       /*
-        * We need locale for number printing, if it isn't set then just
-        * go with the US format.
-        */
-       if (!getenv("LC_NUMERIC"))
-               setlocale(LC_NUMERIC, "en_US");
-
-       ps = sysconf(_SC_PAGESIZE);
-       if (ps < 0) {
-               log_err("Failed to get page size\n");
-               return 1;
-       }
-
-       page_size = ps;
-       page_mask = ps - 1;
-
-       fio_keywords_init();
-
-       if (parse_options(argc, argv))
-               return 1;
-
+       if (nr_clients)
+               return fio_handle_clients();
        if (exec_profile && load_profile(exec_profile))
                return 1;
 
@@ -1764,3 +1751,80 @@ int main(int argc, char *argv[], char *envp[])
        fio_mutex_remove(writeout_mutex);
        return exit_value;
 }
+
+void reset_fio_state(void)
+{
+       groupid = 0;
+       thread_number = 0;
+       nr_process = 0;
+       nr_thread = 0;
+       done_secs = 0;
+}
+
+static int endian_check(void)
+{
+       union {
+               uint8_t c[8];
+               uint64_t v;
+       } u;
+       int le = 0, be = 0;
+
+       u.v = 0x12;
+       if (u.c[7] == 0x12)
+               be = 1;
+       else if (u.c[0] == 0x12)
+               le = 1;
+
+#if defined(FIO_LITTLE_ENDIAN)
+       if (be)
+               return 1;
+#elif defined(FIO_BIG_ENDIAN)
+       if (le)
+               return 1;
+#else
+       return 1;
+#endif
+
+       if (!le && !be)
+               return 1;
+
+       return 0;
+}
+
+int main(int argc, char *argv[], char *envp[])
+{
+       long ps;
+
+       if (endian_check()) {
+               log_err("fio: endianness settings appear wrong.\n");
+               log_err("fio: please report this to fio@vger.kernel.org\n");
+               return 1;
+       }
+
+       arch_init(envp);
+
+       sinit();
+
+       /*
+        * We need locale for number printing, if it isn't set then just
+        * go with the US format.
+        */
+       if (!getenv("LC_NUMERIC"))
+               setlocale(LC_NUMERIC, "en_US");
+
+       ps = sysconf(_SC_PAGESIZE);
+       if (ps < 0) {
+               log_err("Failed to get page size\n");
+               return 1;
+       }
+
+       page_size = ps;
+       page_mask = ps - 1;
+
+       fio_keywords_init();
+
+       if (parse_options(argc, argv))
+               return 1;
+
+       return exec_run();
+}