Fix: sessiond: work-around mismatching variant type tag field and selector names
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.cpp
index 3ca4279a9404da1545b98f4e9acabe156d2e6eef..8addb5edacabb5bd9ed2397ab81f276cf5b078fb 100644 (file)
@@ -287,7 +287,7 @@ static void close_notify_sock_rcu(struct rcu_head *head)
 {
        int ret;
        struct ust_app_notify_sock_obj *obj =
-               caa_container_of(head, struct ust_app_notify_sock_obj, head);
+               lttng::utils::container_of(head, &ust_app_notify_sock_obj::head);
 
        /* Must have a valid fd here. */
        LTTNG_ASSERT(obj->fd >= 0);
@@ -380,8 +380,8 @@ void delete_ust_app_event(int sock, struct ust_app_event *ua_event,
 static
 void free_ust_app_event_notifier_rule_rcu(struct rcu_head *head)
 {
-       struct ust_app_event_notifier_rule *obj = caa_container_of(
-                       head, struct ust_app_event_notifier_rule, rcu_head);
+       struct ust_app_event_notifier_rule *obj = lttng::utils::container_of(
+                       head, &ust_app_event_notifier_rule::rcu_head);
 
        free(obj);
 }
@@ -480,7 +480,7 @@ static
 void delete_ust_app_channel_rcu(struct rcu_head *head)
 {
        struct ust_app_channel *ua_chan =
-               caa_container_of(head, struct ust_app_channel, rcu_head);
+               lttng::utils::container_of(head, &ust_app_channel::rcu_head);
 
        lttng_ht_destroy(ua_chan->ctx);
        lttng_ht_destroy(ua_chan->events);
@@ -902,7 +902,7 @@ static
 void delete_ust_app_session_rcu(struct rcu_head *head)
 {
        struct ust_app_session *ua_sess =
-               caa_container_of(head, struct ust_app_session, rcu_head);
+               lttng::utils::container_of(head, &ust_app_session::rcu_head);
 
        lttng_ht_destroy(ua_sess->channels);
        free(ua_sess);
@@ -1126,9 +1126,9 @@ static
 void delete_ust_app_rcu(struct rcu_head *head)
 {
        struct lttng_ht_node_ulong *node =
-               caa_container_of(head, struct lttng_ht_node_ulong, head);
+               lttng::utils::container_of(head, &lttng_ht_node_ulong::head);
        struct ust_app *app =
-               caa_container_of(node, struct ust_app, pid_n);
+               lttng::utils::container_of(node, &ust_app::pid_n);
 
        DBG3("Call RCU deleting app PID %d", app->pid);
        delete_ust_app(app);
@@ -1470,7 +1470,7 @@ struct ust_app *ust_app_find_by_sock(int sock)
                goto error;
        }
 
-       return caa_container_of(node, struct ust_app, sock_n);
+       return lttng::utils::container_of(node, &ust_app::sock_n);
 
 error:
        return NULL;
@@ -1495,7 +1495,7 @@ static struct ust_app *find_app_by_notify_sock(int sock)
                goto error;
        }
 
-       return caa_container_of(node, struct ust_app, notify_sock_n);
+       return lttng::utils::container_of(node, &ust_app::notify_sock_n);
 
 error:
        return NULL;
@@ -1535,7 +1535,7 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
                goto end;
        }
 
-       event = caa_container_of(node, struct ust_app_event, node);
+       event = lttng::utils::container_of(node, &ust_app_event::node);
 
 end:
        return event;
@@ -1565,8 +1565,8 @@ static struct ust_app_event_notifier_rule *find_ust_app_event_notifier_rule(
                goto end;
        }
 
-       event_notifier_rule = caa_container_of(
-                       node, struct ust_app_event_notifier_rule, node);
+       event_notifier_rule = lttng::utils::container_of(
+                       node, &ust_app_event_notifier_rule::node);
 end:
        return event_notifier_rule;
 }
@@ -2506,7 +2506,7 @@ static struct ust_app_session *lookup_session_by_app(
                goto error;
        }
 
-       return caa_container_of(node, struct ust_app_session, node);
+       return lttng::utils::container_of(node, &ust_app_session::node);
 
 error:
        return NULL;
@@ -2833,7 +2833,7 @@ struct ust_app_ctx *find_ust_app_context(struct lttng_ht *ht,
                goto end;
        }
 
-       app_ctx = caa_container_of(node, struct ust_app_ctx, node);
+       app_ctx = lttng::utils::container_of(node, &ust_app_ctx::node);
 
 end:
        return app_ctx;
@@ -2965,7 +2965,7 @@ static int enable_ust_app_channel(struct ust_app_session *ua_sess,
                goto error;
        }
 
-       ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+       ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
        ret = enable_ust_channel(app, ua_sess, ua_chan);
        if (ret < 0) {
@@ -3461,11 +3461,7 @@ static int create_channel_per_uid(struct ust_app *app,
 
        /* Notify the notification subsystem of the channel's creation. */
        notification_ret = notification_thread_command_add_channel(
-                       the_notification_thread_handle, session->name,
-                       lttng_credentials_get_uid(
-                                       &ua_sess->effective_credentials),
-                       lttng_credentials_get_gid(
-                                       &ua_sess->effective_credentials),
+                       the_notification_thread_handle, session->id,
                        ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST,
                        ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf);
        if (notification_ret != LTTNG_OK) {
@@ -3563,11 +3559,7 @@ static int create_channel_per_pid(struct ust_app *app,
        }
 
        cmd_ret = notification_thread_command_add_channel(
-                       the_notification_thread_handle, session->name,
-                       lttng_credentials_get_uid(
-                                       &ua_sess->effective_credentials),
-                       lttng_credentials_get_gid(
-                                       &ua_sess->effective_credentials),
+                       the_notification_thread_handle, session->id,
                        ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST,
                        ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf);
        if (cmd_ret != LTTNG_OK) {
@@ -3680,7 +3672,7 @@ static int ust_app_channel_allocate(struct ust_app_session *ua_sess,
        lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &iter);
        ua_chan_node = lttng_ht_iter_get_node_str(&iter);
        if (ua_chan_node != NULL) {
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                goto end;
        }
 
@@ -3945,7 +3937,7 @@ struct ust_app *ust_app_find_by_pid(pid_t pid)
 
        DBG2("Found UST app by pid %d", pid);
 
-       app = caa_container_of(node, struct ust_app, pid_n);
+       app = lttng::utils::container_of(node, &ust_app::pid_n);
 
 error:
        return app;
@@ -4270,7 +4262,7 @@ void ust_app_unregister(int sock)
        node = lttng_ht_iter_get_node_ulong(&ust_app_sock_iter);
        LTTNG_ASSERT(node);
 
-       lta = caa_container_of(node, struct ust_app, sock_n);
+       lta = lttng::utils::container_of(node, &ust_app::sock_n);
        DBG("PID %d unregistering with sock %d", lta->pid, sock);
 
        /*
@@ -4763,7 +4755,7 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess,
                /* If the session if found for the app, the channel must be there */
                LTTNG_ASSERT(ua_chan_node);
 
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                /* The channel must not be already disabled */
                LTTNG_ASSERT(ua_chan->enabled == 1);
 
@@ -4866,7 +4858,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
                                        "Skipping", uchan->name, usess->id, app->pid);
                        continue;
                }
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
                                uevent->filter, uevent->attr.loglevel,
@@ -5025,7 +5017,7 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
                        continue;
                }
 
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                /* Get event node */
                ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name,
@@ -5098,7 +5090,7 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
                /* If the channel is not found, there is a code flow error */
                LTTNG_ASSERT(ua_chan_node);
 
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                ret = create_ust_app_event(ua_chan, uevent, app);
                pthread_mutex_unlock(&ua_sess->lock);
@@ -5642,7 +5634,7 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
                /* Session is being or is deleted. */
                goto end;
        }
-       ua_sess = caa_container_of(node, struct ust_app_session, node);
+       ua_sess = lttng::utils::container_of(node, &ust_app_session::node);
 
        health_code_update();
        destroy_app_session(app, ua_sess);
@@ -6326,7 +6318,7 @@ static struct ust_app_session *find_session_by_objd(struct ust_app *app,
                goto error;
        }
 
-       ua_sess = caa_container_of(node, struct ust_app_session, ust_objd_node);
+       ua_sess = lttng::utils::container_of(node, &ust_app_session::ust_objd_node);
 
 error:
        return ua_sess;
@@ -6354,7 +6346,7 @@ static struct ust_app_channel *find_channel_by_objd(struct ust_app *app,
                goto error;
        }
 
-       ua_chan = caa_container_of(node, struct ust_app_channel, ust_objd_node);
+       ua_chan = lttng::utils::container_of(node, &ust_app_channel::ust_objd_node);
 
 error:
        return ua_chan;
@@ -6434,32 +6426,49 @@ static int handle_app_register_channel_notification(int sock,
         * that all apps provide the same typing for the context fields as a
         * sanity check.
         */
-       lst::type::cuptr context_fields = lttng::make_unique<lst::structure_type>(0,
-                       lsu::create_trace_fields_from_ust_ctl_fields(*locked_registry_session,
-                                       ust_ctl_context_fields.get(), context_field_count));
+       try {
+               auto app_context_fields = lsu::create_trace_fields_from_ust_ctl_fields(
+                               *locked_registry_session, ust_ctl_context_fields.get(),
+                               context_field_count,
+                               lst::field_location::root::EVENT_RECORD_COMMON_CONTEXT,
+                               lsu::ctl_field_quirks::UNDERSCORE_PREFIXED_VARIANT_TAG_MAPPINGS);
+
+               if (!ust_reg_chan.is_registered()) {
+                       lst::type::cuptr event_context = app_context_fields.size() ?
+                                       lttng::make_unique<lst::structure_type>(
+                                                       0, std::move(app_context_fields)) :
+                                       nullptr;
+
+                       ust_reg_chan.set_event_context(std::move(event_context));
+               } else {
+                       /*
+                        * Validate that the context fields match between
+                        * registry and newcoming application.
+                        */
+                       bool context_fields_match;
+                       const auto *previous_event_context = ust_reg_chan.get_event_context();
 
-       if (!ust_reg_chan.is_registered()) {
-               ust_reg_chan.set_context(std::move(context_fields));
-       } else {
-               /*
-                * Validate that the context fields match between
-                * registry and newcoming application.
-                */
-               if (ust_reg_chan.get_context() != *context_fields) {
-                       ERR("Registering application channel due to context field mismatch: pid = %d, sock = %d",
-                               app->pid, app->sock);
-                       ret_code = -EINVAL;
-                       goto reply;
-               }
-       }
+                       if (!previous_event_context) {
+                               context_fields_match = app_context_fields.size() == 0;
+                       } else {
+                               const lst::structure_type app_event_context_struct(
+                                               0, std::move(app_context_fields));
 
-       /* Append to metadata */
-       if (!ust_reg_chan._metadata_dumped) {
-               /*ret_code = ust_metadata_channel_statedump(registry, ust_reg_chan);*/
-               if (ret_code) {
-                       ERR("Error appending channel metadata (errno = %d)", ret_code);
-                       goto reply;
+                               context_fields_match = *previous_event_context ==
+                                               app_event_context_struct;
+                       }
+
+                       if (!context_fields_match) {
+                               ERR("Registering application channel due to context field mismatch: pid = %d, sock = %d",
+                                               app->pid, app->sock);
+                               ret_code = -EINVAL;
+                               goto reply;
+                       }
                }
+       } catch (std::exception& ex) {
+               ERR("Failed to handle application context: %s", ex.what());
+               ret_code = -EINVAL;
+               goto reply;
        }
 
 reply:
@@ -6468,7 +6477,7 @@ reply:
                        ret_code);
 
        ret = lttng_ust_ctl_reply_register_channel(sock, chan_id,
-                       ust_reg_chan.header_type == lst::stream_class::header_type::COMPACT ?
+                       ust_reg_chan.header_type_ == lst::stream_class::header_type::COMPACT ?
                                        LTTNG_UST_CTL_CHANNEL_HEADER_COMPACT :
                                              LTTNG_UST_CTL_CHANNEL_HEADER_LARGE,
                        ret_code);
@@ -6556,12 +6565,16 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, const char *na
                                channel.add_event(sobjd, cobjd, name, signature.get(),
                                                lsu::create_trace_fields_from_ust_ctl_fields(
                                                                *locked_registry, fields.get(),
-                                                               nr_fields),
+                                                               nr_fields,
+                                                               lst::field_location::root::
+                                                                               EVENT_RECORD_PAYLOAD,
+                                                               lsu::ctl_field_quirks::
+                                                                               UNDERSCORE_PREFIXED_VARIANT_TAG_MAPPINGS),
                                                loglevel_value,
                                                model_emf_uri.get() ?
                                                                nonstd::optional<std::string>(
                                                                                model_emf_uri.get()) :
-                                                                     nonstd::nullopt,
+                                                               nonstd::nullopt,
                                                ua_sess->buffer_type, *app, event_id);
                                ret_code = 0;
                        } catch (const std::exception& ex) {
@@ -6613,16 +6626,16 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, const char *na
  *
  * On success 0 is returned else a negative value.
  */
-static int add_enum_ust_registry(int sock, int sobjd, char *name,
-               struct lttng_ust_ctl_enum_entry *entries, size_t nr_entries)
+static int add_enum_ust_registry(int sock, int sobjd, const char *name,
+               struct lttng_ust_ctl_enum_entry *raw_entries, size_t nr_entries)
 {
-       int ret = 0, ret_code;
+       int ret = 0;
        struct ust_app *app;
        struct ust_app_session *ua_sess;
-       lsu::registry_session *registry;
        uint64_t enum_id = -1ULL;
-
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock_guard;
+       auto entries = lttng::make_unique_wrapper<struct lttng_ust_ctl_enum_entry, lttng::free>(
+                       raw_entries);
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
@@ -6630,9 +6643,7 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
                /* Return an error since this is not an error */
                DBG("Application socket %d is being torn down. Aborting enum registration",
                                sock);
-               free(entries);
-               ret = -1;
-               goto error_rcu_unlock;
+               return -1;
        }
 
        /* Lookup session by UST object descriptor. */
@@ -6640,34 +6651,37 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
        if (!ua_sess) {
                /* Return an error since this is not an error */
                DBG("Application session is being torn down (session not found). Aborting enum registration.");
-               free(entries);
-               goto error_rcu_unlock;
+               return 0;
        }
 
-       registry = get_session_registry(ua_sess);
-       if (!registry) {
+       auto locked_registry = get_locked_session_registry(ua_sess);
+       if (!locked_registry) {
                DBG("Application session is being torn down (registry not found). Aborting enum registration.");
-               free(entries);
-               goto error_rcu_unlock;
+               return 0;
        }
 
-       pthread_mutex_lock(&registry->_lock);
-
        /*
         * From this point on, the callee acquires the ownership of
         * entries. The variable entries MUST NOT be read/written after
         * call.
         */
-       ret_code = ust_registry_create_or_find_enum(registry, sobjd, name,
-                       entries, nr_entries, &enum_id);
-       entries = NULL;
+       int application_reply_code;
+       try {
+               locked_registry->create_or_find_enum(
+                               sobjd, name, entries.release(), nr_entries, &enum_id);
+               application_reply_code = 0;
+       } catch (const std::exception& ex) {
+               ERR("%s: %s", fmt::format("Failed to create or find enumeration provided by application: app = {}, enumeration name = {}",
+                               *app, name).c_str(), ex.what());
+               application_reply_code = -1;
+       }
 
        /*
         * The return value is returned to ustctl so in case of an error, the
         * application can be notified. In case of an error, it's important not to
         * return a negative error or else the application will get closed.
         */
-       ret = lttng_ust_ctl_reply_register_enum(sock, enum_id, ret_code);
+       ret = lttng_ust_ctl_reply_register_enum(sock, enum_id, application_reply_code);
        if (ret < 0) {
                if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                        DBG3("UST app reply enum failed. Application died: pid = %d, sock = %d",
@@ -6683,16 +6697,11 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
                 * No need to wipe the create enum since the application socket will
                 * get close on error hence cleaning up everything by itself.
                 */
-               goto error;
+               return ret;
        }
 
        DBG3("UST registry enum %s added successfully or already found", name);
-
-error:
-       pthread_mutex_unlock(&registry->_lock);
-error_rcu_unlock:
-       rcu_read_unlock();
-       return ret;
+       return 0;
 }
 
 /*
@@ -7257,7 +7266,7 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                /* If the session is found for the app, the channel must be there */
                LTTNG_ASSERT(ua_chan_node);
 
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                if (overwrite) {
                        uint64_t _lost;
This page took 0.030263 seconds and 4 git commands to generate.