From c04bdcb9d0ef773d58e798341285c78b5722b4ba Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Tue, 7 Jan 2014 16:06:27 -0800 Subject: [PATCH] Second try at printing statistics when processes are interrupted. When the client process gets interrupted, both the client and server dump out accumulated interval statistics, as well as a partial set of summary statistics (basically each side dumps what it has, but without the exchange of information that usually happens at the end of a normal run). If the server process gets interrupted, the server dumps out its accumulated interval and summary statistics as above. The client does this as well in the -R case, but exits with a "Broken pipe" in the non -R case (this behavior was present all along; it was not introduced in this change). More investigation will be needed to understand the client behavior. Bump copyright dates in a few places. Issue: 132 (signal handler for API calls) Discussed with: aaron@internet2.edu --- src/iperf_api.c | 19 ++++++++++++++++--- src/iperf_client_api.c | 10 ++++++++++ src/iperf_server_api.c | 10 +++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/iperf_api.c b/src/iperf_api.c index c540beb..163c779 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -2317,14 +2317,27 @@ iperf_catch_sigend(void (*handler)(int)) void iperf_got_sigend(struct iperf_test *test) { + /* + * If we're the client, or if we're a server and running a test, + * then dump out the accumulated stats so far. + */ + if (test->role == 'c' || + (test->role == 's' && test->state == TEST_RUNNING)) { + + test->done = 1; + cpu_util(test->cpu_util); + test->stats_callback(test); + test->state = DISPLAY_RESULTS; /* change local state only */ + if (test->on_test_finish) + test->on_test_finish(test); + test->reporter_callback(test); + } + if (test->ctrl_sck >= 0) { test->state = (test->role == 'c') ? CLIENT_TERMINATE : SERVER_TERMINATE; (void) Nwrite(test->ctrl_sck, (char*) &test->state, sizeof(signed char), Ptcp); } i_errno = (test->role == 'c') ? IECLIENTTERM : IESERVERTERM; - /* If the client, then dump JSON output if any */ - if (test->role == 'c') - iperf_client_end(test); iperf_errexit(test, "interrupt - %s", iperf_strerror(i_errno)); } diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c index f2e2a4e..8846247 100644 --- a/src/iperf_client_api.c +++ b/src/iperf_client_api.c @@ -221,6 +221,16 @@ iperf_handle_message_client(struct iperf_test *test) break; case SERVER_TERMINATE: i_errno = IESERVERTERM; + + /* + * Temporarily be in DISPLAY_RESULTS phase so we can get + * ending summary statistics. + */ + signed char oldstate = test->state; + cpu_util(test->cpu_util); + test->state = DISPLAY_RESULTS; + test->reporter_callback(test); + test->state = oldstate; return -1; case ACCESS_DENIED: i_errno = IEACCESSDENIED; diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index 659502f..f490fc4 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2011, The Regents of the University of California, + * Copyright (c) 2009-2014, The Regents of the University of California, * through Lawrence Berkeley National Laboratory (subject to receipt of any * required approvals from the U.S. Dept. of Energy). All rights reserved. * @@ -204,6 +204,14 @@ iperf_handle_message_server(struct iperf_test *test) case CLIENT_TERMINATE: i_errno = IECLIENTTERM; + // Temporarily be in DISPLAY_RESULTS phase so we can get + // ending summary statistics. + signed char oldstate = test->state; + cpu_util(test->cpu_util); + test->state = DISPLAY_RESULTS; + test->reporter_callback(test); + test->state = oldstate; + // XXX: Remove this line below! iperf_err(test, "the client has terminated"); SLIST_FOREACH(sp, &test->streams, streams) {