Fix: improve lttng with live by spawning relayd
authorDavid Goulet <dgoulet@efficios.com>
Fri, 28 Feb 2014 17:31:46 +0000 (12:31 -0500)
committerDavid Goulet <dgoulet@efficios.com>
Fri, 28 Feb 2014 17:31:46 +0000 (12:31 -0500)
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 <dgoulet@efficios.com>
src/bin/lttng-sessiond/cmd.c
src/bin/lttng/commands/create.c
src/bin/lttng/commands/view.c
src/bin/lttng/lttng.c
src/bin/lttng/utils.c
src/bin/lttng/utils.h

index 532af7d9917b733b33b59d6309f9a184417c6fbb..812c850faa73b9b4efb34b5030c6f46dd22c00d2 100644 (file)
@@ -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++;
        }
 }
index 2e03373266c2ca9c3d10f469bfb5da9ef3a5dfb6..a5f92f14a31c37ddddce57a925f4f2772cf3e38d 100644 (file)
@@ -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);
index d339282e61e7513b3559643d646f5d847a20bf24..adedf298966c0c7fad786f13bb34a66f4698a6de 100644 (file)
@@ -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) {
index dc9dd9241b9847eb12466fefdefa8120314321ad..6b926954da8c29a53f36f0eea7a1fbea79752d38 100644 (file)
@@ -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;
index 556728da23773f19935d0ea8b484a1b2cf901664..b40465b38ebef7d987381ad82a5353524ef57a7a 100644 (file)
 #include <stdlib.h>
 #include <ctype.h>
 #include <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include <common/error.h>
 #include <common/utils.h>
@@ -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;
+}
index 9dacbb20f09513be2b604fd0eb1e00c5a161fd0c..8b9d029f1806385660455c4d56ebf6e2a60ba930 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <lttng/lttng.h>
 
+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 */
This page took 0.040274 seconds and 5 git commands to generate.