Fix: remove uninitialised value
[lttng-ust.git] / liblttng-ust / lttng-ust-comm.c
index 1720bca9cdbbe07f457ee34f22b6e69a5dfd7f2b..fba236864e5a3aff7db36a2f43bc634dcb8e1288 100644 (file)
@@ -46,6 +46,7 @@
 #include <lttng/ust-ctl.h>
 #include <urcu/tls-compat.h>
 #include <ust-comm.h>
+#include <ust-fd.h>
 #include <usterr-signal-safe.h>
 #include <helper.h>
 #include "tracepoint-internal.h"
@@ -258,7 +259,7 @@ struct sock_info global_apps = {
        .global = 1,
 
        .root_handle = -1,
-       .allowed = 1,
+       .allowed = 0,
        .thread_active = 0,
 
        .sock_path = LTTNG_DEFAULT_RUNDIR "/" LTTNG_UST_SOCK_FILENAME,
@@ -337,6 +338,8 @@ extern void lttng_ring_buffer_client_discard_exit(void);
 extern void lttng_ring_buffer_client_discard_rt_exit(void);
 extern void lttng_ring_buffer_metadata_client_exit(void);
 
+static char *get_map_shm(struct sock_info *sock_info);
+
 ssize_t lttng_ust_read(int fd, void *buf, size_t len)
 {
        ssize_t ret;
@@ -364,11 +367,11 @@ const char *get_lttng_home_dir(void)
 {
        const char *val;
 
-       val = (const char *) lttng_secure_getenv("LTTNG_HOME");
+       val = (const char *) lttng_getenv("LTTNG_HOME");
        if (val != NULL) {
                return val;
        }
-       return (const char *) lttng_secure_getenv("HOME");
+       return (const char *) lttng_getenv("HOME");
 }
 
 /*
@@ -404,6 +407,7 @@ void lttng_ust_fixup_tls(void)
        lttng_fixup_nest_count_tls();
        lttng_fixup_procname_tls();
        lttng_fixup_ust_mutex_nest_tls();
+       lttng_ust_fixup_fd_tracker_tls();
 }
 
 int lttng_get_notify_socket(void *owner)
@@ -427,25 +431,48 @@ void print_cmd(int cmd, int handle)
                lttng_ust_obj_get_name(handle), handle);
 }
 
+static
+int setup_global_apps(void)
+{
+       int ret = 0;
+       assert(!global_apps.wait_shm_mmap);
+
+       global_apps.wait_shm_mmap = get_map_shm(&global_apps);
+       if (!global_apps.wait_shm_mmap) {
+               WARN("Unable to get map shm for global apps. Disabling LTTng-UST global tracing.");
+               global_apps.allowed = 0;
+               ret = -EIO;
+               goto error;
+       }
+
+       global_apps.allowed = 1;
+error:
+       return ret;
+}
 static
 int setup_local_apps(void)
 {
+       int ret = 0;
        const char *home_dir;
        uid_t uid;
 
+       assert(!local_apps.wait_shm_mmap);
+
        uid = getuid();
        /*
         * Disallow per-user tracing for setuid binaries.
         */
        if (uid != geteuid()) {
                assert(local_apps.allowed == 0);
-               return 0;
+               ret = 0;
+               goto end;
        }
        home_dir = get_lttng_home_dir();
        if (!home_dir) {
                WARN("HOME environment variable not set. Disabling LTTng-UST per-user tracing.");
                assert(local_apps.allowed == 0);
-               return -ENOENT;
+               ret = -ENOENT;
+               goto end;
        }
        local_apps.allowed = 1;
        snprintf(local_apps.sock_path, PATH_MAX, "%s/%s/%s",
@@ -455,11 +482,20 @@ int setup_local_apps(void)
        snprintf(local_apps.wait_shm_path, PATH_MAX, "/%s-%u",
                LTTNG_UST_WAIT_FILENAME,
                uid);
-       return 0;
+
+       local_apps.wait_shm_mmap = get_map_shm(&local_apps);
+       if (!local_apps.wait_shm_mmap) {
+               WARN("Unable to get map shm for local apps. Disabling LTTng-UST per-user tracing.");
+               local_apps.allowed = 0;
+               ret = -EIO;
+               goto end;
+       }
+end:
+       return ret;
 }
 
 /*
- * Get notify_sock timeout, in ms.
+ * Get socket timeout, in ms.
  * -1: wait forever. 0: don't wait. >0: timeout, in ms.
  */
 static
@@ -468,7 +504,7 @@ long get_timeout(void)
        long constructor_delay_ms = LTTNG_UST_DEFAULT_CONSTRUCTOR_TIMEOUT_MS;
 
        if (!got_timeout_env) {
-               str_timeout = getenv("LTTNG_UST_REGISTER_TIMEOUT");
+               str_timeout = lttng_getenv("LTTNG_UST_REGISTER_TIMEOUT");
                got_timeout_env = 1;
        }
        if (str_timeout)
@@ -479,12 +515,20 @@ long get_timeout(void)
        return constructor_delay_ms;
 }
 
+/* Timeout for notify socket send and recv. */
 static
 long get_notify_sock_timeout(void)
 {
        return get_timeout();
 }
 
+/* Timeout for connecting to cmd and notify sockets. */
+static
+long get_connect_sock_timeout(void)
+{
+       return get_timeout();
+}
+
 /*
  * Return values: -1: wait forever. 0: don't wait. 1: timeout wait.
  */
@@ -815,12 +859,13 @@ int handle_message(struct sock_info *sock_info,
        {
                /* Receive shm_fd, wakeup_fd */
                ret = ustcomm_recv_stream_from_sessiond(sock,
-                       &lum->u.stream.len,
+                       NULL,
                        &args.stream.shm_fd,
                        &args.stream.wakeup_fd);
                if (ret) {
                        goto error;
                }
+
                if (ops->cmd)
                        ret = ops->cmd(lum->handle, lum->cmd,
                                        (unsigned long) &lum->u,
@@ -946,6 +991,21 @@ int handle_message(struct sock_info *sock_info,
                }
        }
        DBG("Return value: %d", lur.ret_val);
+
+       ust_unlock();
+
+       /*
+        * Performed delayed statedump operations outside of the UST
+        * lock. We need to take the dynamic loader lock before we take
+        * the UST lock internally within handle_pending_statedump().
+         */
+       handle_pending_statedump(sock_info);
+
+       if (ust_lock()) {
+               ret = -LTTNG_UST_ERR_EXITING;
+               goto error;
+       }
+
        ret = send_reply(sock, &lur);
        if (ret < 0) {
                DBG("error sending reply");
@@ -976,13 +1036,6 @@ int handle_message(struct sock_info *sock_info,
 error:
        ust_unlock();
 
-       /*
-        * Performed delayed statedump operations outside of the UST
-        * lock. We need to take the dynamic loader lock before we take
-        * the UST lock internally within handle_pending_statedump().
-         */
-       handle_pending_statedump(sock_info);
-
        return ret;
 }
 
@@ -1223,17 +1276,39 @@ char *get_map_shm(struct sock_info *sock_info)
                goto error;
        }
 
+       lttng_ust_lock_fd_tracker();
        wait_shm_fd = get_wait_shm(sock_info, page_size);
        if (wait_shm_fd < 0) {
+               lttng_ust_unlock_fd_tracker();
                goto error;
        }
+
+       ret = lttng_ust_add_fd_to_tracker(wait_shm_fd);
+       if (ret < 0) {
+               ret = close(wait_shm_fd);
+               if (!ret) {
+                       PERROR("Error closing fd");
+               }
+               lttng_ust_unlock_fd_tracker();
+               goto error;
+       }
+
+       wait_shm_fd = ret;
+       lttng_ust_unlock_fd_tracker();
+
        wait_shm_mmap = mmap(NULL, page_size, PROT_READ,
                  MAP_SHARED, wait_shm_fd, 0);
+
        /* close shm fd immediately after taking the mmap reference */
+       lttng_ust_lock_fd_tracker();
        ret = close(wait_shm_fd);
-       if (ret) {
+       if (!ret) {
+               lttng_ust_delete_fd_from_tracker(wait_shm_fd);
+       } else {
                PERROR("Error closing fd");
        }
+       lttng_ust_unlock_fd_tracker();
+
        if (wait_shm_mmap == MAP_FAILED) {
                DBG("mmap error (can be caused by race with sessiond). Fallback to poll mode.");
                goto error;
@@ -1247,19 +1322,17 @@ error:
 static
 void wait_for_sessiond(struct sock_info *sock_info)
 {
+       /* Use ust_lock to check if we should quit. */
        if (ust_lock()) {
                goto quit;
        }
        if (wait_poll_fallback) {
                goto error;
        }
-       if (!sock_info->wait_shm_mmap) {
-               sock_info->wait_shm_mmap = get_map_shm(sock_info);
-               if (!sock_info->wait_shm_mmap)
-                       goto error;
-       }
        ust_unlock();
 
+       assert(sock_info->wait_shm_mmap);
+
        DBG("Waiting for %s apps sessiond", sock_info->name);
        /* Wait for futex wakeup */
        if (uatomic_read((int32_t *) sock_info->wait_shm_mmap))
@@ -1310,7 +1383,7 @@ static
 void *ust_listener_thread(void *arg)
 {
        struct sock_info *sock_info = arg;
-       int sock, ret, prev_connect_failed = 0, has_waited = 0;
+       int sock, ret, prev_connect_failed = 0, has_waited = 0, fd;
        long timeout;
 
        lttng_ust_fixup_tls();
@@ -1342,7 +1415,12 @@ restart:
                prev_connect_failed = 0;
        }
 
+       if (ust_lock()) {
+               goto quit;
+       }
+
        if (sock_info->socket != -1) {
+               /* FD tracker is updated by ustcomm_close_unix_sock() */
                ret = ustcomm_close_unix_sock(sock_info->socket);
                if (ret) {
                        ERR("Error closing %s ust cmd socket",
@@ -1351,6 +1429,7 @@ restart:
                sock_info->socket = -1;
        }
        if (sock_info->notify_socket != -1) {
+               /* FD tracker is updated by ustcomm_close_unix_sock() */
                ret = ustcomm_close_unix_sock(sock_info->notify_socket);
                if (ret) {
                        ERR("Error closing %s ust notify socket",
@@ -1359,6 +1438,7 @@ restart:
                sock_info->notify_socket = -1;
        }
 
+
        /*
         * Register. We need to perform both connect and sending
         * registration message before doing the next connect otherwise
@@ -1367,15 +1447,14 @@ restart:
         * first connect registration message.
         */
        /* Connect cmd socket */
-       ret = ustcomm_connect_unix_sock(sock_info->sock_path);
+       lttng_ust_lock_fd_tracker();
+       ret = ustcomm_connect_unix_sock(sock_info->sock_path,
+               get_connect_sock_timeout());
        if (ret < 0) {
+               lttng_ust_unlock_fd_tracker();
                DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name);
                prev_connect_failed = 1;
 
-               if (ust_lock()) {
-                       goto quit;
-               }
-
                /*
                 * If we cannot find the sessiond daemon, don't delay
                 * constructor execution.
@@ -1385,8 +1464,28 @@ restart:
                ust_unlock();
                goto restart;
        }
+       fd = ret;
+       ret = lttng_ust_add_fd_to_tracker(fd);
+       if (ret < 0) {
+               ret = close(fd);
+               if (ret) {
+                       PERROR("close on sock_info->socket");
+               }
+               ret = -1;
+               lttng_ust_unlock_fd_tracker();
+               ust_unlock();
+               goto quit;
+       }
+
        sock_info->socket = ret;
+       lttng_ust_unlock_fd_tracker();
 
+       ust_unlock();
+       /*
+        * Unlock/relock ust lock because connect is blocking (with
+        * timeout). Don't delay constructors on the ust lock for too
+        * long.
+        */
        if (ust_lock()) {
                goto quit;
        }
@@ -1421,17 +1520,24 @@ restart:
        }
 
        ust_unlock();
+       /*
+        * Unlock/relock ust lock because connect is blocking (with
+        * timeout). Don't delay constructors on the ust lock for too
+        * long.
+        */
+       if (ust_lock()) {
+               goto quit;
+       }
 
        /* Connect notify socket */
-       ret = ustcomm_connect_unix_sock(sock_info->sock_path);
+       lttng_ust_lock_fd_tracker();
+       ret = ustcomm_connect_unix_sock(sock_info->sock_path,
+               get_connect_sock_timeout());
        if (ret < 0) {
+               lttng_ust_unlock_fd_tracker();
                DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name);
                prev_connect_failed = 1;
 
-               if (ust_lock()) {
-                       goto quit;
-               }
-
                /*
                 * If we cannot find the sessiond daemon, don't delay
                 * constructor execution.
@@ -1441,7 +1547,32 @@ restart:
                ust_unlock();
                goto restart;
        }
+
+       fd = ret;
+       ret = lttng_ust_add_fd_to_tracker(fd);
+       if (ret < 0) {
+               ret = close(fd);
+               if (ret) {
+                       PERROR("close on sock_info->notify_socket");
+               }
+               ret = -1;
+               lttng_ust_unlock_fd_tracker();
+               ust_unlock();
+               goto quit;
+       }
+
        sock_info->notify_socket = ret;
+       lttng_ust_unlock_fd_tracker();
+
+       ust_unlock();
+       /*
+        * Unlock/relock ust lock because connect is blocking (with
+        * timeout). Don't delay constructors on the ust lock for too
+        * long.
+        */
+       if (ust_lock()) {
+               goto quit;
+       }
 
        timeout = get_notify_sock_timeout();
        if (timeout >= 0) {
@@ -1465,10 +1596,6 @@ restart:
                WARN("Unsupported timeout value %ld", timeout);
        }
 
-       if (ust_lock()) {
-               goto quit;
-       }
-
        ret = register_to_sessiond(sock_info->notify_socket,
                        USTCTL_SOCKET_NOTIFY);
        if (ret < 0) {
@@ -1597,7 +1724,9 @@ void __attribute__((constructor)) lttng_ust_init(void)
         * sessiond before the init functions are completed).
         */
        init_usterr();
+       lttng_ust_getenv_init();        /* Needs init_usterr() to be completed. */
        init_tracepoint();
+       lttng_ust_init_fd_tracker();
        lttng_ust_clock_init();
        lttng_ust_getcpu_init();
        lttng_ust_statedump_init();
@@ -1619,8 +1748,15 @@ void __attribute__((constructor)) lttng_ust_init(void)
                PERROR("sem_init");
        }
 
+       ret = setup_global_apps();
+       if (ret) {
+               assert(global_apps.allowed == 0);
+               DBG("global apps setup returned %d", ret);
+       }
+
        ret = setup_local_apps();
        if (ret) {
+               assert(local_apps.allowed == 0);
                DBG("local apps setup returned %d", ret);
        }
 
@@ -1644,14 +1780,18 @@ void __attribute__((constructor)) lttng_ust_init(void)
                ERR("pthread_attr_setdetachstate: %s", strerror(ret));
        }
 
-       pthread_mutex_lock(&ust_exit_mutex);
-       ret = pthread_create(&global_apps.ust_listener, &thread_attr,
-                       ust_listener_thread, &global_apps);
-       if (ret) {
-               ERR("pthread_create global: %s", strerror(ret));
+       if (global_apps.allowed) {
+               pthread_mutex_lock(&ust_exit_mutex);
+               ret = pthread_create(&global_apps.ust_listener, &thread_attr,
+                               ust_listener_thread, &global_apps);
+               if (ret) {
+                       ERR("pthread_create global: %s", strerror(ret));
+               }
+               global_apps.thread_active = 1;
+               pthread_mutex_unlock(&ust_exit_mutex);
+       } else {
+               handle_register_done(&global_apps);
        }
-       global_apps.thread_active = 1;
-       pthread_mutex_unlock(&ust_exit_mutex);
 
        if (local_apps.allowed) {
                pthread_mutex_lock(&ust_exit_mutex);
@@ -1722,6 +1862,7 @@ void lttng_ust_cleanup(int exiting)
        cleanup_sock_info(&global_apps, exiting);
        cleanup_sock_info(&local_apps, exiting);
        local_apps.allowed = 0;
+       global_apps.allowed = 0;
        /*
         * The teardown in this function all affect data structures
         * accessed under the UST lock by the listener thread. This
@@ -1874,7 +2015,9 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 {
        if (URCU_TLS(lttng_ust_nest_count))
                return;
+       lttng_context_vpid_reset();
        lttng_context_vtid_reset();
+       lttng_context_procname_reset();
        DBG("process %d", getpid());
        /* Release urcu mutexes */
        rcu_bp_after_fork_child();
This page took 0.02858 seconds and 4 git commands to generate.