Command to automatically create a local session with all the right parameters
authorJulien Desfossez <jdesfossez@efficios.com>
Tue, 18 Feb 2014 20:22:08 +0000 (15:22 -0500)
committerJulien Desfossez <jdesfossez@efficios.com>
Tue, 18 Feb 2014 20:22:08 +0000 (15:22 -0500)
Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
src/Makefile.am
src/lttng-session.c [new file with mode: 0644]
src/lttng-session.h [new file with mode: 0644]
src/lttngtop.c

index ada47c85c4044c924ff603a2ffc4ebdb16aac816..9fe970d9694d17010750fd90a5ac1b10ce06fb6e 100644 (file)
@@ -18,6 +18,7 @@ noinst_HEADERS = \
        lttng-live-comm.h \
        lttng-viewer-abi.h \
        lttngtop.h \
+       lttng-session.h \
        $(top_builddir)/lib/babeltrace/format.h \
        $(top_builddir)/lib/babeltrace/compat/memstream.h \
        $(top_builddir)/lib/babeltrace/compat/string.h \
@@ -61,7 +62,8 @@ lttngtop_SOURCES = \
        cursesdisplay.c \
        cputop.c \
        iostreamtop.c \
-       mmap-live.c
+       mmap-live.c \
+       lttng-session.c
 
 lttngtop_LDFLAGS = -Wl,--no-as-needed
 
diff --git a/src/lttng-session.c b/src/lttng-session.c
new file mode 100644 (file)
index 0000000..29676f3
--- /dev/null
@@ -0,0 +1,401 @@
+#define _GNU_SOURCE         /* See feature_test_macros(7) */
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#define event_list "lttng_statedump_start,lttng_statedump_end," \
+       "lttng_statedump_process_state,lttng_statedump_file_descriptor," \
+       "lttng_statedump_vm_map,lttng_statedump_network_interface," \
+       "lttng_statedump_interrupt,sched_process_free," \
+       "sched_switch,sched_process_fork"
+#define context_list "-t pid -t procname -t tid -t ppid "
+
+static
+int check_or_start_sessiond()
+{
+       int ret;
+       int sudo = 0;
+
+       ret = system("pgrep -u root lttng-sessiond >/dev/null");
+       if (ret == 0)
+               goto end;
+
+       if (getuid() != 0) {
+               fprintf(stderr, "Trying to start lttng-sessiond with sudo\n");
+               ret = system("sudo -l lttng-sessiond >/dev/null");
+               if (ret < 0) {
+                       fprintf(stderr, "[error] You are not root and not "
+                                       "allowed by sudo to start lttng-sessiond\n");
+                       ret = -1;
+                       goto end;
+               }
+               sudo = 1;
+       }
+
+       if (sudo)
+               ret = system("sudo lttng-sessiond -d");
+       else
+               ret = system("lttng-sessiond -d");
+
+       if (ret != 0) {
+               fprintf(stderr, "Error starting lttng-sessiond as root\n");
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int check_or_start_relayd()
+{
+       int ret;
+
+       ret = system("pgrep lttng-relayd >/dev/null");
+       if (ret == 0)
+               goto end;
+
+       ret = system("lttng-relayd -d");
+       if (ret != 0) {
+               fprintf(stderr, "Error starting lttng-relayd\n");
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+/*
+ * Return 0 if in tracing group or root, 1 if sudo is needed (and working),
+ * a negative value on error.
+ */
+static
+int check_tracing_group()
+{
+       int ret;
+
+       ret = getuid();
+       if (ret == 0)
+               goto end;
+
+       ret = system("groups|grep tracing >/dev/null");
+       if (ret == 0) {
+               goto end;
+       }
+
+       ret = system("sudo lttng --version >/dev/null");
+       if (ret != 0) {
+               fprintf(stderr, "Error executing lttng with sudo, you need to "
+                               "be root or in the \"tracing\" group to start "
+                               "kernel tracing\n");
+               ret = -1;
+               goto end;
+       } else {
+               ret = 1;
+       }
+
+end:
+       return ret;
+}
+
+static
+int check_lttng_modules(int sudo)
+{
+       int ret;
+
+       if (sudo) {
+               ret = system("sudo lttng list -k | grep sched_switch >/dev/null");
+       } else {
+               ret = system("lttng list -k | grep sched_switch >/dev/null");
+       }
+       if (ret != 0) {
+               fprintf(stderr, "Error listing kernel events, "
+                               "lttng-modules might not be installed\n");
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int check_requirements(int *sudo)
+{
+       int ret;
+
+       ret = check_or_start_sessiond();
+       if (ret < 0)
+               goto end;
+       ret = check_or_start_relayd();
+       if (ret < 0)
+               goto end;
+       ret = check_tracing_group();
+       if (ret < 0)
+               goto end;
+       else if (ret == 1)
+               *sudo = 1;
+
+       ret = check_lttng_modules(*sudo);
+       if (ret < 0)
+               goto end;
+end:
+       return ret;
+}
+
+/*
+ * Allocate a random string, must be freed by the caller.
+ */
+static
+char *random_session_name()
+{
+       uint64_t id;
+       char *str = NULL;
+       int ret;
+
+       FILE *f = fopen( "/dev/urandom", "r");
+       if (!f) {
+               perror("fopen");
+               goto end;
+       }
+
+       ret = fread(&id, 1, sizeof(uint64_t), f);
+       if (ret < sizeof(id)) {
+               perror("fread");
+               goto end;
+       }
+
+       ret = asprintf(&str, "lttngtop-%" PRIu64, id);
+       if (ret < 0) {
+               fprintf(stderr, "Error allocating session name");
+               str = NULL;
+               goto end;
+       }
+
+       ret = fclose(f);
+       if (ret != 0) {
+               perror("fclose");
+               goto end;
+       }
+
+end:
+       return str;
+}
+
+static
+int check_session_name(char *name, int sudo)
+{
+       int ret;
+       char cmd[1024];
+
+       ret = sprintf(cmd, "%s lttng list | grep %s >/dev/null",
+                       (sudo) ? "sudo" : " ", name);
+       if (ret < 0) {
+               fprintf(stderr, "Allocating cmd\n");
+               goto end;
+       }
+
+       ret = (system(cmd));
+       if (ret == 0) {
+               fprintf(stderr, "Error: session %s already exist, either we "
+                               "are not random enough or something is "
+                               "really wrong\n", name);
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int local_session(char *name, int sudo)
+{
+       int ret;
+       char cmd[1024];
+
+       ret = sprintf(cmd, "%s lttng create %s >/dev/null",
+                       (sudo) ? "sudo" : " ", name);
+       if (ret < 0) {
+               fprintf(stderr, "Allocating cmd\n");
+               goto end;
+       }
+       ret = (system(cmd));
+       if (ret != 0) {
+               fprintf(stderr, "Error: creating the session\n");
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int enable_event(char *name, int sudo)
+{
+       int ret;
+       char cmd[1024];
+
+       ret = sprintf(cmd, "%s lttng enable-event -s %s -k %s >/dev/null",
+                       (sudo) ? "sudo" : " ", name, event_list);
+       if (ret < 0) {
+               fprintf(stderr, "Allocating cmd\n");
+               goto end;
+       }
+
+       ret = (system(cmd));
+       if (ret != 0) {
+               fprintf(stderr, "Error: enabling events\n");
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int add_contexts(char *name, int sudo)
+{
+       int ret;
+       char cmd[1024];
+
+       ret = sprintf(cmd, "%s lttng add-context -s %s -k %s >/dev/null",
+                       (sudo) ? "sudo" : " ", name, context_list);
+       if (ret < 0) {
+               fprintf(stderr, "allocating cmd\n");
+               goto end;
+       }
+
+       ret = (system(cmd));
+       if (ret != 0) {
+               fprintf(stderr, "error: adding contexts\n");
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int start(char *name, int sudo)
+{
+       int ret;
+       char cmd[1024];
+
+       ret = sprintf(cmd, "%s lttng start %s >/dev/null",
+                       (sudo) ? "sudo" : " ", name);
+       if (ret < 0) {
+               fprintf(stderr, "allocating cmd\n");
+               goto end;
+       }
+
+       ret = (system(cmd));
+       if (ret != 0) {
+               fprintf(stderr, "error: starting the session %s\n", name);
+               ret = -1;
+               goto end;
+       }
+
+       ret = sprintf(cmd, "%s lttng list|grep %s|cut -d'(' -f2|cut -d ')' -f1",
+                       (sudo) ? "sudo" : " ", name);
+       if (ret < 0) {
+               fprintf(stderr, "allocating cmd\n");
+               goto end;
+       }
+       fprintf(stderr, "Local session started in ");
+       ret = (system(cmd));
+       if (ret != 0) {
+               fprintf(stderr, "error: listing the sessions\n");
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int destroy(char *name, int sudo)
+{
+       int ret;
+       char cmd[1024];
+
+       ret = sprintf(cmd, "%s lttng destroy %s >/dev/null",
+                       (sudo) ? "sudo" : " ", name);
+       if (ret < 0) {
+               fprintf(stderr, "allocating cmd\n");
+               goto end;
+       }
+
+       ret = (system(cmd));
+       if (ret != 0) {
+               fprintf(stderr, "error: destroying the session %s\n", name);
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+int create_local_session()
+{
+       int ret;
+       char *name;
+       int sudo = 0;
+
+       ret = check_requirements(&sudo);
+
+       name = random_session_name();
+       if (!name) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = check_session_name(name, sudo);
+       if (ret < 0) {
+               goto end_free;
+       }
+
+       ret = local_session(name, sudo);
+       if (ret < 0) {
+               goto end_free;
+       }
+
+       ret = enable_event(name, sudo);
+       if (ret < 0) {
+               goto end_free;
+       }
+
+       ret = add_contexts(name, sudo);
+       if (ret < 0) {
+               goto end_free;
+       }
+
+       ret = start(name, sudo);
+       if (ret < 0) {
+               goto end_free;
+       }
+
+end_free:
+       free(name);
+end:
+       return ret;
+}
+
+int destroy_local_session(char *name, int sudo)
+{
+       return destroy(name, sudo);
+}
+
+/*
+int create_live_local_session();
+int destroy_live_local_session();
+*/
diff --git a/src/lttng-session.h b/src/lttng-session.h
new file mode 100644 (file)
index 0000000..1d85330
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 Julien Desfossez
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LTTNG_SESSION_H
+#define LTTNG_SESSION_H
+
+int create_local_session();
+int destroy_local_session();
+int create_live_local_session();
+int destroy_live_local_session();
+
+#endif /* LTTNG_SESSION_H */
index cce1901775067469f37bd29ab2ae5e258b4f3c24..9cf3a55d9c80bc4565dc6c5abd4aa5f4fded88f9 100644 (file)
@@ -51,6 +51,7 @@
 #include "iostreamtop.h"
 #include "common.h"
 #include "network-live.h"
+#include "lttng-session.h"
 
 #ifdef HAVE_LIBNCURSES
 #include "cursesdisplay.h"
@@ -107,6 +108,7 @@ enum {
        OPT_OUTPUT_FILE,
        OPT_VERBOSE,
        OPT_GUI_TEST,
+       OPT_CREATE_LOCAL_SESSION,
 };
 
 static struct poptOption long_options[] = {
@@ -124,6 +126,7 @@ static struct poptOption long_options[] = {
        { "output", 'o', POPT_ARG_STRING, &opt_output, OPT_OUTPUT_FILE, NULL, NULL },
        { "verbose", 'v', POPT_ARG_NONE, NULL, OPT_VERBOSE, NULL, NULL },
        { "gui-test", 'g', POPT_ARG_NONE, NULL, OPT_GUI_TEST, NULL, NULL },
+       { "create-local-session", 0, POPT_ARG_NONE, NULL, OPT_CREATE_LOCAL_SESSION, NULL, NULL },
        { NULL, 0, 0, NULL, 0, NULL, NULL },
 };
 
@@ -799,6 +802,9 @@ static int parse_options(int argc, char **argv)
                                exit(EXIT_FAILURE);
 #endif
                                goto end;
+                       case OPT_CREATE_LOCAL_SESSION:
+                               ret = create_local_session();
+                               exit(ret);
                        case OPT_TEXTDUMP:
                                opt_textdump = 1;
                                break;
This page took 0.041881 seconds and 4 git commands to generate.