Fix: agent may not be ready on launch
[lttng-tools.git] / src / bin / lttng-sessiond / main.c
index 3d0a65def51a0a727c3a5d08539c035f341701f5..602db1ee4fb69bf686a0b78f036dc52517002ba3 100644 (file)
@@ -291,7 +291,7 @@ struct lttng_ht *agent_apps_ht_by_sock = NULL;
  * NR_LTTNG_SESSIOND_READY must match the number of calls to
  * sessiond_notify_ready().
  */
-#define NR_LTTNG_SESSIOND_READY                4
+#define NR_LTTNG_SESSIOND_READY                5
 int lttng_sessiond_ready = NR_LTTNG_SESSIOND_READY;
 
 int sessiond_check_thread_quit_pipe(int fd, uint32_t events)
@@ -599,21 +599,6 @@ static void sessiond_cleanup(void)
                free(load_info);
        }
 
-       /*
-        * Cleanup lock file by deleting it and finaly closing it which will
-        * release the file system lock.
-        */
-       if (lockfile_fd >= 0) {
-               ret = remove(config.lock_file_path.value);
-               if (ret < 0) {
-                       PERROR("remove lock file");
-               }
-               ret = close(lockfile_fd);
-               if (ret < 0) {
-                       PERROR("close lock file");
-               }
-       }
-
        /*
         * We do NOT rmdir rundir because there are other processes
         * using it, for instance lttng-relayd, which can start in
@@ -1270,6 +1255,7 @@ restart:
        if (!cmd_socket_wrapper) {
                goto error;
        }
+       cmd_socket_wrapper->lock = &consumer_data->lock;
 
        ret = consumer_send_channel_monitor_pipe(cmd_socket_wrapper,
                        consumer_data->channel_monitor_pipe);
@@ -2442,7 +2428,7 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data)
                {
                        char *tmpnew = NULL;
 
-                       if (config.consumerd64_lib_dir.value[0] != '\0') {
+                       if (config.consumerd64_lib_dir.value) {
                                char *tmp;
                                size_t tmplen;
 
@@ -2450,20 +2436,18 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data)
                                if (!tmp) {
                                        tmp = "";
                                }
-                               tmplen = strlen("LD_LIBRARY_PATH=")
-                                       + strlen(config.consumerd64_lib_dir.value) + 1 /* : */ + strlen(tmp);
+                               tmplen = strlen(config.consumerd64_lib_dir.value) + 1 /* : */ + strlen(tmp);
                                tmpnew = zmalloc(tmplen + 1 /* \0 */);
                                if (!tmpnew) {
                                        ret = -ENOMEM;
                                        goto error;
                                }
-                               strcpy(tmpnew, "LD_LIBRARY_PATH=");
                                strcat(tmpnew, config.consumerd64_lib_dir.value);
                                if (tmp[0] != '\0') {
                                        strcat(tmpnew, ":");
                                        strcat(tmpnew, tmp);
                                }
-                               ret = putenv(tmpnew);
+                               ret = setenv("LD_LIBRARY_PATH", tmpnew, 1);
                                if (ret) {
                                        ret = -errno;
                                        free(tmpnew);
@@ -2476,16 +2460,14 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data)
                                        "--consumerd-err-sock", consumer_data->err_unix_sock_path,
                                        "--group", config.tracing_group_name.value,
                                        NULL);
-                       if (config.consumerd64_lib_dir.value[0] != '\0') {
-                               free(tmpnew);
-                       }
+                       free(tmpnew);
                        break;
                }
                case LTTNG_CONSUMER32_UST:
                {
                        char *tmpnew = NULL;
 
-                       if (config.consumerd32_lib_dir.value[0] != '\0') {
+                       if (config.consumerd32_lib_dir.value) {
                                char *tmp;
                                size_t tmplen;
 
@@ -2493,20 +2475,18 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data)
                                if (!tmp) {
                                        tmp = "";
                                }
-                               tmplen = strlen("LD_LIBRARY_PATH=")
-                                       + strlen(config.consumerd32_lib_dir.value) + 1 /* : */ + strlen(tmp);
+                               tmplen = strlen(config.consumerd32_lib_dir.value) + 1 /* : */ + strlen(tmp);
                                tmpnew = zmalloc(tmplen + 1 /* \0 */);
                                if (!tmpnew) {
                                        ret = -ENOMEM;
                                        goto error;
                                }
-                               strcpy(tmpnew, "LD_LIBRARY_PATH=");
                                strcat(tmpnew, config.consumerd32_lib_dir.value);
                                if (tmp[0] != '\0') {
                                        strcat(tmpnew, ":");
                                        strcat(tmpnew, tmp);
                                }
-                               ret = putenv(tmpnew);
+                               ret = setenv("LD_LIBRARY_PATH", tmpnew, 1);
                                if (ret) {
                                        ret = -errno;
                                        free(tmpnew);
@@ -2519,13 +2499,11 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data)
                                        "--consumerd-err-sock", consumer_data->err_unix_sock_path,
                                        "--group", config.tracing_group_name.value,
                                        NULL);
-                       if (config.consumerd32_lib_dir.value[0] != '\0') {
-                               free(tmpnew);
-                       }
+                       free(tmpnew);
                        break;
                }
                default:
-                       PERROR("unknown consumer type");
+                       ERR("unknown consumer type");
                        exit(EXIT_FAILURE);
                }
                if (errno != 0) {
@@ -4727,7 +4705,7 @@ static int set_option(int opt, const char *arg, const char *optname)
        } else if (string_match(optname, "no-kernel")) {
                config.no_kernel = true;
        } else if (string_match(optname, "quiet") || opt == 'q') {
-               lttng_opt_quiet = true;
+               config.quiet = true;
        } else if (string_match(optname, "verbose") || opt == 'v') {
                /* Verbose level can increase using multiple -v */
                if (arg) {
@@ -5130,18 +5108,57 @@ end:
        return ret;
 }
 
+/*
+ * Create lockfile using the rundir and return its fd.
+ */
+static int create_lockfile(void)
+{
+        return utils_create_lock_file(config.lock_file_path.value);
+}
+
 /*
  * Check if the global socket is available, and if a daemon is answering at the
  * other side. If yes, error is returned.
+ *
+ * Also attempts to create and hold the lock file.
  */
 static int check_existing_daemon(void)
 {
+       int ret = 0;
+
        /* Is there anybody out there ? */
        if (lttng_session_daemon_alive()) {
-               return -EEXIST;
+               ret = -EEXIST;
+               goto end;
        }
 
-       return 0;
+       lockfile_fd = create_lockfile();
+       if (lockfile_fd < 0) {
+               ret = -EEXIST;
+               goto end;
+       }
+end:
+       return ret;
+}
+
+static void sessiond_cleanup_lock_file(void)
+{
+       int ret;
+
+       /*
+        * Cleanup lock file by deleting it and finaly closing it which will
+        * release the file system lock.
+        */
+       if (lockfile_fd >= 0) {
+               ret = remove(config.lock_file_path.value);
+               if (ret < 0) {
+                       PERROR("remove lock file");
+               }
+               ret = close(lockfile_fd);
+               if (ret < 0) {
+                       PERROR("close lock file");
+               }
+       }
 }
 
 /*
@@ -5400,14 +5417,6 @@ static int write_pidfile(void)
         return utils_create_pid_file(getpid(), config.pid_file_path.value);
 }
 
-/*
- * Create lockfile using the rundir and return its fd.
- */
-static int create_lockfile(void)
-{
-        return utils_create_lock_file(config.lock_file_path.value);
-}
-
 /*
  * Write agent TCP port using the rundir.
  */
@@ -5528,6 +5537,18 @@ int main(int argc, char **argv)
 
        sessiond_config_log(&config);
 
+       if (create_lttng_rundir()) {
+               retval = -1;
+               goto exit_options;
+       }
+
+       /* Abort launch if a session daemon is already running. */
+       if (check_existing_daemon()) {
+               ERR("A session daemon is already running.");
+               retval = -1;
+               goto exit_options;
+       }
+
        /* Daemonize */
        if (config.daemonize || config.background) {
                int i;
@@ -5542,9 +5563,12 @@ int main(int argc, char **argv)
                /*
                 * We are in the child. Make sure all other file descriptors are
                 * closed, in case we are called with more opened file
-                * descriptors than the standard ones.
+                * descriptors than the standard ones and the lock file.
                 */
                for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
+                       if (i == lockfile_fd) {
+                               continue;
+                       }
                        (void) close(i);
                }
        }
@@ -5583,12 +5607,6 @@ int main(int argc, char **argv)
 
        /* Check if daemon is UID = 0 */
        is_root = !getuid();
-
-       if (create_lttng_rundir()) {
-               retval = -1;
-               goto exit_init_data;
-       }
-
        if (is_root) {
                /* Create global run dir with root access */
 
@@ -5607,12 +5625,6 @@ int main(int argc, char **argv)
                }
        }
 
-       lockfile_fd = create_lockfile();
-       if (lockfile_fd < 0) {
-               retval = -1;
-               goto exit_init_data;
-       }
-
        /* Set consumer initial state */
        kernel_consumerd_state = CONSUMER_STOPPED;
        ust_consumerd_state = CONSUMER_STOPPED;
@@ -5643,19 +5655,6 @@ int main(int argc, char **argv)
                goto exit_init_data;
        }
 
-       /*
-        * See if daemon already exist.
-        */
-       if (check_existing_daemon()) {
-               ERR("Already running daemon.\n");
-               /*
-                * We do not goto exit because we must not cleanup()
-                * because a daemon is already running.
-                */
-               retval = -1;
-               goto exit_init_data;
-       }
-
        /*
         * Init UST app hash table. Alloc hash table before this point since
         * cleanup() can get called after that point.
@@ -6067,6 +6066,7 @@ exit_health_sessiond_cleanup:
 exit_create_run_as_worker_cleanup:
 
 exit_options:
+       sessiond_cleanup_lock_file();
        sessiond_cleanup_options();
 
 exit_set_signal_handler:
This page took 0.027818 seconds and 4 git commands to generate.