SoW-2019-0002: Dynamic Snapshot
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-internal.h
1 /*
2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #ifndef NOTIFICATION_THREAD_INTERNAL_H
9 #define NOTIFICATION_THREAD_INTERNAL_H
10
11 #include <common/credentials.h>
12 #include <lttng/notification/channel-internal.h>
13 #include <lttng/ref-internal.h>
14 #include <stdbool.h>
15 #include <unistd.h>
16 #include <urcu/rculfhash.h>
17 #include <urcu/ref.h>
18 #include <urcu/call-rcu.h>
19 #include "notification-thread.h"
20
21 struct lttng_evaluation;
22 struct notification_thread_handle;
23
24 struct channel_key {
25 uint64_t key;
26 enum lttng_domain_type domain;
27 };
28
29 struct session_info {
30 struct lttng_ref ref;
31 char *name;
32 uid_t uid;
33 gid_t gid;
34 /*
35 * Hashtable containing back-refs (weak) to all channels in this session.
36 * The hashtable's key is a hash of (struct channel_key) and
37 * the value is of type (struct channel_info *).
38 */
39 struct cds_lfht *channel_infos_ht;
40 struct lttng_session_trigger_list *trigger_list;
41 /* Node in the notification thread state's sessions_ht. */
42 struct cds_lfht_node sessions_ht_node;
43 /*
44 * Weak reference to the thread state's sessions_ht. Used for removal on
45 * destruction.
46 */
47 struct cds_lfht *sessions_ht;
48 uint64_t consumed_data_size;
49 struct {
50 /* Whether a rotation is ongoing for this session. */
51 bool ongoing;
52 /* Identifier of the currently ongoing rotation. */
53 uint64_t id;
54 } rotation;
55 /* call_rcu delayed reclaim. */
56 struct rcu_head rcu_node;
57 };
58
59 struct channel_info {
60 struct channel_key key;
61 char *name;
62 uint64_t capacity;
63 /*
64 * A channel info holds a reference (lttng_ref) on session_info.
65 * session_info, in return, holds a weak reference to the channel.
66 */
67 struct session_info *session_info;
68 /* Node in the notification thread state's channels_ht. */
69 struct cds_lfht_node channels_ht_node;
70 /* Node in the session_info's channels_ht. */
71 struct cds_lfht_node session_info_channels_ht_node;
72 /* call_rcu delayed reclaim. */
73 struct rcu_head rcu_node;
74 };
75
76 struct notification_client_list_element {
77 struct notification_client *client;
78 struct cds_list_head node;
79 };
80
81 /*
82 * Thread safety of notification_client and notification_client_list.
83 *
84 * The notification thread (main thread) and the action executor
85 * interact through client lists. Hence, when the action executor
86 * thread looks-up the list of clients subscribed to a given
87 * condition, it will acquire a reference to the list and lock it
88 * while attempting to communicate with the various clients.
89 *
90 * It is not necessary to reference-count clients as they are guaranteed
91 * to be 'alive' if they are present in a list and that list is locked. Indeed,
92 * removing references to the client from those subscription lists is part of
93 * the work performed on destruction of a client.
94 *
95 * No provision for other access scenarios are taken into account;
96 * this is the bare minimum to make these accesses safe and the
97 * notification thread's state is _not_ "thread-safe" in any general
98 * sense.
99 */
100 struct notification_client_list {
101 pthread_mutex_t lock;
102 struct urcu_ref ref;
103 const struct lttng_trigger *trigger;
104 struct cds_list_head list;
105 /* Weak reference to container. */
106 struct cds_lfht *notification_trigger_clients_ht;
107 struct cds_lfht_node notification_trigger_clients_ht_node;
108 /* call_rcu delayed reclaim. */
109 struct rcu_head rcu_node;
110 };
111
112 struct notification_client {
113 /* Nests within the notification_client_list lock. */
114 pthread_mutex_t lock;
115 notification_client_id id;
116 int socket;
117 /* Client protocol version. */
118 uint8_t major, minor;
119 uid_t uid;
120 gid_t gid;
121 /*
122 * Indicates if the credentials and versions of the client have been
123 * checked.
124 */
125 bool validated;
126 /*
127 * Conditions to which the client's notification channel is subscribed.
128 * List of struct lttng_condition_list_node. The condition member is
129 * owned by the client.
130 */
131 struct cds_list_head condition_list;
132 struct cds_lfht_node client_socket_ht_node;
133 struct cds_lfht_node client_id_ht_node;
134 struct {
135 /*
136 * If a client's communication is inactive, it means that a
137 * fatal error has occurred (could be either a protocol error or
138 * the socket API returned a fatal error). No further
139 * communication should be attempted; the client is queued for
140 * clean-up.
141 */
142 bool active;
143 struct {
144 /*
145 * During the reception of a message, the reception
146 * buffers' "size" is set to contain the current
147 * message's complete payload.
148 */
149 struct lttng_dynamic_buffer buffer;
150 /* Bytes left to receive for the current message. */
151 size_t bytes_to_receive;
152 /* Type of the message being received. */
153 enum lttng_notification_channel_message_type msg_type;
154 /*
155 * Indicates whether or not credentials are expected
156 * from the client.
157 */
158 bool expect_creds;
159 /*
160 * Indicates whether or not credentials were received
161 * from the client.
162 */
163 bool creds_received;
164 /* Only used during credentials reception. */
165 lttng_sock_cred creds;
166 } inbound;
167 struct {
168 /*
169 * Indicates whether or not a notification addressed to
170 * this client was dropped because a command reply was
171 * already buffered.
172 *
173 * A notification is dropped whenever the buffer is not
174 * empty.
175 */
176 bool dropped_notification;
177 /*
178 * Indicates whether or not a command reply is already
179 * buffered. In this case, it means that the client is
180 * not consuming command replies before emitting a new
181 * one. This could be caused by a protocol error or a
182 * misbehaving/malicious client.
183 */
184 bool queued_command_reply;
185 struct lttng_dynamic_buffer buffer;
186 } outbound;
187 } communication;
188 /* call_rcu delayed reclaim. */
189 struct rcu_head rcu_node;
190 };
191
192 enum client_transmission_status {
193 CLIENT_TRANSMISSION_STATUS_COMPLETE,
194 CLIENT_TRANSMISSION_STATUS_QUEUED,
195 /* Communication failure. */
196 CLIENT_TRANSMISSION_STATUS_FAIL,
197 /* Fatal error. */
198 CLIENT_TRANSMISSION_STATUS_ERROR,
199 };
200
201 LTTNG_HIDDEN
202 bool notification_client_list_get(struct notification_client_list *list);
203
204 LTTNG_HIDDEN
205 void notification_client_list_put(struct notification_client_list *list);
206
207 typedef int (*report_client_transmission_result_cb)(
208 struct notification_client *client,
209 enum client_transmission_status status,
210 void *user_data);
211
212 LTTNG_HIDDEN
213 int notification_client_list_send_evaluation(
214 struct notification_client_list *list,
215 const struct lttng_condition *condition,
216 const struct lttng_evaluation *evaluation,
217 const struct lttng_credentials *trigger_creds,
218 const struct lttng_credentials *source_object_creds,
219 report_client_transmission_result_cb client_report,
220 void *user_data);
221
222 LTTNG_HIDDEN
223 int notification_thread_client_communication_update(
224 struct notification_thread_handle *handle,
225 notification_client_id id,
226 enum client_transmission_status transmission_status);
227
228 #endif /* NOTIFICATION_THREAD_INTERNAL_H */
This page took 0.03412 seconds and 5 git commands to generate.