From 38ee087f699718e57d1bc5614c2f79c3c30ccca9 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 17 Oct 2012 13:40:49 -0400 Subject: [PATCH] Wait for data availability when stopping a session The lttng_stop_tracing now waits by default for data availability. A status output is added in the library on stdout. A no wait version is added to the API and the option no-wait is added to the lttng command line for the stop command. Also good to note that if a second stop_tracing call is done on an already stopped session, the call will wait for data availability before returning if the stop command on the session daemon returned an already stopped error code. Signed-off-by: David Goulet --- include/lttng/lttng.h | 11 +++++++ src/bin/lttng/commands/stop.c | 9 +++++- src/common/defaults.h | 6 ++++ src/lib/lttng-ctl/lttng-ctl.c | 60 +++++++++++++++++++++++++++++++---- 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 4171cde41..0a12d9be7 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -472,9 +472,20 @@ extern int lttng_start_tracing(const char *session_name); /* * Stop tracing for *all* registered traces (kernel and user-space). + * + * This call will wait for data availability for each domain of the session so + * this can take an abritrary amount of time. However, when returning you have + * the guarantee that the data is ready to be read and analyse. Use the + * _no_wait call below to avoid this behavior. */ extern int lttng_stop_tracing(const char *session_name); +/* + * Behave exactly like lttng_stop_tracing but does not wait for data + * availability. + */ +extern int lttng_stop_tracing_no_wait(const char *session_name); + /* * Add context to event(s) for a specific channel (or for all). * diff --git a/src/bin/lttng/commands/stop.c b/src/bin/lttng/commands/stop.c index 7c89e37e5..60a1dac8f 100644 --- a/src/bin/lttng/commands/stop.c +++ b/src/bin/lttng/commands/stop.c @@ -29,6 +29,7 @@ #include static char *opt_session_name; +static int opt_no_wait; enum { OPT_HELP = 1, @@ -39,6 +40,7 @@ static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL}, + {"no-wait", 'n', POPT_ARG_VAL, &opt_no_wait, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0} }; @@ -55,6 +57,7 @@ static void usage(FILE *ofp) fprintf(ofp, "Options:\n"); fprintf(ofp, " -h, --help Show this help\n"); fprintf(ofp, " --list-options Simple listing of options\n"); + fprintf(ofp, " -n, --no-wait Don't wait for data availability\n"); fprintf(ofp, "\n"); } @@ -76,7 +79,11 @@ static int stop_tracing(void) session_name = opt_session_name; } - ret = lttng_stop_tracing(session_name); + if (opt_no_wait) { + ret = lttng_stop_tracing_no_wait(session_name); + } else { + ret = lttng_stop_tracing(session_name); + } if (ret < 0) { switch (-ret) { case LTTNG_ERR_TRACE_ALREADY_STOPPED: diff --git a/src/common/defaults.h b/src/common/defaults.h index ad1b708a3..8bb1190e7 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -140,4 +140,10 @@ #define DEFAULT_HEALTH_CHECK_DELTA_S 20 #define DEFAULT_HEALTH_CHECK_DELTA_NS 0 +/* + * Wait period before retrying the lttng_data_available command in the lttng + * stop command of liblttng-ctl. + */ +#define DEFAULT_DATA_AVAILABILITY_WAIT_TIME 200000 /* usec */ + #endif /* _DEFAULTS_H */ diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index c6238e11c..67c597219 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -69,8 +69,6 @@ static int connected; * Those two variables are used by error.h to silent or control the verbosity of * error message. They are global to the library so application linking with it * are able to compile correctly and also control verbosity of the library. - * - * Note that it is *not* possible to silent ERR() and PERROR() macros. */ int lttng_opt_quiet; int lttng_opt_verbose; @@ -682,11 +680,11 @@ int lttng_start_tracing(const char *session_name) } /* - * Stop tracing for all traces of the session. - * Returns size of returned session payload data or a negative error code. + * Stop tracing for all traces of the session. */ -int lttng_stop_tracing(const char *session_name) +static int _lttng_stop_tracing(const char *session_name, int wait) { + int ret, data_ret; struct lttcomm_session_msg lsm; if (session_name == NULL) { @@ -697,7 +695,57 @@ int lttng_stop_tracing(const char *session_name) copy_string(lsm.session.name, session_name, sizeof(lsm.session.name)); - return ask_sessiond(&lsm, NULL); + ret = ask_sessiond(&lsm, NULL); + if (ret < 0 && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) { + goto error; + } + + if (!wait) { + goto end; + } + + _MSG("Waiting for data availability"); + + /* Check for data availability */ + do { + data_ret = lttng_data_available(session_name); + if (data_ret < 0) { + /* Return the data available call error. */ + ret = data_ret; + goto error; + } + + /* + * Data sleep time before retrying (in usec). Don't sleep if the call + * returned value indicates availability. + */ + if (!data_ret) { + usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME); + _MSG("."); + } + } while (data_ret != 1); + + MSG(""); + +end: +error: + return ret; +} + +/* + * Stop tracing and wait for data availability. + */ +int lttng_stop_tracing(const char *session_name) +{ + return _lttng_stop_tracing(session_name, 1); +} + +/* + * Stop tracing but _don't_ wait for data availability. + */ +int lttng_stop_tracing_no_wait(const char *session_name) +{ + return _lttng_stop_tracing(session_name, 0); } /* -- 2.34.1