X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng%2Flttng.c;h=40cf52bc6a3b02059a1ea8635c412737f8a5f71f;hp=6cc540922a77b78ebd29c505255bfa54ad65996b;hb=87378cf56f08f23cd6715a923ba10d98343902d7;hpb=e065084a507dd07b658b3d26c58b1ddd519e25a0 diff --git a/lttng/lttng.c b/lttng/lttng.c index 6cc540922..40cf52bc6 100644 --- a/lttng/lttng.c +++ b/lttng/lttng.c @@ -41,6 +41,10 @@ static char *progname; /* Prototypes */ static int process_client_opt(void); static int process_opt_list_apps(void); +static int process_opt_list_sessions(void); +static int process_opt_create_session(void); +static void sighandler(int sig); +static int set_signal_handler(void); /* * start_client @@ -52,25 +56,108 @@ static int process_opt_list_apps(void); static int process_client_opt(void) { int ret; + uuid_t uuid; /* Connect to the session daemon */ ret = lttng_connect_sessiond(); if (ret < 0) { - ERR("%s", lttng_get_readable_code(ret)); goto end; } if (opt_list_apps) { ret = process_opt_list_apps(); if (ret < 0) { - ERR("%s", lttng_get_readable_code(ret)); goto end; } } + if (opt_list_session) { + ret = process_opt_list_sessions(); + if (ret < 0) { + goto end; + } + } + + if (opt_create_session != NULL) { + ret = process_opt_create_session(); + if (ret < 0) { + goto end; + } + } + + if (opt_destroy_session != NULL) { + uuid_parse(opt_destroy_session, uuid); + ret = lttng_destroy_session(&uuid); + if (ret < 0) { + goto end; + } + } + + if (opt_session_uuid != NULL) { + lttng_set_current_session_uuid(opt_session_uuid); + } + return 0; end: + ERR("%s", lttng_get_readable_code(ret)); + return ret; +} + +/* + * process_opt_create_session + * + * Create a new session using the name pass + * to the command line. + */ +static int process_opt_create_session(void) +{ + int ret; + uuid_t session_id; + char str_uuid[37]; + + ret = lttng_create_session(opt_create_session, &session_id); + if (ret < 0) { + goto error; + } + + uuid_unparse(session_id, str_uuid); + + MSG("Session created:"); + MSG(" %s (%s)", opt_create_session, str_uuid); + +error: + return ret; +} + +/* + * process_opt_list_sessions + * + * Get the list of available sessions from + * the session daemon and print it to user. + */ +static int process_opt_list_sessions(void) +{ + int ret, count, i; + struct lttng_session *sess; + + count = lttng_list_sessions(&sess); + if (count < 0) { + ret = count; + goto error; + } + + MSG("Available sessions [Name (uuid)]:"); + for (i = 0; i < count; i++) { + MSG("\tName: %s (uuid: %s)", sess[i].name, sess[i].uuid); + } + + free(sess); + MSG("\nTo select a session, use --session UUID."); + + return 0; + +error: return ret; } @@ -82,22 +169,24 @@ end: */ static int process_opt_list_apps(void) { - int i, ret; + int i, ret, count; pid_t *pids; FILE *fp; char path[24]; /* Can't go bigger than /proc/65535/cmdline */ char cmdline[PATH_MAX]; - ret = lttng_ust_list_apps(&pids); - if (ret < 0) { + count = lttng_ust_list_apps(&pids); + if (count < 0) { + ret = count; goto error; } MSG("LTTng UST traceable application [name (pid)]:"); - for (i=0; i < ret; i++) { + for (i=0; i < count; i++) { snprintf(path, sizeof(path), "/proc/%d/cmdline", pids[i]); fp = fopen(path, "r"); if (fp == NULL) { + MSG("\t(not running) (%d)", pids[i]); continue; } ret = fread(cmdline, 1, sizeof(cmdline), fp); @@ -114,36 +203,168 @@ error: return ret; } +/* + * spawn_sessiond + * + * Spawn a session daemon by forking and execv. + */ +static int spawn_sessiond(char *pathname) +{ + int ret = 0; + pid_t pid; + + MSG("Spawning session daemon"); + pid = fork(); + if (pid == 0) { + /* Spawn session daemon and tell + * it to signal us when ready. + */ + ret = execlp(pathname, "ltt-sessiond", "--sig-parent", "--quiet", NULL); + if (ret < 0) { + if (errno == ENOENT) { + ERR("No session daemon found. Use --sessiond-path."); + } else { + perror("execlp"); + } + kill(getppid(), SIGTERM); + exit(EXIT_FAILURE); + } + exit(EXIT_SUCCESS); + } else if (pid > 0) { + /* Wait for ltt-sessiond to start */ + pause(); + goto end; + } else { + perror("fork"); + ret = -1; + goto end; + } + +end: + return ret; +} + /* * check_ltt_sessiond * * Check if the session daemon is available using - * the liblttngctl API for the check. + * the liblttngctl API for the check. If not, try to + * spawn a daemon. */ static int check_ltt_sessiond(void) { int ret; + char *pathname = NULL; ret = lttng_check_session_daemon(); if (ret < 0) { - ERR("No session daemon found. Aborting."); + /* Try command line option path */ + if (opt_sessiond_path != NULL) { + ret = access(opt_sessiond_path, F_OK | X_OK); + if (ret < 0) { + ERR("No such file: %s", opt_sessiond_path); + goto end; + } + pathname = opt_sessiond_path; + } else { + /* Try LTTNG_SESSIOND_PATH env variable */ + pathname = getenv(LTTNG_SESSIOND_PATH_ENV); + if (pathname != NULL) { + /* strdup here in order to make the free() + * not fail later on. + */ + pathname = strdup(pathname); + } + } + + /* Let's rock and roll */ + if (pathname == NULL) { + ret = asprintf(&pathname, "ltt-sessiond"); + if (ret < 0) { + goto end; + } + } + + ret = spawn_sessiond(pathname); + free(pathname); + if (ret < 0) { + ERR("Problem occurs when starting %s", pathname); + goto end; + } } +end: return ret; } +/* + * set_signal_handler + * + * Setup signal handler for SIGCHLD and SIGTERM. + */ +static int set_signal_handler(void) +{ + int ret = 0; + struct sigaction sa; + sigset_t sigset; + + if ((ret = sigemptyset(&sigset)) < 0) { + perror("sigemptyset"); + goto end; + } + + sa.sa_handler = sighandler; + sa.sa_mask = sigset; + sa.sa_flags = 0; + if ((ret = sigaction(SIGCHLD, &sa, NULL)) < 0) { + perror("sigaction"); + goto end; + } + + if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) { + perror("sigaction"); + goto end; + } + +end: + return ret; +} +/* + * sighandler + * + * Signal handler for the daemon + */ +static void sighandler(int sig) +{ + DBG("%d received", sig); + switch (sig) { + case SIGTERM: + clean_exit(EXIT_FAILURE); + break; + case SIGCHLD: + /* Notify is done */ + break; + default: + break; + } + + return; +} /* * clean_exit */ void clean_exit(int code) { DBG("Clean exit"); + if (lttng_disconnect_sessiond() < 0) { + ERR("Session daemon disconnect failed."); + } exit(code); } /* - * main + * main */ int main(int argc, char *argv[]) { @@ -158,7 +379,12 @@ int main(int argc, char *argv[]) ret = parse_args(argc, (const char **) argv); if (ret < 0) { - return EXIT_FAILURE; + clean_exit(EXIT_FAILURE); + } + + ret = set_signal_handler(); + if (ret < 0) { + clean_exit(ret); } if (opt_tracing_group != NULL) { @@ -171,21 +397,23 @@ int main(int argc, char *argv[]) DBG("Kernel tracing activated"); if (getuid() != 0) { ERR("%s must be setuid root", progname); - return -EPERM; + clean_exit(-EPERM); } } /* Check if the lttng session daemon is running. * If no, a daemon will be spawned. */ - if (check_ltt_sessiond() < 0) { - return EXIT_FAILURE; + if (opt_no_sessiond == 0 && (check_ltt_sessiond() < 0)) { + clean_exit(EXIT_FAILURE); } ret = process_client_opt(); if (ret < 0) { - return ret; + clean_exit(ret); } + clean_exit(0); + return 0; }