Fix: add missing semicolons after MSG, DBG, ERR print macros
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index c4d9fb5a40c6b14a73bac79014396a8710599ede..4cba76a2195256747312982fca8c363699d9bc66 100644 (file)
@@ -101,12 +101,14 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key)
 {
        struct ust_app_event *event;
        const struct ust_app_ht_key *key;
+       int ev_loglevel_value;
 
        assert(node);
        assert(_key);
 
        event = caa_container_of(node, struct ust_app_event, node.node);
        key = _key;
+       ev_loglevel_value = event->attr.loglevel;
 
        /* Match the 4 elements of the key: name, filter, loglevel, exclusions */
 
@@ -116,9 +118,10 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key)
        }
 
        /* Event loglevel. */
-       if (event->attr.loglevel != key->loglevel) {
+       if (ev_loglevel_value != key->loglevel_type) {
                if (event->attr.loglevel_type == LTTNG_UST_LOGLEVEL_ALL
-                               && key->loglevel == 0 && event->attr.loglevel == -1) {
+                               && key->loglevel_type == 0 &&
+                               ev_loglevel_value == -1) {
                        /*
                         * Match is accepted. This is because on event creation, the
                         * loglevel is set to -1 if the event loglevel type is ALL so 0 and
@@ -184,7 +187,7 @@ static void add_unique_ust_app_event(struct ust_app_channel *ua_chan,
        ht = ua_chan->events;
        key.name = event->attr.name;
        key.filter = event->filter;
-       key.loglevel = event->attr.loglevel;
+       key.loglevel_type = event->attr.loglevel;
        key.exclusion = event->exclusion;
 
        node_ptr = cds_lfht_add_unique(ht->ht,
@@ -1149,7 +1152,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_filter_bytecode *filter, int loglevel,
+               char *name, struct lttng_filter_bytecode *filter,
+               int loglevel_value,
                const struct lttng_event_exclusion *exclusion)
 {
        struct lttng_ht_iter iter;
@@ -1163,7 +1167,7 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
        /* Setup key for event lookup. */
        key.name = name;
        key.filter = filter;
-       key.loglevel = loglevel;
+       key.loglevel_type = loglevel_value;
        /* lttng_event_exclusion and lttng_ust_event_exclusion structures are similar */
        key.exclusion = exclusion;
 
@@ -2702,9 +2706,6 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan,
                        (void) release_ust_app_stream(-1, &stream, app);
                        if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                                ret = -ENOTCONN; /* Caused by app exiting. */
-                               goto error_stream_unlock;
-                       } else if (ret < 0) {
-                               goto error_stream_unlock;
                        }
                        goto error_stream_unlock;
                }
@@ -3478,7 +3479,9 @@ int ust_app_list_events(struct lttng_event **events)
                                }
                                free(tmp_event);
                                release_ret = ustctl_release_handle(app->sock, handle);
-                               if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+                               if (release_ret < 0 &&
+                                               release_ret != -LTTNG_UST_ERR_EXITING &&
+                                               release_ret != -EPIPE) {
                                        ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
                                }
                                pthread_mutex_unlock(&app->sock_lock);
@@ -3503,7 +3506,9 @@ int ust_app_list_events(struct lttng_event **events)
                                        free(tmp_event);
                                        ret = -ENOMEM;
                                        release_ret = ustctl_release_handle(app->sock, handle);
-                                       if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+                                       if (release_ret < 0 &&
+                                                       release_ret != -LTTNG_UST_ERR_EXITING &&
+                                                       release_ret != -EPIPE) {
                                                ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
                                        }
                                        pthread_mutex_unlock(&app->sock_lock);
@@ -3524,7 +3529,7 @@ int ust_app_list_events(struct lttng_event **events)
                }
                ret = ustctl_release_handle(app->sock, handle);
                pthread_mutex_unlock(&app->sock_lock);
-               if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+               if (ret < 0 && ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
                        ERR("Error releasing app handle for app %d with ret %d", app->sock, ret);
                }
        }
@@ -3606,7 +3611,9 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                                free(tmp_event);
                                release_ret = ustctl_release_handle(app->sock, handle);
                                pthread_mutex_unlock(&app->sock_lock);
-                               if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+                               if (release_ret < 0 &&
+                                               release_ret != -LTTNG_UST_ERR_EXITING &&
+                                               release_ret != -EPIPE) {
                                        ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
                                }
                                goto rcu_error;
@@ -3631,7 +3638,9 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                                        ret = -ENOMEM;
                                        release_ret = ustctl_release_handle(app->sock, handle);
                                        pthread_mutex_unlock(&app->sock_lock);
-                                       if (release_ret != -LTTNG_UST_ERR_EXITING && release_ret != -EPIPE) {
+                                       if (release_ret &&
+                                                       release_ret != -LTTNG_UST_ERR_EXITING &&
+                                                       release_ret != -EPIPE) {
                                                ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret);
                                        }
                                        goto rcu_error;
@@ -3657,7 +3666,9 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                }
                ret = ustctl_release_handle(app->sock, handle);
                pthread_mutex_unlock(&app->sock_lock);
-               if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+               if (ret < 0 &&
+                               ret != -LTTNG_UST_ERR_EXITING &&
+                               ret != -EPIPE) {
                        ERR("Error releasing app handle for app %d with ret %d", app->sock, ret);
                }
        }
@@ -3869,7 +3880,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
 {
        int ret = 0;
        struct lttng_ht_iter iter, uiter;
-       struct lttng_ht_node_str *ua_chan_node, *ua_event_node;
+       struct lttng_ht_node_str *ua_chan_node;
        struct ust_app *app;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
@@ -3906,14 +3917,14 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
                }
                ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
 
-               lttng_ht_lookup(ua_chan->events, (void *)uevent->attr.name, &uiter);
-               ua_event_node = lttng_ht_iter_get_node_str(&uiter);
-               if (ua_event_node == NULL) {
+               ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
+                               uevent->filter, uevent->attr.loglevel,
+                               uevent->exclusion);
+               if (ua_event == NULL) {
                        DBG2("Event %s not found in channel %s for app pid %d."
                                        "Skipping", uevent->attr.name, uchan->name, app->pid);
                        continue;
                }
-               ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
 
                ret = disable_ust_app_event(ua_sess, ua_event, app);
                if (ret < 0) {
@@ -4418,7 +4429,6 @@ int ust_app_flush_app_session(struct ust_app *app,
                cds_lfht_for_each_entry(ua_sess->channels->ht, &iter.iter, ua_chan,
                                node.node) {
                        health_code_update();
-                       assert(ua_chan->is_sent);
                        ret = consumer_flush_channel(socket, ua_chan->key);
                        if (ret) {
                                ERR("Error flushing consumer channel");
@@ -4521,6 +4531,155 @@ int ust_app_flush_session(struct ltt_ust_session *usess)
        return ret;
 }
 
+static
+int ust_app_clear_quiescent_app_session(struct ust_app *app,
+               struct ust_app_session *ua_sess)
+{
+       int ret = 0;
+       struct lttng_ht_iter iter;
+       struct ust_app_channel *ua_chan;
+       struct consumer_socket *socket;
+
+       DBG("Clearing stream quiescent state for ust app pid %d", app->pid);
+
+       rcu_read_lock();
+
+       if (!app->compatible) {
+               goto end_not_compatible;
+       }
+
+       pthread_mutex_lock(&ua_sess->lock);
+
+       if (ua_sess->deleted) {
+               goto end_unlock;
+       }
+
+       health_code_update();
+
+       socket = consumer_find_socket_by_bitness(app->bits_per_long,
+                       ua_sess->consumer);
+       if (!socket) {
+               ERR("Failed to find consumer (%" PRIu32 ") socket",
+                               app->bits_per_long);
+               ret = -1;
+               goto end_unlock;
+       }
+
+       /* Clear quiescent state. */
+       switch (ua_sess->buffer_type) {
+       case LTTNG_BUFFER_PER_PID:
+               cds_lfht_for_each_entry(ua_sess->channels->ht, &iter.iter,
+                               ua_chan, node.node) {
+                       health_code_update();
+                       ret = consumer_clear_quiescent_channel(socket,
+                                       ua_chan->key);
+                       if (ret) {
+                               ERR("Error clearing quiescent state for consumer channel");
+                               ret = -1;
+                               continue;
+                       }
+               }
+               break;
+       case LTTNG_BUFFER_PER_UID:
+       default:
+               assert(0);
+               ret = -1;
+               break;
+       }
+
+       health_code_update();
+
+end_unlock:
+       pthread_mutex_unlock(&ua_sess->lock);
+
+end_not_compatible:
+       rcu_read_unlock();
+       health_code_update();
+       return ret;
+}
+
+/*
+ * Clear quiescent state in each stream for all applications for a
+ * specific UST session.
+ * Called with UST session lock held.
+ */
+static
+int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
+
+{
+       int ret = 0;
+
+       DBG("Clearing stream quiescent state for all ust apps");
+
+       rcu_read_lock();
+
+       switch (usess->buffer_type) {
+       case LTTNG_BUFFER_PER_UID:
+       {
+               struct lttng_ht_iter iter;
+               struct buffer_reg_uid *reg;
+
+               /*
+                * Clear quiescent for all per UID buffers associated to
+                * that session.
+                */
+               cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) {
+                       struct consumer_socket *socket;
+                       struct buffer_reg_channel *reg_chan;
+
+                       /* Get associated consumer socket.*/
+                       socket = consumer_find_socket_by_bitness(
+                                       reg->bits_per_long, usess->consumer);
+                       if (!socket) {
+                               /*
+                                * Ignore request if no consumer is found for
+                                * the session.
+                                */
+                               continue;
+                       }
+
+                       cds_lfht_for_each_entry(reg->registry->channels->ht,
+                                       &iter.iter, reg_chan, node.node) {
+                               /*
+                                * The following call will print error values so
+                                * the return code is of little importance
+                                * because whatever happens, we have to try them
+                                * all.
+                                */
+                               (void) consumer_clear_quiescent_channel(socket,
+                                               reg_chan->consumer_key);
+                       }
+               }
+               break;
+       }
+       case LTTNG_BUFFER_PER_PID:
+       {
+               struct ust_app_session *ua_sess;
+               struct lttng_ht_iter iter;
+               struct ust_app *app;
+
+               cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app,
+                               pid_n.node) {
+                       ua_sess = lookup_session_by_app(usess, app);
+                       if (ua_sess == NULL) {
+                               continue;
+                       }
+                       (void) ust_app_clear_quiescent_app_session(app,
+                                       ua_sess);
+               }
+               break;
+       }
+       default:
+               ret = -1;
+               assert(0);
+               break;
+       }
+
+       rcu_read_unlock();
+       health_code_update();
+       return ret;
+}
+
 /*
  * Destroy a specific UST session in apps.
  */
@@ -4579,6 +4738,14 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
 
        rcu_read_lock();
 
+       /*
+        * In a start-stop-start use-case, we need to clear the quiescent state
+        * of each channel set by the prior stop command, thus ensuring that a
+        * following stop or destroy is sure to grab a timestamp_end near those
+        * operations, even if the packet is empty.
+        */
+       (void) ust_app_clear_quiescent_session(usess);
+
        cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                ret = ust_app_start_trace(usess, app);
                if (ret < 0) {
@@ -5173,8 +5340,8 @@ error_rcu_unlock:
  * On success 0 is returned else a negative value.
  */
 static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
-               char *sig, size_t nr_fields, struct ustctl_field *fields, int loglevel,
-               char *model_emf_uri)
+               char *sig, size_t nr_fields, struct ustctl_field *fields,
+               int loglevel_value, char *model_emf_uri)
 {
        int ret, ret_code;
        uint32_t event_id = 0;
@@ -5229,9 +5396,9 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
         * three variables MUST NOT be read/write after this.
         */
        ret_code = ust_registry_create_event(registry, chan_reg_key,
-                       sobjd, cobjd, name, sig, nr_fields, fields, loglevel,
-                       model_emf_uri, ua_sess->buffer_type, &event_id,
-                       app);
+                       sobjd, cobjd, name, sig, nr_fields, fields,
+                       loglevel_value, model_emf_uri, ua_sess->buffer_type,
+                       &event_id, app);
 
        /*
         * The return value is returned to ustctl so in case of an error, the
@@ -5287,15 +5454,16 @@ int ust_app_recv_notify(int sock)
        switch (cmd) {
        case USTCTL_NOTIFY_CMD_EVENT:
        {
-               int sobjd, cobjd, loglevel;
+               int sobjd, cobjd, loglevel_value;
                char name[LTTNG_UST_SYM_NAME_LEN], *sig, *model_emf_uri;
                size_t nr_fields;
                struct ustctl_field *fields;
 
                DBG2("UST app ustctl register event received");
 
-               ret = ustctl_recv_register_event(sock, &sobjd, &cobjd, name, &loglevel,
-                               &sig, &nr_fields, &fields, &model_emf_uri);
+               ret = ustctl_recv_register_event(sock, &sobjd, &cobjd, name,
+                               &loglevel_value, &sig, &nr_fields, &fields,
+                               &model_emf_uri);
                if (ret < 0) {
                        if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
                                ERR("UST app recv event failed with ret %d", ret);
@@ -5312,7 +5480,7 @@ int ust_app_recv_notify(int sock)
                 * to the this function.
                 */
                ret = add_event_ust_registry(sock, sobjd, cobjd, name, sig, nr_fields,
-                               fields, loglevel, model_emf_uri);
+                               fields, loglevel_value, model_emf_uri);
                if (ret < 0) {
                        goto error;
                }
@@ -5460,7 +5628,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                uint64_t nb_packets_per_stream)
 {
        int ret = 0;
-       unsigned int snapshot_done = 0;
        struct lttng_ht_iter iter;
        struct ust_app *app;
        char pathname[PATH_MAX];
@@ -5512,7 +5679,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        if (ret < 0) {
                                goto error;
                        }
-                       snapshot_done = 1;
                }
                break;
        }
@@ -5565,7 +5731,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                        if (ret < 0) {
                                goto error;
                        }
-                       snapshot_done = 1;
                }
                break;
        }
@@ -5574,15 +5739,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
                break;
        }
 
-       if (!snapshot_done) {
-               /*
-                * If no snapshot was made and we are not in the error path, this means
-                * that there are no buffers thus no (prior) application to snapshot
-                * data from so we have simply NO data.
-                */
-               ret = -ENODATA;
-       }
-
 error:
        rcu_read_unlock();
        return ret;
This page took 0.02893 seconds and 4 git commands to generate.