From 4c6d91e8808fd11f3cee663e42db813b0934c8bb Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 30 Mar 2012 10:30:35 +0200 Subject: [PATCH] Define SIGUSR1 to inform fio to dump run stats while continuing to run 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 --- backend.c | 10 ++++++++++ client.c | 10 ++++++++++ stat.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ stat.h | 1 + 4 files changed, 70 insertions(+) diff --git a/backend.c b/backend.c index 4c271ba9..f4bc553b 100644 --- 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; diff --git a/client.c b/client.c index dd75882c..ee6765ed 100644 --- 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 7443e665..542e9106 100644 --- 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 3115539f..be27c72c 100644 --- 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); -- 2.25.1