Gently prod children with a SIGQUIT on terminate
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index b095527e4d028d18ab30d185a7b25c4a93eba7ab..d426ad66f9439a4d5da5f14092d3db8f5b4d628d 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -67,6 +67,7 @@ static void terminate_threads(int group_id, int forced_kill)
 
        for_each_td(td, i) {
                if (group_id == TERMINATE_ALL || groupid == td->groupid) {
+                       kill(td->pid, SIGQUIT);
                        td->terminate = 1;
                        td->start_delay = 0;
                        if (forced_kill)
@@ -100,6 +101,12 @@ static int check_min_rate(struct thread_data *td, struct timeval *now)
        unsigned long spent;
        unsigned long rate;
 
+       /*
+        * No minimum rate set, always ok
+        */
+       if (!td->ratemin)
+               return 0;
+
        /*
         * allow a 2 second settle period in the beginning
         */
@@ -237,7 +244,7 @@ requeue:
 }
 
 /*
- * The main verify engine. Runs over the writes we previusly submitted,
+ * The main verify engine. Runs over the writes we previously submitted,
  * reads the blocks back in, and checks the crc/md5 of the data.
  */
 static void do_verify(struct thread_data *td)
@@ -264,6 +271,8 @@ static void do_verify(struct thread_data *td)
 
        io_u = NULL;
        while (!td->terminate) {
+               int ret2;
+
                io_u = __get_io_u(td);
                if (!io_u)
                        break;
@@ -291,7 +300,7 @@ requeue:
                case FIO_Q_COMPLETED:
                        if (io_u->error)
                                ret = -io_u->error;
-                       if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
+                       else if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
                                int bytes = io_u->xfer_buflen - io_u->resid;
 
                                io_u->xfer_buflen = io_u->resid;
@@ -306,7 +315,9 @@ requeue:
                        break;
                case FIO_Q_BUSY:
                        requeue_io_u(td, &io_u);
-                       ret = td_io_commit(td);
+                       ret2 = td_io_commit(td);
+                       if (ret2 < 0)
+                               ret = ret2;
                        break;
                default:
                        assert(ret < 0);
@@ -390,6 +401,7 @@ static void do_io(struct thread_data *td)
                long bytes_done = 0;
                int min_evts = 0;
                struct io_u *io_u;
+               int ret2;
 
                if (td->terminate)
                        break;
@@ -409,11 +421,9 @@ requeue:
 
                switch (ret) {
                case FIO_Q_COMPLETED:
-                       if (io_u->error) {
-                               ret = io_u->error;
-                               break;
-                       }
-                       if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
+                       if (io_u->error)
+                               ret = -io_u->error;
+                       else if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
                                int bytes = io_u->xfer_buflen - io_u->resid;
 
                                io_u->xfer_buflen = io_u->resid;
@@ -436,7 +446,9 @@ requeue:
                        break;
                case FIO_Q_BUSY:
                        requeue_io_u(td, &io_u);
-                       ret = td_io_commit(td);
+                       ret2 = td_io_commit(td);
+                       if (ret2 < 0)
+                               ret = ret2;
                        break;
                default:
                        assert(ret < 0);
@@ -882,7 +894,8 @@ static void reap_threads(int *nr_running, int *t_rate, int *m_rate)
                        if (WIFSIGNALED(status)) {
                                int sig = WTERMSIG(status);
 
-                               log_err("fio: pid=%d, got signal=%d\n", td->pid, sig);
+                               if (sig != SIGQUIT)
+                                       log_err("fio: pid=%d, got signal=%d\n", td->pid, sig);
                                td_set_runstate(td, TD_REAPED);
                                goto reaped;
                        }