X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fnotification-thread-internal.hpp;fp=src%2Fbin%2Flttng-sessiond%2Fnotification-thread-internal.hpp;h=497484ba04534586263072b4f629c62bb2b124b8;hp=0000000000000000000000000000000000000000;hb=c9e313bc594f40a86eed237dce222c0fc99c957f;hpb=4878de5c7deb512bbdac4fdfc498907efa06fb7c diff --git a/src/bin/lttng-sessiond/notification-thread-internal.hpp b/src/bin/lttng-sessiond/notification-thread-internal.hpp new file mode 100644 index 000000000..497484ba0 --- /dev/null +++ b/src/bin/lttng-sessiond/notification-thread-internal.hpp @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2017 Jérémie Galarneau + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#ifndef NOTIFICATION_THREAD_INTERNAL_H +#define NOTIFICATION_THREAD_INTERNAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "notification-thread.hpp" + +struct lttng_evaluation; +struct notification_thread_handle; + +struct channel_key { + uint64_t key; + enum lttng_domain_type domain; +}; + +struct session_info { + struct lttng_ref ref; + char *name; + uid_t uid; + gid_t gid; + /* + * Hashtable containing back-refs (weak) to all channels in this session. + * The hashtable's key is a hash of (struct channel_key) and + * the value is of type (struct channel_info *). + */ + struct cds_lfht *channel_infos_ht; + struct lttng_session_trigger_list *trigger_list; + /* Node in the notification thread state's sessions_ht. */ + struct cds_lfht_node sessions_ht_node; + /* + * Weak reference to the thread state's sessions_ht. Used for removal on + * destruction. + */ + struct cds_lfht *sessions_ht; + uint64_t consumed_data_size; + struct { + /* Whether a rotation is ongoing for this session. */ + bool ongoing; + /* Identifier of the currently ongoing rotation. */ + uint64_t id; + } rotation; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; +}; + +struct channel_info { + struct channel_key key; + char *name; + uint64_t capacity; + /* + * A channel info holds a reference (lttng_ref) on session_info. + * session_info, in return, holds a weak reference to the channel. + */ + struct session_info *session_info; + /* Node in the notification thread state's channels_ht. */ + struct cds_lfht_node channels_ht_node; + /* Node in the session_info's channels_ht. */ + struct cds_lfht_node session_info_channels_ht_node; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; +}; + +/* + * Facilities to carry the different notifications type in the action + * processing code path. + */ +struct lttng_event_notifier_notification { + uint64_t tracer_token; + enum lttng_domain_type type; + size_t capture_buf_size; + char *capture_buffer; +}; + +struct notification_client_list_element { + struct notification_client *client; + struct cds_list_head node; +}; + +/* + * Thread safety of notification_client and notification_client_list. + * + * The notification thread (main thread) and the action executor + * interact through client lists. Hence, when the action executor + * thread looks-up the list of clients subscribed to a given + * condition, it will acquire a reference to the list and lock it + * while attempting to communicate with the various clients. + * + * It is not necessary to reference-count clients as they are guaranteed + * to be 'alive' if they are present in a list and that list is locked. Indeed, + * removing references to the client from those subscription lists is part of + * the work performed on destruction of a client. + * + * No provision for other access scenarios are taken into account; + * this is the bare minimum to make these accesses safe and the + * notification thread's state is _not_ "thread-safe" in any general + * sense. + */ +struct notification_client_list { + pthread_mutex_t lock; + struct urcu_ref ref; + struct lttng_condition *condition; + /* List of triggers that have an identical condition than `condition`. */ + struct cds_list_head triggers_list; + struct cds_list_head clients_list; + /* Weak reference to container. */ + struct cds_lfht *notification_trigger_clients_ht; + struct cds_lfht_node notification_trigger_clients_ht_node; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; +}; + +struct notification_client { + /* + * Nests within the notification_client_list lock. + * + * Protects the outbound communication and the active flag which + * is used by both the notification and action executor threads. + * + * The remaining fields of the object can be used without any + * synchronization as they are either immutable (id, creds, version) or + * only accessed by the notification thread. + */ + pthread_mutex_t lock; + notification_client_id id; + int socket; + /* Client protocol version. */ + uint8_t major, minor; + uid_t uid; + gid_t gid; + bool is_sessiond; + /* + * Indicates if the credentials and versions of the client have been + * checked. + */ + bool validated; + /* + * Conditions to which the client's notification channel is subscribed. + * List of struct lttng_condition_list_node. The condition member is + * owned by the client. + */ + struct cds_list_head condition_list; + struct cds_lfht_node client_socket_ht_node; + struct cds_lfht_node client_id_ht_node; + struct { + /* + * If a client's communication is inactive, it means that a + * fatal error has occurred (could be either a protocol error or + * the socket API returned a fatal error). No further + * communication should be attempted; the client is queued for + * clean-up. + */ + bool active; + struct { + /* + * During the reception of a message, the reception + * buffers' "size" is set to contain the current + * message's complete payload. + */ + struct lttng_payload payload; + /* Bytes left to receive for the current message. */ + size_t bytes_to_receive; + /* FDs left to receive for the current message. */ + int fds_to_receive; + /* Type of the message being received. */ + enum lttng_notification_channel_message_type msg_type; + /* + * Indicates whether or not credentials are expected + * from the client. + */ + bool expect_creds; + /* + * Indicates whether or not credentials were received + * from the client. + */ + bool creds_received; + /* Only used during credentials reception. */ + lttng_sock_cred creds; + } inbound; + struct { + /* + * Indicates whether or not a notification addressed to + * this client was dropped because a command reply was + * already buffered. + * + * A notification is dropped whenever the buffer is not + * empty. + */ + bool dropped_notification; + /* + * Indicates whether or not a command reply is already + * buffered. In this case, it means that the client is + * not consuming command replies before emitting a new + * one. This could be caused by a protocol error or a + * misbehaving/malicious client. + */ + bool queued_command_reply; + struct lttng_payload payload; + } outbound; + } communication; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; +}; + +enum client_transmission_status { + CLIENT_TRANSMISSION_STATUS_COMPLETE, + CLIENT_TRANSMISSION_STATUS_QUEUED, + /* Communication failure. */ + CLIENT_TRANSMISSION_STATUS_FAIL, + /* Fatal error. */ + CLIENT_TRANSMISSION_STATUS_ERROR, +}; + +bool notification_client_list_get(struct notification_client_list *list); + +void notification_client_list_put(struct notification_client_list *list); + +/* Only returns a non-zero value if a fatal error occurred. */ +typedef int (*report_client_transmission_result_cb)( + struct notification_client *client, + enum client_transmission_status status, + void *user_data); + +int notification_client_list_send_evaluation( + struct notification_client_list *list, + const struct lttng_trigger *trigger, + const struct lttng_evaluation *evaluation, + const struct lttng_credentials *source_object_creds, + report_client_transmission_result_cb client_report, + void *user_data); + +int notification_thread_client_communication_update( + struct notification_thread_handle *handle, + notification_client_id id, + enum client_transmission_status transmission_status); + +/* + * Takes ownership of the payload if present. + */ +struct lttng_event_notifier_notification *lttng_event_notifier_notification_create( + uint64_t tracer_token, + enum lttng_domain_type domain, + char *payload, + size_t payload_size); + +void lttng_event_notifier_notification_destroy( + struct lttng_event_notifier_notification *event_notifier_notification); + +#endif /* NOTIFICATION_THREAD_INTERNAL_H */