+/*
+ * 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) {
+ /*
+ * In daemon mode (--daemonize), sessiond only exits when
+ * it's ready to accept commands.
+ */
+ for (;;) {
+ int status;
+ pid_t wait_pid_ret = waitpid(pid, &status, 0);
+
+ if (wait_pid_ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ PERROR("waitpid");
+ ret = -errno;
+ goto end;
+ }
+
+ 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;
+}
+