clang-tidy: add Chrome-inspired checks
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-commands.cpp
CommitLineData
ab0ee2ca 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
ab0ee2ca 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
ab0ee2ca 5 *
ab0ee2ca
JG
6 */
7
c9e313bc 8#include "notification-thread-commands.hpp"
28ab034a
JG
9#include "notification-thread.hpp"
10
c9e313bc 11#include <common/error.hpp>
28ab034a
JG
12
13#include <lttng/lttng-error.h>
14#include <lttng/trigger/trigger.h>
15
ab0ee2ca 16#include <inttypes.h>
28ab034a
JG
17#include <stdint.h>
18#include <unistd.h>
ab0ee2ca 19
28ab034a 20static void init_notification_thread_command(struct notification_thread_command *cmd)
ab0ee2ca 21{
ab0ee2ca 22 CDS_INIT_LIST_HEAD(&cmd->cmd_list_node);
8ada111f 23 lttng_waiter_init(&cmd->reply_waiter);
ab0ee2ca
JG
24}
25
28ab034a
JG
26static int run_command_wait(struct notification_thread_handle *handle,
27 struct notification_thread_command *cmd)
ab0ee2ca
JG
28{
29 int ret;
30 uint64_t notification_counter = 1;
31
ab0ee2ca
JG
32 pthread_mutex_lock(&handle->cmd_queue.lock);
33 /* Add to queue. */
28ab034a 34 cds_list_add_tail(&cmd->cmd_list_node, &handle->cmd_queue.list);
ab0ee2ca 35 /* Wake-up thread. */
28ab034a
JG
36 ret = lttng_write(
37 handle->cmd_queue.event_fd, &notification_counter, sizeof(notification_counter));
58d3fed5 38 if (ret != sizeof(notification_counter)) {
ab0ee2ca
JG
39 PERROR("write to notification thread's queue event fd");
40 /*
41 * Remove the command from the list so the notification
42 * thread does not process it.
43 */
44 cds_list_del(&cmd->cmd_list_node);
45 goto error_unlock_queue;
46 }
47 pthread_mutex_unlock(&handle->cmd_queue.lock);
48
8ada111f 49 lttng_waiter_wait(&cmd->reply_waiter);
ab0ee2ca
JG
50 return 0;
51error_unlock_queue:
52 pthread_mutex_unlock(&handle->cmd_queue.lock);
53 return -1;
54}
55
28ab034a
JG
56static struct notification_thread_command *
57notification_thread_command_copy(const struct notification_thread_command *original_cmd)
0ab399e0
JG
58{
59 struct notification_thread_command *new_cmd;
60
64803277 61 new_cmd = zmalloc<notification_thread_command>();
0ab399e0
JG
62 if (!new_cmd) {
63 goto end;
64 }
65
66 *new_cmd = *original_cmd;
67 init_notification_thread_command(new_cmd);
68end:
69 return new_cmd;
70}
71
28ab034a
JG
72static int run_command_no_wait(struct notification_thread_handle *handle,
73 const struct notification_thread_command *in_cmd)
0ab399e0
JG
74{
75 int ret;
76 uint64_t notification_counter = 1;
28ab034a 77 struct notification_thread_command *new_cmd = notification_thread_command_copy(in_cmd);
0ab399e0
JG
78
79 if (!new_cmd) {
80 goto error;
81 }
82 new_cmd->is_async = true;
83
84 pthread_mutex_lock(&handle->cmd_queue.lock);
85 /* Add to queue. */
28ab034a 86 cds_list_add_tail(&new_cmd->cmd_list_node, &handle->cmd_queue.list);
0ab399e0 87 /* Wake-up thread. */
28ab034a
JG
88 ret = lttng_write(
89 handle->cmd_queue.event_fd, &notification_counter, sizeof(notification_counter));
0ab399e0
JG
90 if (ret != sizeof(notification_counter)) {
91 PERROR("write to notification thread's queue event fd");
92 /*
93 * Remove the command from the list so the notification
94 * thread does not process it.
95 */
96 cds_list_del(&new_cmd->cmd_list_node);
97 goto error_unlock_queue;
98 }
99 pthread_mutex_unlock(&handle->cmd_queue.lock);
100 return 0;
101error_unlock_queue:
102 free(new_cmd);
103 pthread_mutex_unlock(&handle->cmd_queue.lock);
104error:
105 return -1;
106}
107
28ab034a
JG
108enum lttng_error_code
109notification_thread_command_register_trigger(struct notification_thread_handle *handle,
110 struct lttng_trigger *trigger,
111 bool is_trigger_anonymous)
ab0ee2ca
JG
112{
113 int ret;
114 enum lttng_error_code ret_code;
0ab399e0 115 struct notification_thread_command cmd = {};
ab0ee2ca 116
a0377dfe 117 LTTNG_ASSERT(trigger);
ab0ee2ca
JG
118 init_notification_thread_command(&cmd);
119
120 cmd.type = NOTIFICATION_COMMAND_TYPE_REGISTER_TRIGGER;
242388e4 121 lttng_trigger_get(trigger);
ac16173e 122 cmd.parameters.register_trigger.trigger = trigger;
28ab034a 123 cmd.parameters.register_trigger.is_trigger_anonymous = is_trigger_anonymous;
ab0ee2ca
JG
124
125 ret = run_command_wait(handle, &cmd);
126 if (ret) {
127 ret_code = LTTNG_ERR_UNK;
128 goto end;
129 }
130 ret_code = cmd.reply_code;
131end:
132 return ret_code;
133}
134
28ab034a
JG
135enum lttng_error_code
136notification_thread_command_unregister_trigger(struct notification_thread_handle *handle,
137 const struct lttng_trigger *trigger)
ab0ee2ca
JG
138{
139 int ret;
140 enum lttng_error_code ret_code;
0ab399e0 141 struct notification_thread_command cmd = {};
ab0ee2ca
JG
142
143 init_notification_thread_command(&cmd);
144
145 cmd.type = NOTIFICATION_COMMAND_TYPE_UNREGISTER_TRIGGER;
ac16173e 146 cmd.parameters.unregister_trigger.trigger = trigger;
ab0ee2ca
JG
147
148 ret = run_command_wait(handle, &cmd);
149 if (ret) {
150 ret_code = LTTNG_ERR_UNK;
151 goto end;
152 }
153 ret_code = cmd.reply_code;
154end:
155 return ret_code;
156}
157
28ab034a
JG
158enum lttng_error_code
159notification_thread_command_add_session(struct notification_thread_handle *handle,
160 uint64_t session_id,
161 const char *session_name,
162 uid_t session_uid,
163 gid_t session_gid)
139a8d25
JG
164{
165 int ret;
166 enum lttng_error_code ret_code;
167 struct notification_thread_command cmd = {};
168
169 init_notification_thread_command(&cmd);
170
171 cmd.type = NOTIFICATION_COMMAND_TYPE_ADD_SESSION;
172 cmd.parameters.add_session.session_id = session_id;
173 cmd.parameters.add_session.session_name = session_name;
174 cmd.parameters.add_session.session_uid = session_uid;
175 cmd.parameters.add_session.session_gid = session_gid;
176
177 ret = run_command_wait(handle, &cmd);
178 if (ret) {
179 ret_code = LTTNG_ERR_UNK;
180 goto end;
181 }
182 ret_code = cmd.reply_code;
183end:
184 return ret_code;
185}
186
28ab034a
JG
187enum lttng_error_code
188notification_thread_command_remove_session(struct notification_thread_handle *handle,
189 uint64_t session_id)
139a8d25
JG
190{
191 int ret;
192 enum lttng_error_code ret_code;
193 struct notification_thread_command cmd = {};
194
195 init_notification_thread_command(&cmd);
196
197 cmd.type = NOTIFICATION_COMMAND_TYPE_REMOVE_SESSION;
198 cmd.parameters.remove_session.session_id = session_id;
199
200 ret = run_command_wait(handle, &cmd);
201 if (ret) {
202 ret_code = LTTNG_ERR_UNK;
203 goto end;
204 }
205 ret_code = cmd.reply_code;
206end:
207 return ret_code;
208}
209
28ab034a
JG
210enum lttng_error_code
211notification_thread_command_add_channel(struct notification_thread_handle *handle,
212 uint64_t session_id,
213 char *channel_name,
214 uint64_t key,
215 enum lttng_domain_type domain,
216 uint64_t capacity)
ab0ee2ca
JG
217{
218 int ret;
219 enum lttng_error_code ret_code;
0ab399e0 220 struct notification_thread_command cmd = {};
ab0ee2ca
JG
221
222 init_notification_thread_command(&cmd);
223
224 cmd.type = NOTIFICATION_COMMAND_TYPE_ADD_CHANNEL;
139a8d25 225 cmd.parameters.add_channel.session.id = session_id;
8abe313a
JG
226 cmd.parameters.add_channel.channel.name = channel_name;
227 cmd.parameters.add_channel.channel.key = key;
228 cmd.parameters.add_channel.channel.domain = domain;
229 cmd.parameters.add_channel.channel.capacity = capacity;
ab0ee2ca
JG
230
231 ret = run_command_wait(handle, &cmd);
232 if (ret) {
233 ret_code = LTTNG_ERR_UNK;
234 goto end;
235 }
236 ret_code = cmd.reply_code;
237end:
238 return ret_code;
239}
240
241enum lttng_error_code notification_thread_command_remove_channel(
28ab034a 242 struct notification_thread_handle *handle, uint64_t key, enum lttng_domain_type domain)
ab0ee2ca
JG
243{
244 int ret;
245 enum lttng_error_code ret_code;
0ab399e0 246 struct notification_thread_command cmd = {};
ab0ee2ca
JG
247
248 init_notification_thread_command(&cmd);
249
250 cmd.type = NOTIFICATION_COMMAND_TYPE_REMOVE_CHANNEL;
251 cmd.parameters.remove_channel.key = key;
252 cmd.parameters.remove_channel.domain = domain;
253
254 ret = run_command_wait(handle, &cmd);
255 if (ret) {
256 ret_code = LTTNG_ERR_UNK;
257 goto end;
258 }
259 ret_code = cmd.reply_code;
260end:
261 return ret_code;
262}
263
28ab034a
JG
264enum lttng_error_code
265notification_thread_command_session_rotation_ongoing(struct notification_thread_handle *handle,
266 uint64_t session_id,
267 uint64_t trace_archive_chunk_id)
731c1b12
JG
268{
269 int ret;
270 enum lttng_error_code ret_code;
0ab399e0 271 struct notification_thread_command cmd = {};
731c1b12
JG
272
273 init_notification_thread_command(&cmd);
274
275 cmd.type = NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING;
139a8d25 276 cmd.parameters.session_rotation.session_id = session_id;
28ab034a 277 cmd.parameters.session_rotation.trace_archive_chunk_id = trace_archive_chunk_id;
731c1b12
JG
278
279 ret = run_command_wait(handle, &cmd);
280 if (ret) {
281 ret_code = LTTNG_ERR_UNK;
282 goto end;
283 }
284 ret_code = cmd.reply_code;
285end:
286 return ret_code;
287}
288
289enum lttng_error_code notification_thread_command_session_rotation_completed(
28ab034a
JG
290 struct notification_thread_handle *handle,
291 uint64_t session_id,
292 uint64_t trace_archive_chunk_id,
293 struct lttng_trace_archive_location *location)
731c1b12
JG
294{
295 int ret;
296 enum lttng_error_code ret_code;
0ab399e0 297 struct notification_thread_command cmd = {};
731c1b12
JG
298
299 init_notification_thread_command(&cmd);
300
301 cmd.type = NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_COMPLETED;
139a8d25 302 cmd.parameters.session_rotation.session_id = session_id;
28ab034a 303 cmd.parameters.session_rotation.trace_archive_chunk_id = trace_archive_chunk_id;
731c1b12
JG
304 cmd.parameters.session_rotation.location = location;
305
306 ret = run_command_wait(handle, &cmd);
307 if (ret) {
308 ret_code = LTTNG_ERR_UNK;
309 goto end;
310 }
311 ret_code = cmd.reply_code;
312end:
313 return ret_code;
314}
315
28ab034a
JG
316enum lttng_error_code
317notification_thread_command_add_tracer_event_source(struct notification_thread_handle *handle,
318 int tracer_event_source_fd,
319 enum lttng_domain_type domain)
d02d7404
JR
320{
321 int ret;
322 enum lttng_error_code ret_code;
323 struct notification_thread_command cmd = {};
324
a0377dfe 325 LTTNG_ASSERT(tracer_event_source_fd >= 0);
d02d7404
JR
326
327 init_notification_thread_command(&cmd);
328
329 cmd.type = NOTIFICATION_COMMAND_TYPE_ADD_TRACER_EVENT_SOURCE;
28ab034a 330 cmd.parameters.tracer_event_source.tracer_event_source_fd = tracer_event_source_fd;
d02d7404
JR
331 cmd.parameters.tracer_event_source.domain = domain;
332
333 ret = run_command_wait(handle, &cmd);
334 if (ret) {
335 ret_code = LTTNG_ERR_UNK;
336 goto end;
337 }
338
339 ret_code = cmd.reply_code;
340end:
341 return ret_code;
342}
343
28ab034a
JG
344enum lttng_error_code
345notification_thread_command_remove_tracer_event_source(struct notification_thread_handle *handle,
346 int tracer_event_source_fd)
d02d7404
JR
347{
348 int ret;
349 enum lttng_error_code ret_code;
350 struct notification_thread_command cmd = {};
351
352 init_notification_thread_command(&cmd);
353
354 cmd.type = NOTIFICATION_COMMAND_TYPE_REMOVE_TRACER_EVENT_SOURCE;
28ab034a 355 cmd.parameters.tracer_event_source.tracer_event_source_fd = tracer_event_source_fd;
d02d7404
JR
356
357 ret = run_command_wait(handle, &cmd);
358 if (ret) {
359 ret_code = LTTNG_ERR_UNK;
360 goto end;
361 }
362
363 ret_code = cmd.reply_code;
364end:
365 return ret_code;
366}
367
fbc9f37d 368enum lttng_error_code notification_thread_command_list_triggers(
28ab034a 369 struct notification_thread_handle *handle, uid_t uid, struct lttng_triggers **triggers)
fbc9f37d
JR
370{
371 int ret;
372 enum lttng_error_code ret_code;
373 struct notification_thread_command cmd = {};
374
a0377dfe
FD
375 LTTNG_ASSERT(handle);
376 LTTNG_ASSERT(triggers);
fbc9f37d
JR
377
378 init_notification_thread_command(&cmd);
379
380 cmd.type = NOTIFICATION_COMMAND_TYPE_LIST_TRIGGERS;
381 cmd.parameters.list_triggers.uid = uid;
382
383 ret = run_command_wait(handle, &cmd);
384 if (ret) {
385 ret_code = LTTNG_ERR_UNK;
386 goto end;
387 }
388
389 ret_code = cmd.reply_code;
390 *triggers = cmd.reply.list_triggers.triggers;
391
392end:
393 return ret_code;
394}
395
28ab034a 396void notification_thread_command_quit(struct notification_thread_handle *handle)
ab0ee2ca
JG
397{
398 int ret;
0ab399e0 399 struct notification_thread_command cmd = {};
ab0ee2ca
JG
400
401 init_notification_thread_command(&cmd);
402
403 cmd.type = NOTIFICATION_COMMAND_TYPE_QUIT;
404 ret = run_command_wait(handle, &cmd);
a0377dfe 405 LTTNG_ASSERT(!ret && cmd.reply_code == LTTNG_OK);
ab0ee2ca 406}
f2b3ef9f
JG
407
408int notification_thread_client_communication_update(
28ab034a
JG
409 struct notification_thread_handle *handle,
410 notification_client_id id,
411 enum client_transmission_status transmission_status)
f2b3ef9f
JG
412{
413 struct notification_thread_command cmd = {};
414
415 init_notification_thread_command(&cmd);
416
417 cmd.type = NOTIFICATION_COMMAND_TYPE_CLIENT_COMMUNICATION_UPDATE;
418 cmd.parameters.client_communication_update.id = id;
419 cmd.parameters.client_communication_update.status = transmission_status;
420 return run_command_no_wait(handle, &cmd);
421}
b9a8d78f 422
28ab034a
JG
423enum lttng_error_code
424notification_thread_command_get_trigger(struct notification_thread_handle *handle,
425 const struct lttng_trigger *trigger,
426 struct lttng_trigger **real_trigger)
8790759c
FD
427{
428 int ret;
429 enum lttng_error_code ret_code;
430 struct notification_thread_command cmd = {};
431
432 init_notification_thread_command(&cmd);
433
434 cmd.type = NOTIFICATION_COMMAND_TYPE_GET_TRIGGER;
435 cmd.parameters.get_trigger.trigger = trigger;
436 ret = run_command_wait(handle, &cmd);
437 if (ret) {
438 ret_code = LTTNG_ERR_UNK;
439 goto end;
440 }
441
442 ret_code = cmd.reply_code;
443 *real_trigger = cmd.reply.get_trigger.trigger;
444
445end:
446 return ret_code;
447}
448
82b3cbf4
JR
449/*
450 * Takes ownership of the payload if present.
451 */
82b3cbf4 452struct lttng_event_notifier_notification *lttng_event_notifier_notification_create(
28ab034a 453 uint64_t tracer_token, enum lttng_domain_type domain, char *payload, size_t payload_size)
b9a8d78f 454{
cd9adb8b 455 struct lttng_event_notifier_notification *notification = nullptr;
b9a8d78f 456
a0377dfe
FD
457 LTTNG_ASSERT(domain != LTTNG_DOMAIN_NONE);
458 LTTNG_ASSERT((payload && payload_size) || (!payload && !payload_size));
b9a8d78f 459
64803277 460 notification = zmalloc<lttng_event_notifier_notification>();
cd9adb8b 461 if (notification == nullptr) {
bd0514a5 462 ERR("Error allocating notification");
b9a8d78f
FD
463 goto end;
464 }
465
466 notification->tracer_token = tracer_token;
467 notification->type = domain;
82b3cbf4
JR
468 notification->capture_buffer = payload;
469 notification->capture_buf_size = payload_size;
b9a8d78f
FD
470
471end:
472 return notification;
473}
474
b9a8d78f 475void lttng_event_notifier_notification_destroy(
28ab034a 476 struct lttng_event_notifier_notification *notification)
b9a8d78f
FD
477{
478 if (!notification) {
479 return;
480 }
481
82b3cbf4 482 free(notification->capture_buffer);
b9a8d78f
FD
483 free(notification);
484}
This page took 0.076426 seconds and 4 git commands to generate.