Move LTTng-UST buffer ownership from application to consumer
[lttng-ust.git] / liblttng-ust / lttng-ust-comm.c
index ef8b6fedcf7b045d197223fdcea1056a530d59a0..bfc9bc5a87f8fc6e02bd5cb3d999f575af1c98dc 100644 (file)
 #include <lttng/ust-abi.h>
 #include <lttng/ust.h>
 #include <lttng/ust-error.h>
+#include <lttng/ust-ctl.h>
 #include <ust-comm.h>
 #include <usterr-signal-safe.h>
 #include <helper.h>
 #include "tracepoint-internal.h"
-#include "ltt-tracer-core.h"
+#include "lttng-tracer-core.h"
 #include "compat.h"
 #include "../libringbuffer/tlsfixup.h"
 
@@ -96,6 +97,7 @@ struct sock_info {
        int constructor_sem_posted;
        int allowed;
        int global;
+       int thread_active;
 
        char sock_path[PATH_MAX];
        int socket;
@@ -111,6 +113,7 @@ struct sock_info global_apps = {
 
        .root_handle = -1,
        .allowed = 1,
+       .thread_active = 0,
 
        .sock_path = DEFAULT_GLOBAL_APPS_UNIX_SOCK,
        .socket = -1,
@@ -125,18 +128,54 @@ struct sock_info local_apps = {
        .global = 0,
        .root_handle = -1,
        .allowed = 0,   /* Check setuid bit first */
+       .thread_active = 0,
 
        .socket = -1,
 };
 
 static int wait_poll_fallback;
 
-extern void ltt_ring_buffer_client_overwrite_init(void);
-extern void ltt_ring_buffer_client_discard_init(void);
-extern void ltt_ring_buffer_metadata_client_init(void);
-extern void ltt_ring_buffer_client_overwrite_exit(void);
-extern void ltt_ring_buffer_client_discard_exit(void);
-extern void ltt_ring_buffer_metadata_client_exit(void);
+static const char *cmd_name_mapping[] = {
+       [ LTTNG_UST_RELEASE ] = "Release",
+       [ LTTNG_UST_SESSION ] = "Create Session",
+       [ LTTNG_UST_TRACER_VERSION ] = "Get Tracer Version",
+
+       [ LTTNG_UST_TRACEPOINT_LIST ] = "Create Tracepoint List",
+       [ LTTNG_UST_WAIT_QUIESCENT ] = "Wait for Quiescent State",
+       [ LTTNG_UST_REGISTER_DONE ] = "Registration Done",
+       [ LTTNG_UST_TRACEPOINT_FIELD_LIST ] = "Create Tracepoint Field List",
+
+       /* Session FD commands */
+       [ LTTNG_UST_CHANNEL ] = "Create Channel",
+       [ LTTNG_UST_SESSION_START ] = "Start Session",
+       [ LTTNG_UST_SESSION_STOP ] = "Stop Session",
+
+       /* Channel FD commands */
+       [ LTTNG_UST_STREAM ] = "Create Stream",
+       [ LTTNG_UST_EVENT ] = "Create Event",
+
+       /* Event and Channel FD commands */
+       [ LTTNG_UST_CONTEXT ] = "Create Context",
+       [ LTTNG_UST_FLUSH_BUFFER ] = "Flush Buffer",
+
+       /* Event, Channel and Session commands */
+       [ LTTNG_UST_ENABLE ] = "Enable",
+       [ LTTNG_UST_DISABLE ] = "Disable",
+
+       /* Tracepoint list commands */
+       [ LTTNG_UST_TRACEPOINT_LIST_GET ] = "List Next Tracepoint",
+       [ LTTNG_UST_TRACEPOINT_FIELD_LIST_GET ] = "List Next Tracepoint Field",
+
+       /* Event FD commands */
+       [ LTTNG_UST_FILTER ] = "Create Filter",
+};
+
+extern void lttng_ring_buffer_client_overwrite_init(void);
+extern void lttng_ring_buffer_client_discard_init(void);
+extern void lttng_ring_buffer_metadata_client_init(void);
+extern void lttng_ring_buffer_client_overwrite_exit(void);
+extern void lttng_ring_buffer_client_discard_exit(void);
+extern void lttng_ring_buffer_metadata_client_exit(void);
 
 /*
  * Force a read (imply TLS fixup for dlopen) of TLS variables.
@@ -147,6 +186,18 @@ void lttng_fixup_nest_count_tls(void)
        asm volatile ("" : : "m" (lttng_ust_nest_count));
 }
 
+static
+void print_cmd(int cmd, int handle)
+{
+       const char *cmd_name = "Unknown";
+
+       if (cmd_name_mapping[cmd]) {
+               cmd_name = cmd_name_mapping[cmd];
+       }
+       DBG("Message Received \"%s\", Handle \"%s\" (%d)", cmd_name,
+               lttng_ust_obj_get_name(handle), handle);
+}
+
 static
 int setup_local_apps(void)
 {
@@ -253,7 +304,6 @@ int handle_message(struct sock_info *sock_info,
        int ret = 0;
        const struct lttng_ust_objd_ops *ops;
        struct ustcomm_ust_reply lur;
-       int shm_fd, wait_fd;
        union ust_args args;
        ssize_t len;
 
@@ -262,7 +312,7 @@ int handle_message(struct sock_info *sock_info,
        memset(&lur, 0, sizeof(lur));
 
        if (lttng_ust_comm_should_quit) {
-               ret = -EPERM;
+               ret = -LTTNG_UST_ERR_EXITING;
                goto end;
        }
 
@@ -339,6 +389,7 @@ int handle_message(struct sock_info *sock_info,
                }
                bytecode->bc.len = lum->u.filter.data_size;
                bytecode->bc.reloc_offset = lum->u.filter.reloc_offset;
+               bytecode->bc.seqnum = lum->u.filter.seqnum;
                if (ops->cmd) {
                        ret = ops->cmd(lum->handle, lum->cmd,
                                        (unsigned long) bytecode,
@@ -353,6 +404,62 @@ int handle_message(struct sock_info *sock_info,
                }
                break;
        }
+       case LTTNG_UST_CHANNEL:
+       {
+               void *chan_data;
+
+               len = ustcomm_recv_channel_from_sessiond(sock,
+                               &chan_data, lum->u.channel.len);
+               switch (len) {
+               case 0: /* orderly shutdown */
+                       ret = 0;
+                       goto error;
+               default:
+                       if (len == lum->u.channel.len) {
+                               DBG("channel data received");
+                               break;
+                       } else if (len < 0) {
+                               DBG("Receive failed from lttng-sessiond with errno %d", (int) -len);
+                               if (len == -ECONNRESET) {
+                                       ERR("%s remote end closed connection", sock_info->name);
+                                       ret = len;
+                                       goto error;
+                               }
+                               ret = len;
+                               goto end;
+                       } else {
+                               DBG("incorrect channel data message size: %zd", len);
+                               ret = -EINVAL;
+                               goto end;
+                       }
+               }
+               args.channel.chan_data = chan_data;
+               if (ops->cmd)
+                       ret = ops->cmd(lum->handle, lum->cmd,
+                                       (unsigned long) &lum->u,
+                                       &args, sock_info);
+               else
+                       ret = -ENOSYS;
+               break;
+       }
+       case LTTNG_UST_STREAM:
+       {
+               /* Receive shm_fd, wakeup_fd */
+               ret = ustcomm_recv_stream_from_sessiond(sock,
+                       &lum->u.stream.len,
+                       &args.stream.shm_fd,
+                       &args.stream.wakeup_fd);
+               if (ret) {
+                       goto end;
+               }
+               if (ops->cmd)
+                       ret = ops->cmd(lum->handle, lum->cmd,
+                                       (unsigned long) &lum->u,
+                                       &args, sock_info);
+               else
+                       ret = -ENOSYS;
+               break;
+       }
        default:
                if (ops->cmd)
                        ret = ops->cmd(lum->handle, lum->cmd,
@@ -404,21 +511,6 @@ end:
        }
        if (ret >= 0) {
                switch (lum->cmd) {
-               case LTTNG_UST_STREAM:
-                       /*
-                        * Special-case reply to send stream info.
-                        * Use lum.u output.
-                        */
-                       lur.u.stream.memory_map_size = *args.stream.memory_map_size;
-                       shm_fd = *args.stream.shm_fd;
-                       wait_fd = *args.stream.wait_fd;
-                       break;
-               case LTTNG_UST_METADATA:
-               case LTTNG_UST_CHANNEL:
-                       lur.u.channel.memory_map_size = *args.channel.memory_map_size;
-                       shm_fd = *args.channel.shm_fd;
-                       wait_fd = *args.channel.wait_fd;
-                       break;
                case LTTNG_UST_TRACER_VERSION:
                        lur.u.version = lum->u.version;
                        break;
@@ -427,42 +519,13 @@ end:
                        break;
                }
        }
+       DBG("Return value: %d", lur.ret_val);
        ret = send_reply(sock, &lur);
        if (ret < 0) {
                DBG("error sending reply");
                goto error;
        }
 
-       if ((lum->cmd == LTTNG_UST_STREAM
-            || lum->cmd == LTTNG_UST_CHANNEL
-            || lum->cmd == LTTNG_UST_METADATA)
-                       && lur.ret_code == LTTNG_UST_OK) {
-               int sendret = 0;
-
-               /* we also need to send the file descriptors. */
-               ret = ustcomm_send_fds_unix_sock(sock,
-                       &shm_fd, &shm_fd,
-                       1, sizeof(int));
-               if (ret < 0) {
-                       ERR("send shm_fd");
-                       sendret = ret;
-               }
-               /*
-                * The sessiond expects 2 file descriptors, even upon
-                * error.
-                */
-               ret = ustcomm_send_fds_unix_sock(sock,
-                       &wait_fd, &wait_fd,
-                       1, sizeof(int));
-               if (ret < 0) {
-                       perror("send wait_fd");
-                       goto error;
-               }
-               if (sendret) {
-                       ret = sendret;
-                       goto error;
-               }
-       }
        /*
         * LTTNG_UST_TRACEPOINT_FIELD_LIST_GET needs to send the field
         * after the reply.
@@ -483,49 +546,6 @@ end:
                        }
                }
        }
-       /*
-        * We still have the memory map reference, and the fds have been
-        * sent to the sessiond. We can therefore close those fds. Note
-        * that we keep the write side of the wait_fd open, but close
-        * the read side.
-        */
-       if (lur.ret_code == LTTNG_UST_OK) {
-               switch (lum->cmd) {
-               case LTTNG_UST_STREAM:
-                       if (shm_fd >= 0) {
-                               ret = close(shm_fd);
-                               if (ret) {
-                                       PERROR("Error closing stream shm_fd");
-                               }
-                               *args.stream.shm_fd = -1;
-                       }
-                       if (wait_fd >= 0) {
-                               ret = close(wait_fd);
-                               if (ret) {
-                                       PERROR("Error closing stream wait_fd");
-                               }
-                               *args.stream.wait_fd = -1;
-                       }
-                       break;
-               case LTTNG_UST_METADATA:
-               case LTTNG_UST_CHANNEL:
-                       if (shm_fd >= 0) {
-                               ret = close(shm_fd);
-                               if (ret) {
-                                       PERROR("Error closing channel shm_fd");
-                               }
-                               *args.channel.shm_fd = -1;
-                       }
-                       if (wait_fd >= 0) {
-                               ret = close(wait_fd);
-                               if (ret) {
-                                       PERROR("Error closing channel wait_fd");
-                               }
-                               *args.channel.wait_fd = -1;
-                       }
-                       break;
-               }
-       }
 
 error:
        ust_unlock();
@@ -815,7 +835,6 @@ restart:
        ust_lock();
 
        if (lttng_ust_comm_should_quit) {
-               ust_unlock();
                goto quit;
        }
 
@@ -853,7 +872,6 @@ restart:
                ret = lttng_abi_create_root_handle();
                if (ret < 0) {
                        ERR("Error creating root handle");
-                       ust_unlock();
                        goto quit;
                }
                sock_info->root_handle = ret;
@@ -881,8 +899,11 @@ restart:
                len = ustcomm_recv_unix_sock(sock, &lum, sizeof(lum));
                switch (len) {
                case 0: /* orderly shutdown */
-                       DBG("%s ltt-sessiond has performed an orderly shutdown", sock_info->name);
+                       DBG("%s lttng-sessiond has performed an orderly shutdown", sock_info->name);
                        ust_lock();
+                       if (lttng_ust_comm_should_quit) {
+                               goto quit;
+                       }
                        /*
                         * Either sessiond has shutdown or refused us by closing the socket.
                         * In either case, we don't want to delay construction execution,
@@ -898,7 +919,7 @@ restart:
                        ust_unlock();
                        goto end;
                case sizeof(lum):
-                       DBG("message received");
+                       print_cmd(lum.cmd, lum.handle);
                        ret = handle_message(sock_info, sock, &lum);
                        if (ret) {
                                ERR("Error handling message for %s socket", sock_info->name);
@@ -920,11 +941,17 @@ restart:
        }
 end:
        ust_lock();
+       if (lttng_ust_comm_should_quit) {
+               goto quit;
+       }
        /* Cleanup socket handles before trying to reconnect */
        lttng_ust_objd_table_owner_cleanup(sock_info);
        ust_unlock();
        goto restart;   /* try to reconnect */
+
 quit:
+       sock_info->thread_active = 0;
+       ust_unlock();
        return NULL;
 }
 
@@ -988,7 +1015,6 @@ void __attribute__((constructor)) lttng_ust_init(void)
         * to be the dynamic linker mutex) and ust_lock, taken within
         * the ust lock.
         */
-       lttng_fixup_event_tls();
        lttng_fixup_ringbuffer_tls();
        lttng_fixup_vtid_tls();
        lttng_fixup_nest_count_tls();
@@ -1002,9 +1028,9 @@ void __attribute__((constructor)) lttng_ust_init(void)
         */
        init_usterr();
        init_tracepoint();
-       ltt_ring_buffer_metadata_client_init();
-       ltt_ring_buffer_client_overwrite_init();
-       ltt_ring_buffer_client_discard_init();
+       lttng_ring_buffer_metadata_client_init();
+       lttng_ring_buffer_client_overwrite_init();
+       lttng_ring_buffer_client_discard_init();
 
        timeout_mode = get_timeout(&constructor_timeout);
 
@@ -1036,17 +1062,24 @@ void __attribute__((constructor)) lttng_ust_init(void)
                ERR("pthread_attr_setdetachstate: %s", strerror(ret));
        }
 
+       ust_lock();
        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;
+       ust_unlock();
+
        if (local_apps.allowed) {
+               ust_lock();
                ret = pthread_create(&local_apps.ust_listener, &thread_attr,
                                ust_listener_thread, &local_apps);
                if (ret) {
                        ERR("pthread_create local: %s", strerror(ret));
                }
+               local_apps.thread_active = 1;
+               ust_unlock();
        } else {
                handle_register_done(&local_apps);
        }
@@ -1068,7 +1101,7 @@ void __attribute__((constructor)) lttng_ust_init(void)
                                        &constructor_timeout);
                } while (ret < 0 && errno == EINTR);
                if (ret < 0 && errno == ETIMEDOUT) {
-                       ERR("Timed out waiting for ltt-sessiond");
+                       ERR("Timed out waiting for lttng-sessiond");
                } else {
                        assert(!ret);
                }
@@ -1100,9 +1133,9 @@ void lttng_ust_cleanup(int exiting)
         */
        lttng_ust_abi_exit();
        lttng_ust_events_exit();
-       ltt_ring_buffer_client_discard_exit();
-       ltt_ring_buffer_client_overwrite_exit();
-       ltt_ring_buffer_metadata_client_exit();
+       lttng_ring_buffer_client_discard_exit();
+       lttng_ring_buffer_client_overwrite_exit();
+       lttng_ring_buffer_metadata_client_exit();
        exit_tracepoint();
        if (!exiting) {
                /* Reinitialize values for fork */
@@ -1129,21 +1162,28 @@ void __attribute__((destructor)) lttng_ust_exit(void)
         */
        ust_lock();
        lttng_ust_comm_should_quit = 1;
-       ust_unlock();
 
        /* cancel threads */
-       ret = pthread_cancel(global_apps.ust_listener);
-       if (ret) {
-               ERR("Error cancelling global ust listener thread: %s",
-                       strerror(ret));
+       if (global_apps.thread_active) {
+               ret = pthread_cancel(global_apps.ust_listener);
+               if (ret) {
+                       ERR("Error cancelling global ust listener thread: %s",
+                               strerror(ret));
+               } else {
+                       global_apps.thread_active = 0;
+               }
        }
-       if (local_apps.allowed) {
+       if (local_apps.thread_active) {
                ret = pthread_cancel(local_apps.ust_listener);
                if (ret) {
                        ERR("Error cancelling local ust listener thread: %s",
                                strerror(ret));
+               } else {
+                       local_apps.thread_active = 0;
                }
        }
+       ust_unlock();
+
        /*
         * Do NOT join threads: use of sys_futex makes it impossible to
         * join the threads without using async-cancel, but async-cancel
This page took 0.029582 seconds and 4 git commands to generate.