From 8960e9cd5adb7e5cdaece135530a457cd65324dc Mon Sep 17 00:00:00 2001 From: David Goulet Date: Fri, 28 Feb 2014 12:31:46 -0500 Subject: [PATCH] Fix: improve lttng with live by spawning relayd The create --live, will try to spawn a default relayd if no URL is given. The lttng view now supports the live tracing mode thus lttng view is usable with a live session. Fixes #738 Signed-off-by: David Goulet --- src/bin/lttng-sessiond/cmd.c | 1 + src/bin/lttng/commands/create.c | 10 ++++ src/bin/lttng/commands/view.c | 80 +++++++++++++++++++++++++--- src/bin/lttng/lttng.c | 8 +++ src/bin/lttng/utils.c | 94 +++++++++++++++++++++++++++++++++ src/bin/lttng/utils.h | 5 ++ 6 files changed, 190 insertions(+), 8 deletions(-) diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 532af7d99..812c850fa 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -2506,6 +2506,7 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions, uid_t uid, sessions[i].name[NAME_MAX - 1] = '\0'; sessions[i].enabled = session->enabled; sessions[i].snapshot_mode = session->snapshot_mode; + sessions[i].live_timer_interval = session->live_timer; i++; } } diff --git a/src/bin/lttng/commands/create.c b/src/bin/lttng/commands/create.c index 2e0337326..a5f92f14a 100644 --- a/src/bin/lttng/commands/create.c +++ b/src/bin/lttng/commands/create.c @@ -376,6 +376,16 @@ static int create_session(void) } ret = lttng_create_session_snapshot(session_name, snapshot_url); } else if (opt_live_timer) { + const char *pathname; + + if (opt_relayd_path) { + pathname = opt_relayd_path; + } else { + pathname = INSTALL_BIN_PATH "/lttng-relayd"; + } + if (!check_relayd() && spawn_relayd(pathname, 0) < 0) { + goto error; + } ret = lttng_create_session_live(session_name, url, opt_live_timer); } else { ret = _lttng_create_session_ext(session_name, url, datetime, -1); diff --git a/src/bin/lttng/commands/view.c b/src/bin/lttng/commands/view.c index d339282e6..adedf2989 100644 --- a/src/bin/lttng/commands/view.c +++ b/src/bin/lttng/commands/view.c @@ -76,6 +76,9 @@ static struct viewers { { NULL, VIEWER_USER_DEFINED }, }; +/* Is the session we are trying to view is in live mode. */ +static int session_live_mode; + /* * usage */ @@ -179,20 +182,38 @@ static char **alloc_argv_from_local_opts(const char **opts, size_t opts_len, const char *trace_path) { char **argv; - size_t size; + size_t size, mem_len; + + + /* Add one for the NULL terminating element. */ + mem_len = opts_len + 1; + if (session_live_mode) { + /* Add 3 option for the live mode being "-i lttng-live URL". */ + mem_len += 3; + } else { + /* Add option for the trace path. */ + mem_len += 1; + } - size = sizeof(char *) * opts_len; + size = sizeof(char *) * mem_len; /* Add two here for the trace_path and the NULL terminating element. */ - argv = malloc(size + 2); + argv = malloc(size); if (argv == NULL) { goto error; } memcpy(argv, opts, size); - argv[opts_len] = (char *)trace_path; - argv[opts_len + 1] = NULL; + if (session_live_mode) { + argv[opts_len] = "-i"; + argv[opts_len + 1] = "lttng-live"; + argv[opts_len + 2] = (char *) trace_path; + argv[opts_len + 3] = NULL; + } else { + argv[opts_len] = (char *) trace_path; + argv[opts_len + 1] = NULL; + } error: return argv; @@ -273,13 +294,39 @@ error: return ret; } +/* + * Build the live path we need for the lttng live view. + */ +static char *build_live_path(char *session_name) +{ + int ret; + char *path = NULL; + char hostname[HOST_NAME_MAX]; + + ret = gethostname(hostname, sizeof(hostname)); + if (ret < 0) { + perror("gethostname"); + goto error; + } + + ret = asprintf(&path, "net://localhost/host/%s/%s", hostname, + session_name); + if (ret < 0) { + perror("asprintf live path"); + goto error; + } + +error: + return path; +} + /* * Exec viewer if found and use session name path. */ static int view_trace(void) { int ret; - char *session_name, *trace_path; + char *session_name, *trace_path = NULL; struct lttng_session *sessions = NULL; /* @@ -340,14 +387,28 @@ static int view_trace(void) goto free_sessions; } - trace_path = sessions[i].path; + session_live_mode = sessions[i].live_timer_interval; + + DBG("Session live mode set to %d", session_live_mode); - if (sessions[i].enabled) { + if (sessions[i].enabled && !session_live_mode) { WARN("Session %s is running. Please stop it before reading it.", session_name); ret = CMD_ERROR; goto free_sessions; } + + /* If the timer interval is set we are in live mode. */ + if (session_live_mode) { + trace_path = build_live_path(session_name); + if (!trace_path) { + ret = CMD_ERROR; + goto free_sessions; + } + } else { + /* Get file system session path. */ + trace_path = sessions[i].path; + } } else { trace_path = opt_trace_path; } @@ -361,6 +422,9 @@ static int view_trace(void) } free_sessions: + if (session_live_mode) { + free(trace_path); + } free(sessions); free_error: if (opt_session_name == NULL) { diff --git a/src/bin/lttng/lttng.c b/src/bin/lttng/lttng.c index dc9dd9241..6b926954d 100644 --- a/src/bin/lttng/lttng.c +++ b/src/bin/lttng/lttng.c @@ -39,7 +39,10 @@ static char *opt_sessiond_path; static pid_t sessiond_pid; static volatile int recv_child_signal; +char *opt_relayd_path; + enum { + OPT_RELAYD_PATH, OPT_SESSION_PATH, OPT_DUMP_OPTIONS, OPT_DUMP_COMMANDS, @@ -54,6 +57,7 @@ static struct option long_options[] = { {"quiet", 0, NULL, 'q'}, {"no-sessiond", 0, NULL, 'n'}, {"sessiond-path", 1, NULL, OPT_SESSION_PATH}, + {"relayd-path", 1, NULL, OPT_RELAYD_PATH}, {"list-options", 0, NULL, OPT_DUMP_OPTIONS}, {"list-commands", 0, NULL, OPT_DUMP_COMMANDS}, {NULL, 0, NULL, 0} @@ -96,6 +100,7 @@ static void usage(FILE *ofp) fprintf(ofp, " -g, --group NAME Unix tracing group name. (default: tracing)\n"); fprintf(ofp, " -n, --no-sessiond Don't spawn a session daemon\n"); fprintf(ofp, " --sessiond-path PATH Session daemon full path\n"); + fprintf(ofp, " --relayd-path PATH Relayd daemon full path\n"); fprintf(ofp, "\n"); fprintf(ofp, "Commands:\n"); fprintf(ofp, " add-context Add context to event and/or channel\n"); @@ -442,6 +447,9 @@ static int parse_args(int argc, char **argv) case OPT_SESSION_PATH: opt_sessiond_path = strdup(optarg); break; + case OPT_RELAYD_PATH: + opt_relayd_path = strdup(optarg); + break; case OPT_DUMP_OPTIONS: list_options(stdout); ret = 0; diff --git a/src/bin/lttng/utils.c b/src/bin/lttng/utils.c index 556728da2..b40465b38 100644 --- a/src/bin/lttng/utils.c +++ b/src/bin/lttng/utils.c @@ -20,6 +20,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -276,3 +281,92 @@ const char *get_domain_str(enum lttng_domain_type domain) return str_dom; } + +/* + * Spawn a lttng relayd daemon by forking and execv. + */ +int spawn_relayd(const char *pathname, int port) +{ + int ret = 0; + pid_t pid; + char url[255]; + + if (!port) { + port = DEFAULT_NETWORK_VIEWER_PORT; + } + + ret = snprintf(url, sizeof(url), "tcp://localhost:%d", port); + if (ret < 0) { + goto end; + } + + MSG("Spawning a relayd daemon"); + pid = fork(); + if (pid == 0) { + /* + * Spawn session daemon and tell + * it to signal us when ready. + */ + execlp(pathname, "lttng-relayd", "-L", url, NULL); + /* execlp only returns if error happened */ + if (errno == ENOENT) { + ERR("No relayd found. Use --relayd-path."); + } else { + perror("execlp"); + } + kill(getppid(), SIGTERM); /* wake parent */ + exit(EXIT_FAILURE); + } else if (pid > 0) { + goto end; + } else { + perror("fork"); + ret = -1; + goto end; + } + +end: + return ret; +} + +/* + * Check if relayd is alive. + * + * Return 1 if found else 0 if NOT found. Negative value on error. + */ +int check_relayd(void) +{ + int ret, fd; + struct sockaddr_in sin; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + perror("socket check relayd"); + goto error; + } + + sin.sin_family = AF_INET; + sin.sin_port = htons(DEFAULT_NETWORK_VIEWER_PORT); + ret = inet_pton(sin.sin_family, "127.0.0.1", &sin.sin_addr); + if (ret < 1) { + perror("inet_pton check relayd"); + goto error; + } + + /* + * A successful connect means the relayd exists thus returning 0 else a + * negative value means it does NOT exists. + */ + ret = connect(fd, &sin, sizeof(sin)); + if (ret < 0) { + /* Not found. */ + ret = 0; + } else { + /* Already spawned. */ + ret = 1; + } + + return ret; + +error: + return -1; +} diff --git a/src/bin/lttng/utils.h b/src/bin/lttng/utils.h index 9dacbb20f..8b9d029f1 100644 --- a/src/bin/lttng/utils.h +++ b/src/bin/lttng/utils.h @@ -22,6 +22,8 @@ #include +extern char *opt_relayd_path; + struct cmd_struct; char *get_session_name(void); @@ -54,4 +56,7 @@ void print_missing_domain(void) ERR("Please specify a domain (-k/-u/-j)."); } +int spawn_relayd(const char *pathname, int port); +int check_relayd(void); + #endif /* _LTTNG_UTILS_H */ -- 2.34.1