From b852e7cf097cec1c7fb92305f9c3c6b394bb39ad 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 75cb18b8..62df0ec3 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 5b5d60a3..5dcc5f54 100644 --- a/client.c +++ b/client.c @@ -401,6 +401,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; @@ -414,6 +419,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 int send_client_cmd_line(struct fio_client *client) diff --git a/stat.c b/stat.c index 7e2ab36c..37127839 100644 --- a/stat.c +++ b/stat.c @@ -1073,6 +1073,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 ce640d9c..cbbbf44a 100644 --- a/stat.h +++ b/stat.h @@ -196,6 +196,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