When verify fails, dump the good/bad blocks to files
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index 91bf6b613cac30403ff9c7ec96865a2b56051103..e475a36f678673fe809612c588a9f93bf27817e9 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
+#include <limits.h>
 #include <signal.h>
 #include <time.h>
 #include <locale.h>
@@ -101,12 +102,12 @@ static void terminate_threads(int group_id)
                         * if the thread is running, just let it exit
                         */
                        if (td->runstate < TD_RUNNING)
-                               kill(td->pid, SIGQUIT);
+                               kill(td->pid, SIGTERM);
                        else {
                                struct ioengine_ops *ops = td->io_ops;
 
-                               if (ops && (ops->flags & FIO_SIGQUIT))
-                                       kill(td->pid, SIGQUIT);
+                               if (ops && (ops->flags & FIO_SIGTERM))
+                                       kill(td->pid, SIGTERM);
                        }
                }
        }
@@ -161,8 +162,9 @@ static void posix_timer_setup(void)
        evt.sigev_notify = SIGEV_THREAD;
        evt.sigev_notify_function = ival_fn;
 
-       if (timer_create(CLOCK_MONOTONIC, &evt, &ival_timer) < 0)
+       if (timer_create(FIO_TIMER_CLOCK, &evt, &ival_timer) < 0)
                perror("timer_create");
+
 }
 
 static void set_sig_handlers(void)
@@ -177,7 +179,7 @@ static void set_sig_handlers(void)
        memset(&act, 0, sizeof(act));
        act.sa_handler = sig_quit;
        act.sa_flags = SA_RESTART;
-       sigaction(SIGQUIT, &act, NULL);
+       sigaction(SIGTERM, &act, NULL);
 }
 
 /*
@@ -863,7 +865,7 @@ static int init_io_u(struct thread_data *td)
                                 * Fill the buffer with the pattern if we are
                                 * going to be doing writes.
                                 */
-                               fill_pattern(td, io_u->buf, max_bs, io_u);
+                               fill_pattern(td, io_u->buf, max_bs, io_u, 0, 0);
                        }
                }
 
@@ -987,8 +989,10 @@ void reset_all_stats(struct thread_data *td)
                td->io_issues[i] = 0;
                td->ts.total_io_u[i] = 0;
        }
-       
+
        fio_gettime(&tv, NULL);
+       td->ts.runtime[0] = 0;
+       td->ts.runtime[1] = 0;
        memcpy(&td->epoch, &tv, sizeof(tv));
        memcpy(&td->start, &tv, sizeof(tv));
 }
@@ -1027,7 +1031,7 @@ static int exec_string(const char *string)
  */
 static void *thread_main(void *data)
 {
-       unsigned long long runtime[2], elapsed;
+       unsigned long long elapsed;
        struct thread_data *td = data;
        pthread_condattr_t attr;
        int clear_state;
@@ -1066,14 +1070,18 @@ static void *thread_main(void *data)
         */
        fio_mutex_remove(td->mutex);
 
-       if (td->o.uid != -1U && setuid(td->o.uid)) {
-               td_verror(td, errno, "setuid");
-               goto err;
-       }
+       /*
+        * A new gid requires privilege, so we need to do this before setting
+        * the uid.
+        */
        if (td->o.gid != -1U && setgid(td->o.gid)) {
                td_verror(td, errno, "setgid");
                goto err;
        }
+       if (td->o.uid != -1U && setuid(td->o.uid)) {
+               td_verror(td, errno, "setuid");
+               goto err;
+       }
 
        /*
         * May alter parameters that init_io_u() will use, so we need to
@@ -1145,7 +1153,6 @@ static void *thread_main(void *data)
        fio_gettime(&td->epoch, NULL);
        getrusage(RUSAGE_SELF, &td->ts.ru_start);
 
-       runtime[0] = runtime[1] = 0;
        clear_state = 0;
        while (keep_running(td)) {
                fio_gettime(&td->start, NULL);
@@ -1170,11 +1177,11 @@ static void *thread_main(void *data)
 
                if (td_read(td) && td->io_bytes[DDIR_READ]) {
                        elapsed = utime_since_now(&td->start);
-                       runtime[DDIR_READ] += elapsed;
+                       td->ts.runtime[DDIR_READ] += elapsed;
                }
                if (td_write(td) && td->io_bytes[DDIR_WRITE]) {
                        elapsed = utime_since_now(&td->start);
-                       runtime[DDIR_WRITE] += elapsed;
+                       td->ts.runtime[DDIR_WRITE] += elapsed;
                }
 
                if (td->error || td->terminate)
@@ -1191,15 +1198,15 @@ static void *thread_main(void *data)
 
                do_verify(td);
 
-               runtime[DDIR_READ] += utime_since_now(&td->start);
+               td->ts.runtime[DDIR_READ] += utime_since_now(&td->start);
 
                if (td->error || td->terminate)
                        break;
        }
 
        update_rusage_stat(td);
-       td->ts.runtime[0] = (runtime[0] + 999) / 1000;
-       td->ts.runtime[1] = (runtime[1] + 999) / 1000;
+       td->ts.runtime[0] = (td->ts.runtime[0] + 999) / 1000;
+       td->ts.runtime[1] = (td->ts.runtime[1] + 999) / 1000;
        td->ts.total_run_time = mtime_since_now(&td->epoch);
        td->ts.io_bytes[0] = td->io_bytes[0];
        td->ts.io_bytes[1] = td->io_bytes[1];
@@ -1351,7 +1358,7 @@ static void reap_threads(int *nr_running, int *t_rate, int *m_rate)
                        if (WIFSIGNALED(status)) {
                                int sig = WTERMSIG(status);
 
-                               if (sig != SIGQUIT)
+                               if (sig != SIGTERM)
                                        log_err("fio: pid=%d, got signal=%d\n",
                                                        (int) td->pid, sig);
                                td_set_runstate(td, TD_REAPED);
@@ -1702,7 +1709,11 @@ int main(int argc, char *argv[])
        }
 
        startup_mutex = fio_mutex_init(0);
+       if (startup_mutex == NULL)
+               return 1;
        writeout_mutex = fio_mutex_init(1);
+       if (writeout_mutex == NULL)
+               return 1;
 
        set_genesis_time();