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