2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
8 #ifndef NOTIFICATION_THREAD_INTERNAL_H
9 #define NOTIFICATION_THREAD_INTERNAL_H
11 #include <common/compat/socket.h>
12 #include <common/credentials.h>
13 #include <common/payload.h>
14 #include <lttng/notification/channel-internal.h>
15 #include <lttng/ref-internal.h>
18 #include <urcu/rculfhash.h>
20 #include <urcu/call-rcu.h>
21 #include "notification-thread.h"
23 struct lttng_evaluation
;
24 struct notification_thread_handle
;
28 enum lttng_domain_type domain
;
37 * Hashtable containing back-refs (weak) to all channels in this session.
38 * The hashtable's key is a hash of (struct channel_key) and
39 * the value is of type (struct channel_info *).
41 struct cds_lfht
*channel_infos_ht
;
42 struct lttng_session_trigger_list
*trigger_list
;
43 /* Node in the notification thread state's sessions_ht. */
44 struct cds_lfht_node sessions_ht_node
;
46 * Weak reference to the thread state's sessions_ht. Used for removal on
49 struct cds_lfht
*sessions_ht
;
50 uint64_t consumed_data_size
;
52 /* Whether a rotation is ongoing for this session. */
54 /* Identifier of the currently ongoing rotation. */
57 /* call_rcu delayed reclaim. */
58 struct rcu_head rcu_node
;
62 struct channel_key key
;
66 * A channel info holds a reference (lttng_ref) on session_info.
67 * session_info, in return, holds a weak reference to the channel.
69 struct session_info
*session_info
;
70 /* Node in the notification thread state's channels_ht. */
71 struct cds_lfht_node channels_ht_node
;
72 /* Node in the session_info's channels_ht. */
73 struct cds_lfht_node session_info_channels_ht_node
;
74 /* call_rcu delayed reclaim. */
75 struct rcu_head rcu_node
;
79 * Facilities to carry the different notifications type in the action
80 * processing code path.
82 struct lttng_event_notifier_notification
{
83 uint64_t tracer_token
;
84 enum lttng_domain_type type
;
85 size_t capture_buf_size
;
89 struct notification_client_list_element
{
90 struct notification_client
*client
;
91 struct cds_list_head node
;
95 * Thread safety of notification_client and notification_client_list.
97 * The notification thread (main thread) and the action executor
98 * interact through client lists. Hence, when the action executor
99 * thread looks-up the list of clients subscribed to a given
100 * condition, it will acquire a reference to the list and lock it
101 * while attempting to communicate with the various clients.
103 * It is not necessary to reference-count clients as they are guaranteed
104 * to be 'alive' if they are present in a list and that list is locked. Indeed,
105 * removing references to the client from those subscription lists is part of
106 * the work performed on destruction of a client.
108 * No provision for other access scenarios are taken into account;
109 * this is the bare minimum to make these accesses safe and the
110 * notification thread's state is _not_ "thread-safe" in any general
113 struct notification_client_list
{
114 pthread_mutex_t lock
;
116 struct lttng_condition
*condition
;
117 struct cds_list_head triggers_list
;
118 struct cds_list_head clients_list
;
119 /* Weak reference to container. */
120 struct cds_lfht
*notification_trigger_clients_ht
;
121 struct cds_lfht_node notification_trigger_clients_ht_node
;
122 /* call_rcu delayed reclaim. */
123 struct rcu_head rcu_node
;
126 struct notification_client
{
128 * Nests within the notification_client_list lock.
130 * Protects the outbound communication and the active flag which
131 * is used by both the notification and action executor threads.
133 * The remaining fields of the object can be used without any
134 * synchronization as they are either immutable (id, creds, version) or
135 * only accessed by the notification thread.
137 pthread_mutex_t lock
;
138 notification_client_id id
;
140 /* Client protocol version. */
141 uint8_t major
, minor
;
145 * Indicates if the credentials and versions of the client have been
150 * Conditions to which the client's notification channel is subscribed.
151 * List of struct lttng_condition_list_node. The condition member is
152 * owned by the client.
154 struct cds_list_head condition_list
;
155 struct cds_lfht_node client_socket_ht_node
;
156 struct cds_lfht_node client_id_ht_node
;
159 * If a client's communication is inactive, it means that a
160 * fatal error has occurred (could be either a protocol error or
161 * the socket API returned a fatal error). No further
162 * communication should be attempted; the client is queued for
168 * During the reception of a message, the reception
169 * buffers' "size" is set to contain the current
170 * message's complete payload.
172 struct lttng_payload payload
;
173 /* Bytes left to receive for the current message. */
174 size_t bytes_to_receive
;
175 /* FDs left to receive for the current message. */
177 /* Type of the message being received. */
178 enum lttng_notification_channel_message_type msg_type
;
180 * Indicates whether or not credentials are expected
185 * Indicates whether or not credentials were received
189 /* Only used during credentials reception. */
190 lttng_sock_cred creds
;
194 * Indicates whether or not a notification addressed to
195 * this client was dropped because a command reply was
198 * A notification is dropped whenever the buffer is not
201 bool dropped_notification
;
203 * Indicates whether or not a command reply is already
204 * buffered. In this case, it means that the client is
205 * not consuming command replies before emitting a new
206 * one. This could be caused by a protocol error or a
207 * misbehaving/malicious client.
209 bool queued_command_reply
;
210 struct lttng_payload payload
;
213 /* call_rcu delayed reclaim. */
214 struct rcu_head rcu_node
;
217 enum client_transmission_status
{
218 CLIENT_TRANSMISSION_STATUS_COMPLETE
,
219 CLIENT_TRANSMISSION_STATUS_QUEUED
,
220 /* Communication failure. */
221 CLIENT_TRANSMISSION_STATUS_FAIL
,
223 CLIENT_TRANSMISSION_STATUS_ERROR
,
227 bool notification_client_list_get(struct notification_client_list
*list
);
230 void notification_client_list_put(struct notification_client_list
*list
);
232 /* Only returns a non-zero value if a fatal error occurred. */
233 typedef int (*report_client_transmission_result_cb
)(
234 struct notification_client
*client
,
235 enum client_transmission_status status
,
239 int notification_client_list_send_evaluation(
240 struct notification_client_list
*list
,
241 const struct lttng_condition
*condition
,
242 const struct lttng_evaluation
*evaluation
,
243 const struct lttng_credentials
*trigger_creds
,
244 const struct lttng_credentials
*source_object_creds
,
245 report_client_transmission_result_cb client_report
,
249 int notification_thread_client_communication_update(
250 struct notification_thread_handle
*handle
,
251 notification_client_id id
,
252 enum client_transmission_status transmission_status
);
255 * Takes ownership of the payload if present.
258 struct lttng_event_notifier_notification
*lttng_event_notifier_notification_create(
259 uint64_t tracer_token
,
260 enum lttng_domain_type domain
,
262 size_t payload_size
);
265 void lttng_event_notifier_notification_destroy(
266 struct lttng_event_notifier_notification
*event_notifier_notification
);
268 #endif /* NOTIFICATION_THREAD_INTERNAL_H */