X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Fcreate.c;h=a7d327fbcada361477b71f44d025595adba67056;hp=b8d9f3b5655c56975bfa1716a08065b86ca1ca14;hb=d1edd8a82868dafce6d61600c87ac916d7f73702;hpb=d7ba13889c8692b14f99238ddf2721ed78df89d2 diff --git a/src/bin/lttng/commands/create.c b/src/bin/lttng/commands/create.c index b8d9f3b56..a7d327fbc 100644 --- a/src/bin/lttng/commands/create.c +++ b/src/bin/lttng/commands/create.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include @@ -79,7 +81,7 @@ static struct poptOption long_options[] = { * why this declaration exists and used ONLY in for this command. */ extern int _lttng_create_session_ext(const char *name, const char *url, - const char *datetime, int live_timer); + const char *datetime); /* * usage @@ -458,7 +460,7 @@ static int create_session(void) } ret = lttng_create_session_live(session_name, url, opt_live_timer); } else { - ret = _lttng_create_session_ext(session_name, url, datetime, -1); + ret = _lttng_create_session_ext(session_name, url, datetime); } if (ret < 0) { /* Don't set ret so lttng can interpret the sessiond error. */ @@ -550,6 +552,129 @@ 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 a session daemon"); + pid = fork(); + if (pid == 0) { + /* + * Spawn session daemon in daemon mode. + */ + execlp(pathname, "lttng-sessiond", + "--daemonize", NULL); + /* execlp only returns if error happened */ + if (errno == ENOENT) { + ERR("No session daemon found. Use --sessiond-path."); + } else { + PERROR("execlp"); + } + kill(getppid(), SIGTERM); /* wake parent */ + exit(EXIT_FAILURE); + } else if (pid > 0) { + int status; + + /* + * In daemon mode (--daemonize), sessiond only exits when + * it's ready to accept commands. + */ + for (;;) { + waitpid(pid, &status, 0); + + if (WIFSIGNALED(status)) { + ERR("Session daemon was killed by signal %d", + WTERMSIG(status)); + ret = -1; + goto end; + } else if (WIFEXITED(status)) { + DBG("Session daemon terminated normally (exit status: %d)", + WEXITSTATUS(status)); + + if (WEXITSTATUS(status) != 0) { + ERR("Session daemon terminated with an error (exit status: %d)", + WEXITSTATUS(status)); + ret = -1; + goto end; + } + break; + } + } + + goto end; + } else { + PERROR("fork"); + ret = -1; + goto end; + } + +end: + return ret; +} + +/* + * launch_sessiond + * + * Check if the session daemon is available using + * the liblttngctl API for the check. If not, try to + * spawn a daemon. + */ +static int launch_sessiond(void) +{ + int ret; + char *pathname = NULL; + + ret = lttng_session_daemon_alive(); + if (ret) { + /* Sessiond is alive, not an error */ + ret = 0; + goto end; + } + + /* Try command line option path */ + pathname = opt_sessiond_path; + + /* Try LTTNG_SESSIOND_PATH env variable */ + if (pathname == NULL) { + pathname = getenv(DEFAULT_SESSIOND_PATH_ENV); + } + + /* Try with configured path */ + if (pathname == NULL) { + if (CONFIG_SESSIOND_BIN[0] != '\0') { + pathname = CONFIG_SESSIOND_BIN; + } + } + + /* Try the default path */ + if (pathname == NULL) { + pathname = INSTALL_BIN_PATH "/lttng-sessiond"; + } + + DBG("Session daemon binary path: %s", pathname); + + /* Check existence and permissions */ + ret = access(pathname, F_OK | X_OK); + if (ret < 0) { + ERR("No such file or access denied: %s", pathname); + goto end; + } + + ret = spawn_sessiond(pathname); +end: + if (ret) { + ERR("Problem occurred while launching session daemon (%s)", + pathname); + } + return ret; +} + /* * The 'create ' first level command * @@ -597,6 +722,11 @@ int cmd_create(int argc, const char **argv) ret = CMD_ERROR; goto end; } + if (v == 0) { + ERR("Live timer interval must be greater than zero"); + ret = CMD_ERROR; + goto end; + } opt_live_timer = (uint32_t) v; DBG("Session live timer interval set to %d", opt_live_timer); break; @@ -614,6 +744,15 @@ int cmd_create(int argc, const char **argv) goto end; } + /* Spawn a session daemon if needed */ + if (!opt_no_sessiond) { + ret = launch_sessiond(); + if (ret) { + ret = CMD_ERROR; + goto end; + } + } + /* MI initialization */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);