Define SIGUSR1 to inform fio to dump run stats while continuing to run
authorJens Axboe <axboe@kernel.dk>
Fri, 30 Mar 2012 08:30:35 +0000 (10:30 +0200)
committerJens Axboe <axboe@kernel.dk>
Wed, 11 Apr 2012 20:04:55 +0000 (22:04 +0200)
For long running jobs, it may be interesting to see the stats without
having to terminate the job. Set up SIGUSR1 so that it does that,
gives you the stats at that point in time.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
backend.c
client.c
stat.c
stat.h

index 4c271ba92aba4e71493f53d1ba62c6c0da177240..f4bc553b0a5ee9dab880685f1844221975d4c64f 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -87,6 +87,11 @@ static void sig_int(int sig)
        }
 }
 
+static void sig_show_status(int sig)
+{
+       show_running_run_stats();
+}
+
 static void set_sig_handlers(void)
 {
        struct sigaction act;
@@ -101,6 +106,11 @@ static void set_sig_handlers(void)
        act.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &act, NULL);
 
+       memset(&act, 0, sizeof(act));
+       act.sa_handler = sig_show_status;
+       act.sa_flags = SA_RESTART;
+       sigaction(SIGUSR1, &act, NULL);
+
        if (is_backend) {
                memset(&act, 0, sizeof(act));
                act.sa_handler = sig_int;
index dd75882c54f3714db8d8ca37e7119b91be742a66..ee6765ed7adf9671c5cc131909e80ebe2e5abdff 100644 (file)
--- a/client.c
+++ b/client.c
@@ -344,6 +344,11 @@ static void sig_int(int sig)
        fio_clients_terminate();
 }
 
+static void sig_show_status(int sig)
+{
+       show_running_run_stats();
+}
+
 static void client_signal_handler(void)
 {
        struct sigaction act;
@@ -357,6 +362,11 @@ static void client_signal_handler(void)
        act.sa_handler = sig_int;
        act.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &act, NULL);
+
+       memset(&act, 0, sizeof(act));
+       act.sa_handler = sig_show_status;
+       act.sa_flags = SA_RESTART;
+       sigaction(SIGUSR1, &act, NULL);
 }
 
 static void probe_client(struct fio_client *client)
diff --git a/stat.c b/stat.c
index 7443e665deb6c5a2c1869920a5f022f25969e5d9..542e910606ff16043547aa57272bca45aa002b90 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -1106,6 +1106,55 @@ void show_run_stats(void)
        free(threadstats);
 }
 
+static void *__show_running_run_stats(void *arg)
+{
+       struct thread_data *td;
+       unsigned long long *rt;
+       struct timeval tv;
+       int i;
+
+       rt = malloc(thread_number * sizeof(unsigned long long));
+       fio_gettime(&tv, NULL);
+
+       for_each_td(td, i) {
+               rt[i] = mtime_since(&td->start, &tv);
+               if (td_read(td) && td->io_bytes[DDIR_READ])
+                       td->ts.runtime[DDIR_READ] += rt[i];
+               if (td_write(td) && td->io_bytes[DDIR_WRITE])
+                       td->ts.runtime[DDIR_WRITE] += rt[i];
+
+               update_rusage_stat(td);
+               td->ts.io_bytes[0] = td->io_bytes[0];
+               td->ts.io_bytes[1] = td->io_bytes[1];
+               td->ts.total_run_time = mtime_since(&td->epoch, &tv);
+       }
+
+       show_run_stats();
+
+       for_each_td(td, i) {
+               if (td_read(td) && td->io_bytes[DDIR_READ])
+                       td->ts.runtime[DDIR_READ] -= rt[i];
+               if (td_write(td) && td->io_bytes[DDIR_WRITE])
+                       td->ts.runtime[DDIR_WRITE] -= rt[i];
+       }
+
+       free(rt);
+       return NULL;
+}
+
+/*
+ * Called from signal handler. It _should_ be safe to just run this inline
+ * in the sig handler, but we should be disturbing the system less by just
+ * creating a thread to do it.
+ */
+void show_running_run_stats(void)
+{
+       pthread_t thread;
+
+       pthread_create(&thread, NULL, __show_running_run_stats, NULL);
+       pthread_detach(thread);
+}
+
 static inline void add_stat_sample(struct io_stat *is, unsigned long data)
 {
        double val = data;
diff --git a/stat.h b/stat.h
index 3115539fdb183ad57240f1b2ea8fe9cf27ba526e..be27c72c1990ac65fc18dc411b93b16ee2ed0d65 100644 (file)
--- a/stat.h
+++ b/stat.h
@@ -193,6 +193,7 @@ extern void show_group_stats(struct group_run_stats *rs);
 extern int calc_thread_status(struct jobs_eta *je, int force);
 extern void display_thread_status(struct jobs_eta *je);
 extern void show_run_stats(void);
+extern void show_running_run_stats(void);
 extern void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, int nr);
 extern void sum_group_stats(struct group_run_stats *dst, struct group_run_stats *src);
 extern void init_thread_stat(struct thread_stat *ts);