Send filter expression string to session daemon
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index bed8f830d6e887b79a4c67081ed6edaef1142a16..4b8d82efe255d398d9e5eba605be42d96cec5421 100644 (file)
@@ -30,7 +30,7 @@
 #include "channel.h"
 #include "consumer.h"
 #include "event.h"
-#include "health.h"
+#include "health-sessiond.h"
 #include "kernel.h"
 #include "kernel-consumer.h"
 #include "lttng-sessiond.h"
@@ -182,6 +182,55 @@ static void list_lttng_channels(int domain, struct ltt_session *session,
        }
 }
 
+/*
+ * Create a list of JUL domain events.
+ *
+ * Return number of events in list on success or else a negative value.
+ */
+static int list_lttng_jul_events(struct jul_domain *dom,
+               struct lttng_event **events)
+{
+       int i = 0, ret = 0;
+       unsigned int nb_event = 0;
+       struct jul_event *event;
+       struct lttng_event *tmp_events;
+       struct lttng_ht_iter iter;
+
+       assert(dom);
+       assert(events);
+
+       DBG3("Listing JUL events");
+
+       nb_event = lttng_ht_get_count(dom->events);
+       if (nb_event == 0) {
+               ret = nb_event;
+               goto error;
+       }
+
+       tmp_events = zmalloc(nb_event * sizeof(*tmp_events));
+       if (!tmp_events) {
+               PERROR("zmalloc JUL events session");
+               ret = -LTTNG_ERR_FATAL;
+               goto error;
+       }
+
+       rcu_read_lock();
+       cds_lfht_for_each_entry(dom->events->ht, &iter.iter, event, node.node) {
+               strncpy(tmp_events[i].name, event->name, sizeof(tmp_events[i].name));
+               tmp_events[i].name[sizeof(tmp_events[i].name) - 1] = '\0';
+               tmp_events[i].enabled = event->enabled;
+               i++;
+       }
+       rcu_read_unlock();
+
+       *events = tmp_events;
+       ret = nb_event;
+
+error:
+       assert(nb_event == i);
+       return ret;
+}
+
 /*
  * Create a list of ust global domain events.
  */
@@ -256,6 +305,9 @@ static int list_lttng_ust_global_events(char *channel_name,
                if (uevent->filter) {
                        tmp[i].filter = 1;
                }
+               if (uevent->exclusion) {
+                       tmp[i].exclusion = 1;
+               }
                i++;
        }
 
@@ -547,7 +599,8 @@ error:
  */
 static int send_consumer_relayd_socket(int domain, unsigned int session_id,
                struct lttng_uri *relayd_uri, struct consumer_output *consumer,
-               struct consumer_socket *consumer_sock)
+               struct consumer_socket *consumer_sock,
+               char *session_name, char *hostname, int session_live_timer)
 {
        int ret;
        struct lttcomm_relayd_sock *rsock = NULL;
@@ -573,7 +626,8 @@ static int send_consumer_relayd_socket(int domain, unsigned int session_id,
 
        /* Send relayd socket to consumer. */
        ret = consumer_send_relayd_socket(consumer_sock, rsock, consumer,
-                       relayd_uri->stype, session_id);
+                       relayd_uri->stype, session_id,
+                       session_name, hostname, session_live_timer);
        if (ret < 0) {
                ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
                goto close_sock;
@@ -615,7 +669,8 @@ error:
  * session.
  */
 static int send_consumer_relayd_sockets(int domain, unsigned int session_id,
-               struct consumer_output *consumer, struct consumer_socket *sock)
+               struct consumer_output *consumer, struct consumer_socket *sock,
+               char *session_name, char *hostname, int session_live_timer)
 {
        int ret = LTTNG_OK;
 
@@ -625,7 +680,8 @@ static int send_consumer_relayd_sockets(int domain, unsigned int session_id,
        /* Sending control relayd socket. */
        if (!sock->control_sock_sent) {
                ret = send_consumer_relayd_socket(domain, session_id,
-                               &consumer->dst.net.control, consumer, sock);
+                               &consumer->dst.net.control, consumer, sock,
+                               session_name, hostname, session_live_timer);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -634,7 +690,8 @@ static int send_consumer_relayd_sockets(int domain, unsigned int session_id,
        /* Sending data relayd socket. */
        if (!sock->data_sock_sent) {
                ret = send_consumer_relayd_socket(domain, session_id,
-                               &consumer->dst.net.data, consumer, sock);
+                               &consumer->dst.net.data, consumer, sock,
+                               session_name, hostname, session_live_timer);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -673,7 +730,9 @@ int cmd_setup_relayd(struct ltt_session *session)
                                socket, node.node) {
                        pthread_mutex_lock(socket->lock);
                        ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_UST, session->id,
-                                       usess->consumer, socket);
+                                       usess->consumer, socket,
+                                       session->name, session->hostname,
+                                       session->live_timer);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
                                goto error;
@@ -689,7 +748,9 @@ int cmd_setup_relayd(struct ltt_session *session)
                                socket, node.node) {
                        pthread_mutex_lock(socket->lock);
                        ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_KERNEL, session->id,
-                                       ksess->consumer, socket);
+                                       ksess->consumer, socket,
+                                       session->name, session->hostname,
+                                       session->live_timer);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
                                goto error;
@@ -1013,6 +1074,19 @@ int cmd_disable_event(struct ltt_session *session, int domain,
                                channel_name);
                break;
        }
+       case LTTNG_DOMAIN_JUL:
+       {
+               struct ltt_ust_session *usess = session->ust_session;
+
+               assert(usess);
+
+               ret = event_jul_disable(usess, event_name);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
+               break;
+       }
 #if 0
        case LTTNG_DOMAIN_UST_EXEC_NAME:
        case LTTNG_DOMAIN_UST_PID:
@@ -1103,6 +1177,19 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
 
                DBG3("Disable all UST events in channel %s completed", channel_name);
 
+               break;
+       }
+       case LTTNG_DOMAIN_JUL:
+       {
+               struct ltt_ust_session *usess = session->ust_session;
+
+               assert(usess);
+
+               ret = event_jul_disable_all(usess);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
                break;
        }
 #if 0
@@ -1222,7 +1309,10 @@ error:
  */
 int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain,
                char *channel_name, struct lttng_event *event,
-               struct lttng_filter_bytecode *filter, int wpipe)
+               char *filter_expression,
+               struct lttng_filter_bytecode *filter,
+               struct lttng_event_exclusion *exclusion,
+               int wpipe)
 {
        int ret, channel_created = 0;
        struct lttng_channel *attr;
@@ -1335,12 +1425,60 @@ int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain,
                }
 
                /* At this point, the session and channel exist on the tracer */
-               ret = event_ust_enable_tracepoint(usess, uchan, event, filter);
+               ret = event_ust_enable_tracepoint(usess, uchan, event,
+                               filter_expression, filter, exclusion);
                if (ret != LTTNG_OK) {
                        goto error;
                }
                break;
        }
+       case LTTNG_DOMAIN_JUL:
+       {
+               struct lttng_event uevent;
+               struct lttng_domain tmp_dom;
+               struct ltt_ust_session *usess = session->ust_session;
+
+               assert(usess);
+
+               /* Create the default JUL tracepoint. */
+               memset(&uevent, 0, sizeof(uevent));
+               uevent.type = LTTNG_EVENT_TRACEPOINT;
+               uevent.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
+               if (is_root) {
+                       strncpy(uevent.name, DEFAULT_SYS_JUL_EVENT_NAME,
+                                       sizeof(uevent.name));
+               } else {
+                       strncpy(uevent.name, DEFAULT_USER_JUL_EVENT_NAME,
+                                       sizeof(uevent.name));
+               }
+               uevent.name[sizeof(uevent.name) - 1] = '\0';
+
+               /*
+                * The domain type is changed because we are about to enable the
+                * default channel and event for the JUL domain that are hardcoded.
+                * This happens in the UST domain.
+                */
+               memcpy(&tmp_dom, domain, sizeof(tmp_dom));
+               tmp_dom.type = LTTNG_DOMAIN_UST;
+
+               ret = cmd_enable_event(session, &tmp_dom, DEFAULT_JUL_CHANNEL_NAME,
+                       &uevent, NULL, NULL, NULL, wpipe);
+               if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_ENABLED) {
+                       goto error;
+               }
+
+               /* The wild card * means that everything should be enabled. */
+               if (strncmp(event->name, "*", 1) == 0 && strlen(event->name) == 1) {
+                       ret = event_jul_enable_all(usess, event);
+               } else {
+                       ret = event_jul_enable(usess, event);
+               }
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
+               break;
+       }
 #if 0
        case LTTNG_DOMAIN_UST_EXEC_NAME:
        case LTTNG_DOMAIN_UST_PID:
@@ -1363,6 +1501,7 @@ error:
  */
 int cmd_enable_event_all(struct ltt_session *session,
                struct lttng_domain *domain, char *channel_name, int event_type,
+               char *filter_expression,
                struct lttng_filter_bytecode *filter, int wpipe)
 {
        int ret;
@@ -1496,7 +1635,8 @@ int cmd_enable_event_all(struct ltt_session *session,
                switch (event_type) {
                case LTTNG_EVENT_ALL:
                case LTTNG_EVENT_TRACEPOINT:
-                       ret = event_ust_enable_all_tracepoints(usess, uchan, filter);
+                       ret = event_ust_enable_all_tracepoints(usess, uchan,
+                               filter_expression, filter);
                        if (ret != LTTNG_OK) {
                                goto error;
                        }
@@ -1511,6 +1651,52 @@ int cmd_enable_event_all(struct ltt_session *session,
                        goto error;
                }
 
+               break;
+       }
+       case LTTNG_DOMAIN_JUL:
+       {
+               struct lttng_event uevent, event;
+               struct lttng_domain tmp_dom;
+               struct ltt_ust_session *usess = session->ust_session;
+
+               assert(usess);
+
+               /* Create the default JUL tracepoint. */
+               uevent.type = LTTNG_EVENT_TRACEPOINT;
+               uevent.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
+               if (is_root) {
+                       strncpy(uevent.name, DEFAULT_SYS_JUL_EVENT_NAME,
+                                       sizeof(uevent.name));
+               } else {
+                       strncpy(uevent.name, DEFAULT_USER_JUL_EVENT_NAME,
+                                       sizeof(uevent.name));
+               }
+               uevent.name[sizeof(uevent.name) - 1] = '\0';
+
+               /*
+                * The domain type is changed because we are about to enable the
+                * default channel and event for the JUL domain that are hardcoded.
+                * This happens in the UST domain.
+                */
+               memcpy(&tmp_dom, domain, sizeof(tmp_dom));
+               tmp_dom.type = LTTNG_DOMAIN_UST;
+
+               ret = cmd_enable_event(session, &tmp_dom, DEFAULT_JUL_CHANNEL_NAME,
+                       &uevent, NULL, NULL, NULL, wpipe);
+               if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_ENABLED) {
+                       goto error;
+               }
+
+               event.loglevel = LTTNG_LOGLEVEL_JUL_ALL;
+               event.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
+               strncpy(event.name, "*", sizeof(event.name));
+               event.name[sizeof(event.name) - 1] = '\0';
+
+               ret = event_jul_enable_all(usess, &event);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
                break;
        }
 #if 0
@@ -1554,6 +1740,13 @@ ssize_t cmd_list_tracepoints(int domain, struct lttng_event **events)
                        goto error;
                }
                break;
+       case LTTNG_DOMAIN_JUL:
+               nb_events = jul_list_events(events);
+               if (nb_events < 0) {
+                       ret = LTTNG_ERR_UST_LIST_FAIL;
+                       goto error;
+               }
+               break;
        default:
                ret = LTTNG_ERR_UND;
                goto error;
@@ -1602,6 +1795,7 @@ error:
 int cmd_start_trace(struct ltt_session *session)
 {
        int ret;
+       unsigned long nb_chan = 0;
        struct ltt_kernel_session *ksession;
        struct ltt_ust_session *usess;
 
@@ -1617,6 +1811,21 @@ int cmd_start_trace(struct ltt_session *session)
                goto error;
        }
 
+       /*
+        * Starting a session without channel is useless since after that it's not
+        * possible to enable channel thus inform the client.
+        */
+       if (usess && usess->domain_global.channels) {
+               nb_chan += lttng_ht_get_count(usess->domain_global.channels);
+       }
+       if (ksession) {
+               nb_chan += ksession->channel_count;
+       }
+       if (!nb_chan) {
+               ret = LTTNG_ERR_NO_CHANNEL;
+               goto error;
+       }
+
        session->enabled = 1;
 
        /* Kernel tracing */
@@ -1976,7 +2185,14 @@ int cmd_calibrate(int domain, struct lttng_calibrate *calibrate)
        {
                struct lttng_kernel_calibrate kcalibrate;
 
-               kcalibrate.type = calibrate->type;
+               switch (calibrate->type) {
+               case LTTNG_CALIBRATE_FUNCTION:
+               default:
+                       /* Default and only possible calibrate option. */
+                       kcalibrate.type = LTTNG_KERNEL_CALIBRATE_KRETPROBE;
+                       break;
+               }
+
                ret = kernel_calibrate(kernel_tracer_fd, &kcalibrate);
                if (ret < 0) {
                        ret = LTTNG_ERR_KERN_ENABLE_FAIL;
@@ -1988,7 +2204,14 @@ int cmd_calibrate(int domain, struct lttng_calibrate *calibrate)
        {
                struct lttng_ust_calibrate ucalibrate;
 
-               ucalibrate.type = calibrate->type;
+               switch (calibrate->type) {
+               case LTTNG_CALIBRATE_FUNCTION:
+               default:
+                       /* Default and only possible calibrate option. */
+                       ucalibrate.type = LTTNG_UST_CALIBRATE_TRACEPOINT;
+                       break;
+               }
+
                ret = ust_app_calibrate_glb(&ucalibrate);
                if (ret < 0) {
                        ret = LTTNG_ERR_UST_CALIBRATE_FAIL;
@@ -2102,6 +2325,10 @@ ssize_t cmd_list_domains(struct ltt_session *session,
        if (session->ust_session != NULL) {
                DBG3("Listing domains found UST global domain");
                nb_dom++;
+
+               if (session->ust_session->domain_jul.being_used) {
+                       nb_dom++;
+               }
        }
 
        *domains = zmalloc(nb_dom * sizeof(struct lttng_domain));
@@ -2119,6 +2346,12 @@ ssize_t cmd_list_domains(struct ltt_session *session,
                (*domains)[index].type = LTTNG_DOMAIN_UST;
                (*domains)[index].buf_type = session->ust_session->buffer_type;
                index++;
+
+               if (session->ust_session->domain_jul.being_used) {
+                       (*domains)[index].type = LTTNG_DOMAIN_JUL;
+                       (*domains)[index].buf_type = session->ust_session->buffer_type;
+                       index++;
+               }
        }
 
        return nb_dom;
@@ -2209,6 +2442,12 @@ ssize_t cmd_list_events(int domain, struct ltt_session *session,
                }
                break;
        }
+       case LTTNG_DOMAIN_JUL:
+               if (session->ust_session) {
+                       nb_event = list_lttng_jul_events(
+                                       &session->ust_session->domain_jul, events);
+               }
+               break;
        default:
                ret = LTTNG_ERR_UND;
                goto error;
@@ -2271,6 +2510,7 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions, uid_t uid,
                sessions[i].name[NAME_MAX - 1] = '\0';
                sessions[i].enabled = session->enabled;
                sessions[i].snapshot_mode = session->snapshot_mode;
+               sessions[i].live_timer_interval = session->live_timer;
                i++;
        }
 }
@@ -2539,7 +2779,9 @@ static int set_relayd_for_snapshot(struct consumer_output *consumer,
        cds_lfht_for_each_entry(snap_output->consumer->socks->ht, &iter.iter,
                        socket, node.node) {
                ret = send_consumer_relayd_sockets(0, session->id,
-                               snap_output->consumer, socket);
+                               snap_output->consumer, socket,
+                               session->name, session->hostname,
+                               session->live_timer);
                if (ret != LTTNG_OK) {
                        rcu_read_unlock();
                        goto error;
@@ -2554,7 +2796,7 @@ error:
 /*
  * Record a kernel snapshot.
  *
- * Return 0 on success or a LTTNG_ERR code.
+ * Return LTTNG_OK on success or a LTTNG_ERR code.
  */
 static int record_kernel_snapshot(struct ltt_kernel_session *ksess,
                struct snapshot_output *output, struct ltt_session *session,
@@ -2643,12 +2885,17 @@ static int record_ust_snapshot(struct ltt_ust_session *usess,
 
        ret = ust_app_snapshot_record(usess, output, wait, nb_streams);
        if (ret < 0) {
-               if (ret == -EINVAL) {
+               switch (-ret) {
+               case EINVAL:
                        ret = LTTNG_ERR_INVALID;
-                       goto error_snapshot;
+                       break;
+               case ENODATA:
+                       ret = LTTNG_ERR_SNAPSHOT_NODATA;
+                       break;
+               default:
+                       ret = LTTNG_ERR_SNAPSHOT_FAIL;
+                       break;
                }
-
-               ret = LTTNG_ERR_SNAPSHOT_FAIL;
                goto error_snapshot;
        }
 
This page took 0.031665 seconds and 5 git commands to generate.