Fix: bad logical check of error codes
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index 2d8cb2c279c8306eb25cc8f6a02d56be70cbb31e..ab08ac0e4d04ccf409c8d02e358e11f0033a0520 100644 (file)
@@ -287,7 +287,8 @@ void delete_ust_app_event(int sock, struct ust_app_event *ua_event)
        assert(ua_event);
 
        free(ua_event->filter);
-
+       if (ua_event->exclusion != NULL)
+               free(ua_event->exclusion);
        if (ua_event->obj != NULL) {
                ret = ustctl_release_object(sock, ua_event->obj);
                if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
@@ -405,7 +406,8 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan,
        if (ua_chan->obj != NULL) {
                /* Remove channel from application UST object descriptor. */
                iter.iter.node = &ua_chan->ust_objd_node.node;
-               lttng_ht_del(app->ust_objd, &iter);
+               ret = lttng_ht_del(app->ust_objd, &iter);
+               assert(!ret);
                ret = ustctl_release_object(sock, ua_chan->obj);
                if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
                        ERR("UST app sock %d release channel obj failed with ret %d",
@@ -480,6 +482,25 @@ push_data:
        ret = consumer_push_metadata(socket, registry->metadata_key,
                        metadata_str, len, offset);
        if (ret < 0) {
+               /*
+                * There is an acceptable race here between the registry metadata key
+                * assignment and the creation on the consumer. The session daemon can
+                * concurrently push metadata for this registry while being created on
+                * the consumer since the metadata key of the registry is assigned
+                * *before* it is setup to avoid the consumer to ask for metadata that
+                * could possibly be not found in the session daemon.
+                *
+                * The metadata will get pushed either by the session being stopped or
+                * the consumer requesting metadata if that race is triggered.
+                */
+               if (ret == -LTTCOMM_CONSUMERD_CHANNEL_FAIL) {
+                       ret = 0;
+               }
+
+               /* Update back the actual metadata len sent since it failed here. */
+               pthread_mutex_lock(&registry->lock);
+               registry->metadata_len_sent -= len;
+               pthread_mutex_unlock(&registry->lock);
                ret_val = ret;
                goto error_push;
        }
@@ -1021,7 +1042,8 @@ error:
  * Return an ust_app_event object or NULL on error.
  */
 static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
-               char *name, struct lttng_ust_filter_bytecode *filter, int loglevel)
+               char *name, struct lttng_ust_filter_bytecode *filter, int loglevel,
+               const struct lttng_event_exclusion *exclusion)
 {
        struct lttng_ht_iter iter;
        struct lttng_ht_node_str *node;
@@ -1035,6 +1057,8 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
        key.name = name;
        key.filter = filter;
        key.loglevel = loglevel;
+       /* lttng_event_exclusion and lttng_ust_event_exclusion structures are similar */
+       key.exclusion = (struct lttng_ust_event_exclusion *)exclusion;
 
        /* Lookup using the event name as hash and a custom match fct. */
        cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
@@ -1132,6 +1156,47 @@ error:
        return ret;
 }
 
+/*
+ * Set event exclusions on the tracer.
+ */
+static
+int set_ust_event_exclusion(struct ust_app_event *ua_event,
+               struct ust_app *app)
+{
+       int ret;
+
+       health_code_update();
+
+       if (!ua_event->exclusion || !ua_event->exclusion->count) {
+               ret = 0;
+               goto error;
+       }
+
+       ret = ustctl_set_exclusion(app->sock, ua_event->exclusion,
+                       ua_event->obj);
+       if (ret < 0) {
+               if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
+                       ERR("UST app event %s exclusions failed for app (pid: %d) "
+                                       "with ret %d", ua_event->attr.name, app->pid, ret);
+               } else {
+                       /*
+                        * This is normal behavior, an application can die during the
+                        * creation process. Don't report an error so the execution can
+                        * continue normally.
+                        */
+                       ret = 0;
+                       DBG3("UST app event exclusion failed. Application is dead.");
+               }
+               goto error;
+       }
+
+       DBG2("UST exclusion set successfully for event %s", ua_event->name);
+
+error:
+       health_code_update();
+       return ret;
+}
+
 /*
  * Disable the specified event on to UST tracer for the UST session.
  */
@@ -1371,6 +1436,14 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
                }
        }
 
+       /* Set exclusions for the event */
+       if (ua_event->exclusion) {
+               ret = set_ust_event_exclusion(ua_event, app);
+               if (ret < 0) {
+                       goto error;
+               }
+       }
+
        /* If event not enabled, disable it on the tracer */
        if (ua_event->enabled == 0) {
                ret = disable_ust_event(app, ua_sess, ua_event);
@@ -1406,6 +1479,8 @@ error:
 static void shadow_copy_event(struct ust_app_event *ua_event,
                struct ltt_ust_event *uevent)
 {
+       size_t exclusion_alloc_size;
+
        strncpy(ua_event->name, uevent->attr.name, sizeof(ua_event->name));
        ua_event->name[sizeof(ua_event->name) - 1] = '\0';
 
@@ -1419,6 +1494,19 @@ static void shadow_copy_event(struct ust_app_event *ua_event,
                ua_event->filter = alloc_copy_ust_app_filter(uevent->filter);
                /* Filter might be NULL here in case of ENONEM. */
        }
+
+       /* Copy exclusion data */
+       if (uevent->exclusion) {
+               exclusion_alloc_size = sizeof(struct lttng_ust_event_exclusion) +
+                               LTTNG_UST_SYM_NAME_LEN * uevent->exclusion->count;
+               ua_event->exclusion = zmalloc(exclusion_alloc_size);
+               if (ua_event->exclusion == NULL) {
+                       PERROR("malloc");
+               } else {
+                       memcpy(ua_event->exclusion, uevent->exclusion,
+                                       exclusion_alloc_size);
+               }
+       }
 }
 
 /*
@@ -1470,7 +1558,7 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan,
        /* Copy all events from ltt ust channel to ust app channel */
        cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) {
                ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
-                               uevent->filter, uevent->attr.loglevel);
+                               uevent->filter, uevent->attr.loglevel, uevent->exclusion);
                if (ua_event == NULL) {
                        DBG2("UST event %s not found on shadow copy channel",
                                        uevent->attr.name);
@@ -2583,7 +2671,7 @@ int create_ust_app_event(struct ust_app_session *ua_sess,
 
        /* Get event node */
        ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
-                       uevent->filter, uevent->attr.loglevel);
+                       uevent->filter, uevent->attr.loglevel, uevent->exclusion);
        if (ua_event != NULL) {
                ret = -EEXIST;
                goto end;
@@ -3060,7 +3148,7 @@ int ust_app_list_events(struct lttng_event **events)
                        /* Handle ustctl error. */
                        if (ret < 0) {
                                free(tmp_event);
-                               if (ret != -LTTNG_UST_ERR_EXITING || ret != -EPIPE) {
+                               if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
                                        ERR("UST app tp list get failed for app %d with ret %d",
                                                        app->sock, ret);
                                } else {
@@ -3160,7 +3248,7 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                        /* Handle ustctl error. */
                        if (ret < 0) {
                                free(tmp_event);
-                               if (ret != -LTTNG_UST_ERR_EXITING || ret != -EPIPE) {
+                               if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
                                        ERR("UST app tp list field failed for app %d with ret %d",
                                                        app->sock, ret);
                                } else {
@@ -3194,12 +3282,13 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                        }
 
                        memcpy(tmp_event[count].field_name, uiter.field_name, LTTNG_UST_SYM_NAME_LEN);
-                       tmp_event[count].type = uiter.type;
+                       /* Mapping between these enums matches 1 to 1. */
+                       tmp_event[count].type = (enum lttng_event_field_type) uiter.type;
                        tmp_event[count].nowrite = uiter.nowrite;
 
                        memcpy(tmp_event[count].event.name, uiter.event_name, LTTNG_UST_SYM_NAME_LEN);
                        tmp_event[count].event.loglevel = uiter.loglevel;
-                       tmp_event[count].event.type = LTTNG_UST_TRACEPOINT;
+                       tmp_event[count].event.type = LTTNG_EVENT_TRACEPOINT;
                        tmp_event[count].event.pid = app->pid;
                        tmp_event[count].event.enabled = -1;
                        count++;
@@ -3641,7 +3730,7 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
 
                /* Get event node */
                ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
-                               uevent->filter, uevent->attr.loglevel);
+                               uevent->filter, uevent->attr.loglevel, uevent->exclusion);
                if (ua_event == NULL) {
                        DBG3("UST app enable event %s not found for app PID %d."
                                        "Skipping app", uevent->attr.name, app->pid);
@@ -4367,7 +4456,7 @@ int ust_app_enable_event_pid(struct ltt_ust_session *usess,
        ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
 
        ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
-                       uevent->filter, uevent->attr.loglevel);
+                       uevent->filter, uevent->attr.loglevel, uevent->exclusion);
        if (ua_event == NULL) {
                ret = create_ust_app_event(ua_sess, ua_chan, uevent, app);
                if (ret < 0) {
This page took 0.029435 seconds and 5 git commands to generate.