Fix: sessiond: notification: use after free of trigger object
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-events.c
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 #include "lttng/action/action.h"
9 #include "lttng/trigger/trigger-internal.h"
10 #define _LGPL_SOURCE
11 #include <urcu.h>
12 #include <urcu/rculfhash.h>
13
14 #include <common/defaults.h>
15 #include <common/error.h>
16 #include <common/futex.h>
17 #include <common/unix.h>
18 #include <common/dynamic-buffer.h>
19 #include <common/hashtable/utils.h>
20 #include <common/sessiond-comm/sessiond-comm.h>
21 #include <common/macros.h>
22 #include <lttng/condition/condition.h>
23 #include <lttng/action/action-internal.h>
24 #include <lttng/action/group-internal.h>
25 #include <lttng/domain-internal.h>
26 #include <lttng/notification/notification-internal.h>
27 #include <lttng/condition/condition-internal.h>
28 #include <lttng/condition/buffer-usage-internal.h>
29 #include <lttng/condition/session-consumed-size-internal.h>
30 #include <lttng/condition/session-rotation-internal.h>
31 #include <lttng/condition/on-event-internal.h>
32 #include <lttng/domain-internal.h>
33 #include <lttng/notification/channel-internal.h>
34 #include <lttng/trigger/trigger-internal.h>
35 #include <lttng/event-rule/event-rule-internal.h>
36
37 #include <time.h>
38 #include <unistd.h>
39 #include <assert.h>
40 #include <inttypes.h>
41 #include <fcntl.h>
42
43 #include "condition-internal.h"
44 #include "event-notifier-error-accounting.h"
45 #include "notification-thread.h"
46 #include "notification-thread-events.h"
47 #include "notification-thread-commands.h"
48 #include "lttng-sessiond.h"
49 #include "kernel.h"
50
51 #define CLIENT_POLL_MASK_IN (LPOLLIN | LPOLLERR | LPOLLHUP | LPOLLRDHUP)
52 #define CLIENT_POLL_MASK_IN_OUT (CLIENT_POLL_MASK_IN | LPOLLOUT)
53
54 /* The tracers currently limit the capture size to PIPE_BUF (4kb on linux). */
55 #define MAX_CAPTURE_SIZE (PIPE_BUF)
56
57 enum lttng_object_type {
58 LTTNG_OBJECT_TYPE_UNKNOWN,
59 LTTNG_OBJECT_TYPE_NONE,
60 LTTNG_OBJECT_TYPE_CHANNEL,
61 LTTNG_OBJECT_TYPE_SESSION,
62 };
63
64 struct lttng_trigger_list_element {
65 /* No ownership of the trigger object is assumed. */
66 struct lttng_trigger *trigger;
67 struct cds_list_head node;
68 };
69
70 struct lttng_channel_trigger_list {
71 struct channel_key channel_key;
72 /* List of struct lttng_trigger_list_element. */
73 struct cds_list_head list;
74 /* Node in the channel_triggers_ht */
75 struct cds_lfht_node channel_triggers_ht_node;
76 /* call_rcu delayed reclaim. */
77 struct rcu_head rcu_node;
78 };
79
80 /*
81 * List of triggers applying to a given session.
82 *
83 * See:
84 * - lttng_session_trigger_list_create()
85 * - lttng_session_trigger_list_build()
86 * - lttng_session_trigger_list_destroy()
87 * - lttng_session_trigger_list_add()
88 */
89 struct lttng_session_trigger_list {
90 /*
91 * Not owned by this; points to the session_info structure's
92 * session name.
93 */
94 const char *session_name;
95 /* List of struct lttng_trigger_list_element. */
96 struct cds_list_head list;
97 /* Node in the session_triggers_ht */
98 struct cds_lfht_node session_triggers_ht_node;
99 /*
100 * Weak reference to the notification system's session triggers
101 * hashtable.
102 *
103 * The session trigger list structure structure is owned by
104 * the session's session_info.
105 *
106 * The session_info is kept alive the the channel_infos holding a
107 * reference to it (reference counting). When those channels are
108 * destroyed (at runtime or on teardown), the reference they hold
109 * to the session_info are released. On destruction of session_info,
110 * session_info_destroy() will remove the list of triggers applying
111 * to this session from the notification system's state.
112 *
113 * This implies that the session_triggers_ht must be destroyed
114 * after the channels.
115 */
116 struct cds_lfht *session_triggers_ht;
117 /* Used for delayed RCU reclaim. */
118 struct rcu_head rcu_node;
119 };
120
121 struct lttng_trigger_ht_element {
122 struct lttng_trigger *trigger;
123 struct cds_lfht_node node;
124 struct cds_lfht_node node_by_name_uid;
125 struct cds_list_head client_list_trigger_node;
126 /* call_rcu delayed reclaim. */
127 struct rcu_head rcu_node;
128 };
129
130 struct lttng_condition_list_element {
131 struct lttng_condition *condition;
132 struct cds_list_head node;
133 };
134
135 struct channel_state_sample {
136 struct channel_key key;
137 struct cds_lfht_node channel_state_ht_node;
138 uint64_t highest_usage;
139 uint64_t lowest_usage;
140 uint64_t channel_total_consumed;
141 /* call_rcu delayed reclaim. */
142 struct rcu_head rcu_node;
143 };
144
145 static unsigned long hash_channel_key(struct channel_key *key);
146 static int evaluate_buffer_condition(const struct lttng_condition *condition,
147 struct lttng_evaluation **evaluation,
148 const struct notification_thread_state *state,
149 const struct channel_state_sample *previous_sample,
150 const struct channel_state_sample *latest_sample,
151 uint64_t previous_session_consumed_total,
152 uint64_t latest_session_consumed_total,
153 struct channel_info *channel_info);
154 static
155 int send_evaluation_to_clients(const struct lttng_trigger *trigger,
156 const struct lttng_evaluation *evaluation,
157 struct notification_client_list *client_list,
158 struct notification_thread_state *state,
159 uid_t channel_uid, gid_t channel_gid);
160
161
162 /* session_info API */
163 static
164 void session_info_destroy(void *_data);
165 static
166 void session_info_get(struct session_info *session_info);
167 static
168 void session_info_put(struct session_info *session_info);
169 static
170 struct session_info *session_info_create(const char *name,
171 uid_t uid, gid_t gid,
172 struct lttng_session_trigger_list *trigger_list,
173 struct cds_lfht *sessions_ht);
174 static
175 void session_info_add_channel(struct session_info *session_info,
176 struct channel_info *channel_info);
177 static
178 void session_info_remove_channel(struct session_info *session_info,
179 struct channel_info *channel_info);
180
181 /* lttng_session_trigger_list API */
182 static
183 struct lttng_session_trigger_list *lttng_session_trigger_list_create(
184 const char *session_name,
185 struct cds_lfht *session_triggers_ht);
186 static
187 struct lttng_session_trigger_list *lttng_session_trigger_list_build(
188 const struct notification_thread_state *state,
189 const char *session_name);
190 static
191 void lttng_session_trigger_list_destroy(
192 struct lttng_session_trigger_list *list);
193 static
194 int lttng_session_trigger_list_add(struct lttng_session_trigger_list *list,
195 struct lttng_trigger *trigger);
196
197 static
198 int client_handle_transmission_status(
199 struct notification_client *client,
200 enum client_transmission_status transmission_status,
201 struct notification_thread_state *state);
202
203 static
204 int handle_one_event_notifier_notification(
205 struct notification_thread_state *state,
206 int pipe, enum lttng_domain_type domain);
207
208 static
209 void free_lttng_trigger_ht_element_rcu(struct rcu_head *node);
210
211 static
212 int match_client_socket(struct cds_lfht_node *node, const void *key)
213 {
214 /* This double-cast is intended to supress pointer-to-cast warning. */
215 const int socket = (int) (intptr_t) key;
216 const struct notification_client *client = caa_container_of(node,
217 struct notification_client, client_socket_ht_node);
218
219 return client->socket == socket;
220 }
221
222 static
223 int match_client_id(struct cds_lfht_node *node, const void *key)
224 {
225 /* This double-cast is intended to supress pointer-to-cast warning. */
226 const notification_client_id id = *((notification_client_id *) key);
227 const struct notification_client *client = caa_container_of(
228 node, struct notification_client, client_id_ht_node);
229
230 return client->id == id;
231 }
232
233 static
234 int match_channel_trigger_list(struct cds_lfht_node *node, const void *key)
235 {
236 struct channel_key *channel_key = (struct channel_key *) key;
237 struct lttng_channel_trigger_list *trigger_list;
238
239 trigger_list = caa_container_of(node, struct lttng_channel_trigger_list,
240 channel_triggers_ht_node);
241
242 return !!((channel_key->key == trigger_list->channel_key.key) &&
243 (channel_key->domain == trigger_list->channel_key.domain));
244 }
245
246 static
247 int match_session_trigger_list(struct cds_lfht_node *node, const void *key)
248 {
249 const char *session_name = (const char *) key;
250 struct lttng_session_trigger_list *trigger_list;
251
252 trigger_list = caa_container_of(node, struct lttng_session_trigger_list,
253 session_triggers_ht_node);
254
255 return !!(strcmp(trigger_list->session_name, session_name) == 0);
256 }
257
258 static
259 int match_channel_state_sample(struct cds_lfht_node *node, const void *key)
260 {
261 struct channel_key *channel_key = (struct channel_key *) key;
262 struct channel_state_sample *sample;
263
264 sample = caa_container_of(node, struct channel_state_sample,
265 channel_state_ht_node);
266
267 return !!((channel_key->key == sample->key.key) &&
268 (channel_key->domain == sample->key.domain));
269 }
270
271 static
272 int match_channel_info(struct cds_lfht_node *node, const void *key)
273 {
274 struct channel_key *channel_key = (struct channel_key *) key;
275 struct channel_info *channel_info;
276
277 channel_info = caa_container_of(node, struct channel_info,
278 channels_ht_node);
279
280 return !!((channel_key->key == channel_info->key.key) &&
281 (channel_key->domain == channel_info->key.domain));
282 }
283
284 static
285 int match_trigger(struct cds_lfht_node *node, const void *key)
286 {
287 struct lttng_trigger *trigger_key = (struct lttng_trigger *) key;
288 struct lttng_trigger_ht_element *trigger_ht_element;
289
290 trigger_ht_element = caa_container_of(node, struct lttng_trigger_ht_element,
291 node);
292
293 return !!lttng_trigger_is_equal(trigger_key, trigger_ht_element->trigger);
294 }
295
296 static
297 int match_trigger_token(struct cds_lfht_node *node, const void *key)
298 {
299 const uint64_t *_key = key;
300 struct notification_trigger_tokens_ht_element *element;
301
302 element = caa_container_of(node,
303 struct notification_trigger_tokens_ht_element, node);
304 return *_key == element->token;
305 }
306
307 static
308 int match_client_list_condition(struct cds_lfht_node *node, const void *key)
309 {
310 struct lttng_condition *condition_key = (struct lttng_condition *) key;
311 struct notification_client_list *client_list;
312 const struct lttng_condition *condition;
313
314 assert(condition_key);
315
316 client_list = caa_container_of(node, struct notification_client_list,
317 notification_trigger_clients_ht_node);
318 condition = client_list->condition;
319
320 return !!lttng_condition_is_equal(condition_key, condition);
321 }
322
323 static
324 int match_session(struct cds_lfht_node *node, const void *key)
325 {
326 const char *name = key;
327 struct session_info *session_info = caa_container_of(
328 node, struct session_info, sessions_ht_node);
329
330 return !strcmp(session_info->name, name);
331 }
332
333 static
334 const char *notification_command_type_str(
335 enum notification_thread_command_type type)
336 {
337 switch (type) {
338 case NOTIFICATION_COMMAND_TYPE_REGISTER_TRIGGER:
339 return "REGISTER_TRIGGER";
340 case NOTIFICATION_COMMAND_TYPE_UNREGISTER_TRIGGER:
341 return "UNREGISTER_TRIGGER";
342 case NOTIFICATION_COMMAND_TYPE_ADD_CHANNEL:
343 return "ADD_CHANNEL";
344 case NOTIFICATION_COMMAND_TYPE_REMOVE_CHANNEL:
345 return "REMOVE_CHANNEL";
346 case NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING:
347 return "SESSION_ROTATION_ONGOING";
348 case NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_COMPLETED:
349 return "SESSION_ROTATION_COMPLETED";
350 case NOTIFICATION_COMMAND_TYPE_ADD_TRACER_EVENT_SOURCE:
351 return "ADD_TRACER_EVENT_SOURCE";
352 case NOTIFICATION_COMMAND_TYPE_REMOVE_TRACER_EVENT_SOURCE:
353 return "REMOVE_TRACER_EVENT_SOURCE";
354 case NOTIFICATION_COMMAND_TYPE_LIST_TRIGGERS:
355 return "LIST_TRIGGERS";
356 case NOTIFICATION_COMMAND_TYPE_QUIT:
357 return "QUIT";
358 case NOTIFICATION_COMMAND_TYPE_CLIENT_COMMUNICATION_UPDATE:
359 return "CLIENT_COMMUNICATION_UPDATE";
360 default:
361 abort();
362 }
363 }
364
365 /*
366 * Match trigger based on name and credentials only.
367 * Name duplication is NOT allowed for the same uid.
368 */
369 static
370 int match_trigger_by_name_uid(struct cds_lfht_node *node,
371 const void *key)
372 {
373 bool match = false;
374 const char *name;
375 const char *key_name;
376 enum lttng_trigger_status status;
377 const struct lttng_credentials *key_creds;
378 const struct lttng_credentials *node_creds;
379 const struct lttng_trigger *trigger_key =
380 (const struct lttng_trigger *) key;
381 const struct lttng_trigger_ht_element *trigger_ht_element =
382 caa_container_of(node,
383 struct lttng_trigger_ht_element,
384 node_by_name_uid);
385
386 status = lttng_trigger_get_name(trigger_ht_element->trigger, &name);
387 assert(status == LTTNG_TRIGGER_STATUS_OK);
388
389 status = lttng_trigger_get_name(trigger_key, &key_name);
390 assert(status == LTTNG_TRIGGER_STATUS_OK);
391
392 /* Compare the names. */
393 if (strcmp(name, key_name) != 0) {
394 goto end;
395 }
396
397 /* Compare the owners' UIDs. */
398 key_creds = lttng_trigger_get_credentials(trigger_key);
399 node_creds = lttng_trigger_get_credentials(trigger_ht_element->trigger);
400
401 match = lttng_credentials_is_equal_uid(key_creds, node_creds);
402
403 end:
404 return match;
405 }
406
407 /*
408 * Hash trigger based on name and credentials only.
409 */
410 static
411 unsigned long hash_trigger_by_name_uid(const struct lttng_trigger *trigger)
412 {
413 unsigned long hash = 0;
414 const struct lttng_credentials *trigger_creds;
415 const char *trigger_name;
416 enum lttng_trigger_status status;
417
418 status = lttng_trigger_get_name(trigger, &trigger_name);
419 if (status == LTTNG_TRIGGER_STATUS_OK) {
420 hash = hash_key_str(trigger_name, lttng_ht_seed);
421 }
422
423 trigger_creds = lttng_trigger_get_credentials(trigger);
424 hash ^= hash_key_ulong((void *) (unsigned long) LTTNG_OPTIONAL_GET(trigger_creds->uid),
425 lttng_ht_seed);
426
427 return hash;
428 }
429
430 static
431 unsigned long hash_channel_key(struct channel_key *key)
432 {
433 unsigned long key_hash = hash_key_u64(&key->key, lttng_ht_seed);
434 unsigned long domain_hash = hash_key_ulong(
435 (void *) (unsigned long) key->domain, lttng_ht_seed);
436
437 return key_hash ^ domain_hash;
438 }
439
440 static
441 unsigned long hash_client_socket(int socket)
442 {
443 return hash_key_ulong((void *) (unsigned long) socket, lttng_ht_seed);
444 }
445
446 static
447 unsigned long hash_client_id(notification_client_id id)
448 {
449 return hash_key_u64(&id, lttng_ht_seed);
450 }
451
452 /*
453 * Get the type of object to which a given condition applies. Bindings let
454 * the notification system evaluate a trigger's condition when a given
455 * object's state is updated.
456 *
457 * For instance, a condition bound to a channel will be evaluated everytime
458 * the channel's state is changed by a channel monitoring sample.
459 */
460 static
461 enum lttng_object_type get_condition_binding_object(
462 const struct lttng_condition *condition)
463 {
464 switch (lttng_condition_get_type(condition)) {
465 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
466 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
467 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
468 return LTTNG_OBJECT_TYPE_CHANNEL;
469 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
470 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
471 return LTTNG_OBJECT_TYPE_SESSION;
472 case LTTNG_CONDITION_TYPE_ON_EVENT:
473 return LTTNG_OBJECT_TYPE_NONE;
474 default:
475 return LTTNG_OBJECT_TYPE_UNKNOWN;
476 }
477 }
478
479 static
480 void free_channel_info_rcu(struct rcu_head *node)
481 {
482 free(caa_container_of(node, struct channel_info, rcu_node));
483 }
484
485 static
486 void channel_info_destroy(struct channel_info *channel_info)
487 {
488 if (!channel_info) {
489 return;
490 }
491
492 if (channel_info->session_info) {
493 session_info_remove_channel(channel_info->session_info,
494 channel_info);
495 session_info_put(channel_info->session_info);
496 }
497 if (channel_info->name) {
498 free(channel_info->name);
499 }
500 call_rcu(&channel_info->rcu_node, free_channel_info_rcu);
501 }
502
503 static
504 void free_session_info_rcu(struct rcu_head *node)
505 {
506 free(caa_container_of(node, struct session_info, rcu_node));
507 }
508
509 /* Don't call directly, use the ref-counting mechanism. */
510 static
511 void session_info_destroy(void *_data)
512 {
513 struct session_info *session_info = _data;
514 int ret;
515
516 assert(session_info);
517 if (session_info->channel_infos_ht) {
518 ret = cds_lfht_destroy(session_info->channel_infos_ht, NULL);
519 if (ret) {
520 ERR("[notification-thread] Failed to destroy channel information hash table");
521 }
522 }
523 lttng_session_trigger_list_destroy(session_info->trigger_list);
524
525 rcu_read_lock();
526 cds_lfht_del(session_info->sessions_ht,
527 &session_info->sessions_ht_node);
528 rcu_read_unlock();
529 free(session_info->name);
530 call_rcu(&session_info->rcu_node, free_session_info_rcu);
531 }
532
533 static
534 void session_info_get(struct session_info *session_info)
535 {
536 if (!session_info) {
537 return;
538 }
539 lttng_ref_get(&session_info->ref);
540 }
541
542 static
543 void session_info_put(struct session_info *session_info)
544 {
545 if (!session_info) {
546 return;
547 }
548 lttng_ref_put(&session_info->ref);
549 }
550
551 static
552 struct session_info *session_info_create(const char *name, uid_t uid, gid_t gid,
553 struct lttng_session_trigger_list *trigger_list,
554 struct cds_lfht *sessions_ht)
555 {
556 struct session_info *session_info;
557
558 assert(name);
559
560 session_info = zmalloc(sizeof(*session_info));
561 if (!session_info) {
562 goto end;
563 }
564 lttng_ref_init(&session_info->ref, session_info_destroy);
565
566 session_info->channel_infos_ht = cds_lfht_new(DEFAULT_HT_SIZE,
567 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
568 if (!session_info->channel_infos_ht) {
569 goto error;
570 }
571
572 cds_lfht_node_init(&session_info->sessions_ht_node);
573 session_info->name = strdup(name);
574 if (!session_info->name) {
575 goto error;
576 }
577 session_info->uid = uid;
578 session_info->gid = gid;
579 session_info->trigger_list = trigger_list;
580 session_info->sessions_ht = sessions_ht;
581 end:
582 return session_info;
583 error:
584 session_info_put(session_info);
585 return NULL;
586 }
587
588 static
589 void session_info_add_channel(struct session_info *session_info,
590 struct channel_info *channel_info)
591 {
592 rcu_read_lock();
593 cds_lfht_add(session_info->channel_infos_ht,
594 hash_channel_key(&channel_info->key),
595 &channel_info->session_info_channels_ht_node);
596 rcu_read_unlock();
597 }
598
599 static
600 void session_info_remove_channel(struct session_info *session_info,
601 struct channel_info *channel_info)
602 {
603 rcu_read_lock();
604 cds_lfht_del(session_info->channel_infos_ht,
605 &channel_info->session_info_channels_ht_node);
606 rcu_read_unlock();
607 }
608
609 static
610 struct channel_info *channel_info_create(const char *channel_name,
611 struct channel_key *channel_key, uint64_t channel_capacity,
612 struct session_info *session_info)
613 {
614 struct channel_info *channel_info = zmalloc(sizeof(*channel_info));
615
616 if (!channel_info) {
617 goto end;
618 }
619
620 cds_lfht_node_init(&channel_info->channels_ht_node);
621 cds_lfht_node_init(&channel_info->session_info_channels_ht_node);
622 memcpy(&channel_info->key, channel_key, sizeof(*channel_key));
623 channel_info->capacity = channel_capacity;
624
625 channel_info->name = strdup(channel_name);
626 if (!channel_info->name) {
627 goto error;
628 }
629
630 /*
631 * Set the references between session and channel infos:
632 * - channel_info holds a strong reference to session_info
633 * - session_info holds a weak reference to channel_info
634 */
635 session_info_get(session_info);
636 session_info_add_channel(session_info, channel_info);
637 channel_info->session_info = session_info;
638 end:
639 return channel_info;
640 error:
641 channel_info_destroy(channel_info);
642 return NULL;
643 }
644
645 LTTNG_HIDDEN
646 bool notification_client_list_get(struct notification_client_list *list)
647 {
648 return urcu_ref_get_unless_zero(&list->ref);
649 }
650
651 static
652 void free_notification_client_list_rcu(struct rcu_head *node)
653 {
654 free(caa_container_of(node, struct notification_client_list,
655 rcu_node));
656 }
657
658 static
659 void notification_client_list_release(struct urcu_ref *list_ref)
660 {
661 struct notification_client_list *list =
662 container_of(list_ref, typeof(*list), ref);
663 struct notification_client_list_element *client_list_element, *tmp;
664
665 lttng_condition_put(list->condition);
666
667 if (list->notification_trigger_clients_ht) {
668 rcu_read_lock();
669
670 cds_lfht_del(list->notification_trigger_clients_ht,
671 &list->notification_trigger_clients_ht_node);
672 rcu_read_unlock();
673 list->notification_trigger_clients_ht = NULL;
674 }
675 cds_list_for_each_entry_safe(client_list_element, tmp,
676 &list->clients_list, node) {
677 free(client_list_element);
678 }
679
680 assert(cds_list_empty(&list->triggers_list));
681
682 pthread_mutex_destroy(&list->lock);
683 call_rcu(&list->rcu_node, free_notification_client_list_rcu);
684 }
685
686 static
687 bool condition_applies_to_client(const struct lttng_condition *condition,
688 struct notification_client *client)
689 {
690 bool applies = false;
691 struct lttng_condition_list_element *condition_list_element;
692
693 cds_list_for_each_entry(condition_list_element, &client->condition_list,
694 node) {
695 applies = lttng_condition_is_equal(
696 condition_list_element->condition,
697 condition);
698 if (applies) {
699 break;
700 }
701 }
702
703 return applies;
704 }
705
706 static
707 struct notification_client_list *notification_client_list_create(
708 struct notification_thread_state *state,
709 const struct lttng_condition *condition)
710 {
711 struct notification_client *client;
712 struct cds_lfht_iter iter;
713 struct notification_client_list *client_list;
714
715 client_list = zmalloc(sizeof(*client_list));
716 if (!client_list) {
717 PERROR("Failed to allocate notification client list");
718 goto end;
719 }
720
721 pthread_mutex_init(&client_list->lock, NULL);
722 /*
723 * The trigger that owns the condition has the first reference to this
724 * client list.
725 */
726 urcu_ref_init(&client_list->ref);
727 cds_lfht_node_init(&client_list->notification_trigger_clients_ht_node);
728 CDS_INIT_LIST_HEAD(&client_list->clients_list);
729 CDS_INIT_LIST_HEAD(&client_list->triggers_list);
730
731 /*
732 * Create a copy of the condition so that it's independent of any
733 * trigger. The client list may outlive the trigger object (which owns
734 * the condition) that is used to create it.
735 */
736 client_list->condition = lttng_condition_copy(condition);
737
738 /* Build a list of clients to which this new condition applies. */
739 cds_lfht_for_each_entry (state->client_socket_ht, &iter, client,
740 client_socket_ht_node) {
741 struct notification_client_list_element *client_list_element;
742
743 if (!condition_applies_to_client(condition, client)) {
744 continue;
745 }
746
747 client_list_element = zmalloc(sizeof(*client_list_element));
748 if (!client_list_element) {
749 goto error_put_client_list;
750 }
751
752 CDS_INIT_LIST_HEAD(&client_list_element->node);
753 client_list_element->client = client;
754 cds_list_add(&client_list_element->node, &client_list->clients_list);
755 }
756
757 client_list->notification_trigger_clients_ht =
758 state->notification_trigger_clients_ht;
759
760 rcu_read_lock();
761 /*
762 * Add the client list to the global list of client list.
763 */
764 cds_lfht_add_unique(state->notification_trigger_clients_ht,
765 lttng_condition_hash(client_list->condition),
766 match_client_list_condition,
767 client_list->condition,
768 &client_list->notification_trigger_clients_ht_node);
769 rcu_read_unlock();
770 goto end;
771
772 error_put_client_list:
773 notification_client_list_put(client_list);
774 client_list = NULL;
775
776 end:
777 return client_list;
778 }
779
780 void notification_client_list_put(struct notification_client_list *list)
781 {
782 if (!list) {
783 return;
784 }
785 return urcu_ref_put(&list->ref, notification_client_list_release);
786 }
787
788 /* Provides a reference to the returned list. */
789 static
790 struct notification_client_list *get_client_list_from_condition(
791 struct notification_thread_state *state,
792 const struct lttng_condition *condition)
793 {
794 struct cds_lfht_node *node;
795 struct cds_lfht_iter iter;
796 struct notification_client_list *list = NULL;
797
798 rcu_read_lock();
799 cds_lfht_lookup(state->notification_trigger_clients_ht,
800 lttng_condition_hash(condition),
801 match_client_list_condition,
802 condition,
803 &iter);
804 node = cds_lfht_iter_get_node(&iter);
805 if (node) {
806 list = container_of(node, struct notification_client_list,
807 notification_trigger_clients_ht_node);
808 list = notification_client_list_get(list) ? list : NULL;
809 }
810
811 rcu_read_unlock();
812 return list;
813 }
814
815 static
816 int evaluate_channel_condition_for_client(
817 const struct lttng_condition *condition,
818 struct notification_thread_state *state,
819 struct lttng_evaluation **evaluation,
820 uid_t *session_uid, gid_t *session_gid)
821 {
822 int ret;
823 struct cds_lfht_iter iter;
824 struct cds_lfht_node *node;
825 struct channel_info *channel_info = NULL;
826 struct channel_key *channel_key = NULL;
827 struct channel_state_sample *last_sample = NULL;
828 struct lttng_channel_trigger_list *channel_trigger_list = NULL;
829
830 rcu_read_lock();
831
832 /* Find the channel associated with the condition. */
833 cds_lfht_for_each_entry(state->channel_triggers_ht, &iter,
834 channel_trigger_list, channel_triggers_ht_node) {
835 struct lttng_trigger_list_element *element;
836
837 cds_list_for_each_entry(element, &channel_trigger_list->list, node) {
838 const struct lttng_condition *current_condition =
839 lttng_trigger_get_const_condition(
840 element->trigger);
841
842 assert(current_condition);
843 if (!lttng_condition_is_equal(condition,
844 current_condition)) {
845 continue;
846 }
847
848 /* Found the trigger, save the channel key. */
849 channel_key = &channel_trigger_list->channel_key;
850 break;
851 }
852 if (channel_key) {
853 /* The channel key was found stop iteration. */
854 break;
855 }
856 }
857
858 if (!channel_key){
859 /* No channel found; normal exit. */
860 DBG("[notification-thread] No known channel associated with newly subscribed-to condition");
861 ret = 0;
862 goto end;
863 }
864
865 /* Fetch channel info for the matching channel. */
866 cds_lfht_lookup(state->channels_ht,
867 hash_channel_key(channel_key),
868 match_channel_info,
869 channel_key,
870 &iter);
871 node = cds_lfht_iter_get_node(&iter);
872 assert(node);
873 channel_info = caa_container_of(node, struct channel_info,
874 channels_ht_node);
875
876 /* Retrieve the channel's last sample, if it exists. */
877 cds_lfht_lookup(state->channel_state_ht,
878 hash_channel_key(channel_key),
879 match_channel_state_sample,
880 channel_key,
881 &iter);
882 node = cds_lfht_iter_get_node(&iter);
883 if (node) {
884 last_sample = caa_container_of(node,
885 struct channel_state_sample,
886 channel_state_ht_node);
887 } else {
888 /* Nothing to evaluate, no sample was ever taken. Normal exit */
889 DBG("[notification-thread] No channel sample associated with newly subscribed-to condition");
890 ret = 0;
891 goto end;
892 }
893
894 ret = evaluate_buffer_condition(condition, evaluation, state,
895 NULL, last_sample,
896 0, channel_info->session_info->consumed_data_size,
897 channel_info);
898 if (ret) {
899 WARN("[notification-thread] Fatal error occurred while evaluating a newly subscribed-to condition");
900 goto end;
901 }
902
903 *session_uid = channel_info->session_info->uid;
904 *session_gid = channel_info->session_info->gid;
905 end:
906 rcu_read_unlock();
907 return ret;
908 }
909
910 static
911 const char *get_condition_session_name(const struct lttng_condition *condition)
912 {
913 const char *session_name = NULL;
914 enum lttng_condition_status status;
915
916 switch (lttng_condition_get_type(condition)) {
917 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
918 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
919 status = lttng_condition_buffer_usage_get_session_name(
920 condition, &session_name);
921 break;
922 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
923 status = lttng_condition_session_consumed_size_get_session_name(
924 condition, &session_name);
925 break;
926 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
927 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
928 status = lttng_condition_session_rotation_get_session_name(
929 condition, &session_name);
930 break;
931 default:
932 abort();
933 }
934 if (status != LTTNG_CONDITION_STATUS_OK) {
935 ERR("[notification-thread] Failed to retrieve session rotation condition's session name");
936 goto end;
937 }
938 end:
939 return session_name;
940 }
941
942 static
943 int evaluate_session_condition_for_client(
944 const struct lttng_condition *condition,
945 struct notification_thread_state *state,
946 struct lttng_evaluation **evaluation,
947 uid_t *session_uid, gid_t *session_gid)
948 {
949 int ret;
950 struct cds_lfht_iter iter;
951 struct cds_lfht_node *node;
952 const char *session_name;
953 struct session_info *session_info = NULL;
954
955 rcu_read_lock();
956 session_name = get_condition_session_name(condition);
957
958 /* Find the session associated with the trigger. */
959 cds_lfht_lookup(state->sessions_ht,
960 hash_key_str(session_name, lttng_ht_seed),
961 match_session,
962 session_name,
963 &iter);
964 node = cds_lfht_iter_get_node(&iter);
965 if (!node) {
966 DBG("[notification-thread] No known session matching name \"%s\"",
967 session_name);
968 ret = 0;
969 goto end;
970 }
971
972 session_info = caa_container_of(node, struct session_info,
973 sessions_ht_node);
974 session_info_get(session_info);
975
976 /*
977 * Evaluation is performed in-line here since only one type of
978 * session-bound condition is handled for the moment.
979 */
980 switch (lttng_condition_get_type(condition)) {
981 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
982 if (!session_info->rotation.ongoing) {
983 ret = 0;
984 goto end_session_put;
985 }
986
987 *evaluation = lttng_evaluation_session_rotation_ongoing_create(
988 session_info->rotation.id);
989 if (!*evaluation) {
990 /* Fatal error. */
991 ERR("[notification-thread] Failed to create session rotation ongoing evaluation for session \"%s\"",
992 session_info->name);
993 ret = -1;
994 goto end_session_put;
995 }
996 ret = 0;
997 break;
998 default:
999 ret = 0;
1000 goto end_session_put;
1001 }
1002
1003 *session_uid = session_info->uid;
1004 *session_gid = session_info->gid;
1005
1006 end_session_put:
1007 session_info_put(session_info);
1008 end:
1009 rcu_read_unlock();
1010 return ret;
1011 }
1012
1013 static
1014 int evaluate_condition_for_client(const struct lttng_trigger *trigger,
1015 const struct lttng_condition *condition,
1016 struct notification_client *client,
1017 struct notification_thread_state *state)
1018 {
1019 int ret;
1020 struct lttng_evaluation *evaluation = NULL;
1021 struct notification_client_list client_list = {
1022 .lock = PTHREAD_MUTEX_INITIALIZER,
1023 };
1024 struct notification_client_list_element client_list_element = { 0 };
1025 uid_t object_uid = 0;
1026 gid_t object_gid = 0;
1027
1028 assert(trigger);
1029 assert(condition);
1030 assert(client);
1031 assert(state);
1032
1033 switch (get_condition_binding_object(condition)) {
1034 case LTTNG_OBJECT_TYPE_SESSION:
1035 ret = evaluate_session_condition_for_client(condition, state,
1036 &evaluation, &object_uid, &object_gid);
1037 break;
1038 case LTTNG_OBJECT_TYPE_CHANNEL:
1039 ret = evaluate_channel_condition_for_client(condition, state,
1040 &evaluation, &object_uid, &object_gid);
1041 break;
1042 case LTTNG_OBJECT_TYPE_NONE:
1043 DBG("[notification-thread] Newly subscribed-to condition not bound to object, nothing to evaluate");
1044 ret = 0;
1045 goto end;
1046 case LTTNG_OBJECT_TYPE_UNKNOWN:
1047 default:
1048 ret = -1;
1049 goto end;
1050 }
1051 if (ret) {
1052 /* Fatal error. */
1053 goto end;
1054 }
1055 if (!evaluation) {
1056 /* Evaluation yielded nothing. Normal exit. */
1057 DBG("[notification-thread] Newly subscribed-to condition evaluated to false, nothing to report to client");
1058 ret = 0;
1059 goto end;
1060 }
1061
1062 /*
1063 * Create a temporary client list with the client currently
1064 * subscribing.
1065 */
1066 cds_lfht_node_init(&client_list.notification_trigger_clients_ht_node);
1067 CDS_INIT_LIST_HEAD(&client_list.clients_list);
1068
1069 CDS_INIT_LIST_HEAD(&client_list_element.node);
1070 client_list_element.client = client;
1071 cds_list_add(&client_list_element.node, &client_list.clients_list);
1072
1073 /* Send evaluation result to the newly-subscribed client. */
1074 DBG("[notification-thread] Newly subscribed-to condition evaluated to true, notifying client");
1075 ret = send_evaluation_to_clients(trigger, evaluation, &client_list,
1076 state, object_uid, object_gid);
1077
1078 end:
1079 return ret;
1080 }
1081
1082 static
1083 int notification_thread_client_subscribe(struct notification_client *client,
1084 struct lttng_condition *condition,
1085 struct notification_thread_state *state,
1086 enum lttng_notification_channel_status *_status)
1087 {
1088 int ret = 0;
1089 struct notification_client_list *client_list = NULL;
1090 struct lttng_condition_list_element *condition_list_element = NULL;
1091 struct notification_client_list_element *client_list_element = NULL;
1092 enum lttng_notification_channel_status status =
1093 LTTNG_NOTIFICATION_CHANNEL_STATUS_OK;
1094
1095 /*
1096 * Ensure that the client has not already subscribed to this condition
1097 * before.
1098 */
1099 cds_list_for_each_entry(condition_list_element, &client->condition_list, node) {
1100 if (lttng_condition_is_equal(condition_list_element->condition,
1101 condition)) {
1102 status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED;
1103 goto end;
1104 }
1105 }
1106
1107 condition_list_element = zmalloc(sizeof(*condition_list_element));
1108 if (!condition_list_element) {
1109 ret = -1;
1110 goto error;
1111 }
1112 client_list_element = zmalloc(sizeof(*client_list_element));
1113 if (!client_list_element) {
1114 ret = -1;
1115 goto error;
1116 }
1117
1118 /*
1119 * Add the newly-subscribed condition to the client's subscription list.
1120 */
1121 CDS_INIT_LIST_HEAD(&condition_list_element->node);
1122 condition_list_element->condition = condition;
1123 cds_list_add(&condition_list_element->node, &client->condition_list);
1124
1125 client_list = get_client_list_from_condition(state, condition);
1126 if (!client_list) {
1127 /*
1128 * No notification-emiting trigger registered with this
1129 * condition. We don't evaluate the condition right away
1130 * since this trigger is not registered yet.
1131 */
1132 free(client_list_element);
1133 goto end;
1134 }
1135
1136 /*
1137 * The condition to which the client just subscribed is evaluated
1138 * at this point so that conditions that are already TRUE result
1139 * in a notification being sent out.
1140 *
1141 * The client_list's trigger is used without locking the list itself.
1142 * This is correct since the list doesn't own the trigger and the
1143 * object is immutable.
1144 */
1145 struct lttng_trigger_ht_element *trigger_ht_element;
1146 pthread_mutex_lock(&client_list->lock);
1147 cds_list_for_each_entry(trigger_ht_element,
1148 &client_list->triggers_list, client_list_trigger_node) {
1149 if (evaluate_condition_for_client(trigger_ht_element->trigger, condition,
1150 client, state)) {
1151 WARN("[notification-thread] Evaluation of a condition on client subscription failed, aborting.");
1152 ret = -1;
1153 free(client_list_element);
1154 goto end;
1155 }
1156 }
1157 pthread_mutex_unlock(&client_list->lock);
1158
1159 /*
1160 * Add the client to the list of clients interested in a given trigger
1161 * if a "notification" trigger with a corresponding condition was
1162 * added prior.
1163 */
1164 client_list_element->client = client;
1165 CDS_INIT_LIST_HEAD(&client_list_element->node);
1166
1167 pthread_mutex_lock(&client_list->lock);
1168 cds_list_add(&client_list_element->node, &client_list->clients_list);
1169 pthread_mutex_unlock(&client_list->lock);
1170 end:
1171 if (_status) {
1172 *_status = status;
1173 }
1174 if (client_list) {
1175 notification_client_list_put(client_list);
1176 }
1177 return ret;
1178 error:
1179 free(condition_list_element);
1180 free(client_list_element);
1181 return ret;
1182 }
1183
1184 static
1185 int notification_thread_client_unsubscribe(
1186 struct notification_client *client,
1187 struct lttng_condition *condition,
1188 struct notification_thread_state *state,
1189 enum lttng_notification_channel_status *_status)
1190 {
1191 struct notification_client_list *client_list;
1192 struct lttng_condition_list_element *condition_list_element,
1193 *condition_tmp;
1194 struct notification_client_list_element *client_list_element,
1195 *client_tmp;
1196 bool condition_found = false;
1197 enum lttng_notification_channel_status status =
1198 LTTNG_NOTIFICATION_CHANNEL_STATUS_OK;
1199
1200 /* Remove the condition from the client's condition list. */
1201 cds_list_for_each_entry_safe(condition_list_element, condition_tmp,
1202 &client->condition_list, node) {
1203 if (!lttng_condition_is_equal(condition_list_element->condition,
1204 condition)) {
1205 continue;
1206 }
1207
1208 cds_list_del(&condition_list_element->node);
1209 /*
1210 * The caller may be iterating on the client's conditions to
1211 * tear down a client's connection. In this case, the condition
1212 * will be destroyed at the end.
1213 */
1214 if (condition != condition_list_element->condition) {
1215 lttng_condition_destroy(
1216 condition_list_element->condition);
1217 }
1218 free(condition_list_element);
1219 condition_found = true;
1220 break;
1221 }
1222
1223 if (!condition_found) {
1224 status = LTTNG_NOTIFICATION_CHANNEL_STATUS_UNKNOWN_CONDITION;
1225 goto end;
1226 }
1227
1228 /*
1229 * Remove the client from the list of clients interested the trigger
1230 * matching the condition.
1231 */
1232 client_list = get_client_list_from_condition(state, condition);
1233 if (!client_list) {
1234 goto end;
1235 }
1236
1237 pthread_mutex_lock(&client_list->lock);
1238 cds_list_for_each_entry_safe(client_list_element, client_tmp,
1239 &client_list->clients_list, node) {
1240 if (client_list_element->client->id != client->id) {
1241 continue;
1242 }
1243 cds_list_del(&client_list_element->node);
1244 free(client_list_element);
1245 break;
1246 }
1247 pthread_mutex_unlock(&client_list->lock);
1248 notification_client_list_put(client_list);
1249 client_list = NULL;
1250 end:
1251 lttng_condition_destroy(condition);
1252 if (_status) {
1253 *_status = status;
1254 }
1255 return 0;
1256 }
1257
1258 static
1259 void free_notification_client_rcu(struct rcu_head *node)
1260 {
1261 free(caa_container_of(node, struct notification_client, rcu_node));
1262 }
1263
1264 static
1265 void notification_client_destroy(struct notification_client *client,
1266 struct notification_thread_state *state)
1267 {
1268 if (!client) {
1269 return;
1270 }
1271
1272 /*
1273 * The client object is not reachable by other threads, no need to lock
1274 * the client here.
1275 */
1276 if (client->socket >= 0) {
1277 (void) lttcomm_close_unix_sock(client->socket);
1278 client->socket = -1;
1279 }
1280 client->communication.active = false;
1281 lttng_payload_reset(&client->communication.inbound.payload);
1282 lttng_payload_reset(&client->communication.outbound.payload);
1283 pthread_mutex_destroy(&client->lock);
1284 call_rcu(&client->rcu_node, free_notification_client_rcu);
1285 }
1286
1287 /*
1288 * Call with rcu_read_lock held (and hold for the lifetime of the returned
1289 * client pointer).
1290 */
1291 static
1292 struct notification_client *get_client_from_socket(int socket,
1293 struct notification_thread_state *state)
1294 {
1295 struct cds_lfht_iter iter;
1296 struct cds_lfht_node *node;
1297 struct notification_client *client = NULL;
1298
1299 cds_lfht_lookup(state->client_socket_ht,
1300 hash_client_socket(socket),
1301 match_client_socket,
1302 (void *) (unsigned long) socket,
1303 &iter);
1304 node = cds_lfht_iter_get_node(&iter);
1305 if (!node) {
1306 goto end;
1307 }
1308
1309 client = caa_container_of(node, struct notification_client,
1310 client_socket_ht_node);
1311 end:
1312 return client;
1313 }
1314
1315 /*
1316 * Call with rcu_read_lock held (and hold for the lifetime of the returned
1317 * client pointer).
1318 */
1319 static
1320 struct notification_client *get_client_from_id(notification_client_id id,
1321 struct notification_thread_state *state)
1322 {
1323 struct cds_lfht_iter iter;
1324 struct cds_lfht_node *node;
1325 struct notification_client *client = NULL;
1326
1327 cds_lfht_lookup(state->client_id_ht,
1328 hash_client_id(id),
1329 match_client_id,
1330 &id,
1331 &iter);
1332 node = cds_lfht_iter_get_node(&iter);
1333 if (!node) {
1334 goto end;
1335 }
1336
1337 client = caa_container_of(node, struct notification_client,
1338 client_id_ht_node);
1339 end:
1340 return client;
1341 }
1342
1343 static
1344 bool buffer_usage_condition_applies_to_channel(
1345 const struct lttng_condition *condition,
1346 const struct channel_info *channel_info)
1347 {
1348 enum lttng_condition_status status;
1349 enum lttng_domain_type condition_domain;
1350 const char *condition_session_name = NULL;
1351 const char *condition_channel_name = NULL;
1352
1353 status = lttng_condition_buffer_usage_get_domain_type(condition,
1354 &condition_domain);
1355 assert(status == LTTNG_CONDITION_STATUS_OK);
1356 if (channel_info->key.domain != condition_domain) {
1357 goto fail;
1358 }
1359
1360 status = lttng_condition_buffer_usage_get_session_name(
1361 condition, &condition_session_name);
1362 assert((status == LTTNG_CONDITION_STATUS_OK) && condition_session_name);
1363
1364 status = lttng_condition_buffer_usage_get_channel_name(
1365 condition, &condition_channel_name);
1366 assert((status == LTTNG_CONDITION_STATUS_OK) && condition_channel_name);
1367
1368 if (strcmp(channel_info->session_info->name, condition_session_name)) {
1369 goto fail;
1370 }
1371 if (strcmp(channel_info->name, condition_channel_name)) {
1372 goto fail;
1373 }
1374
1375 return true;
1376 fail:
1377 return false;
1378 }
1379
1380 static
1381 bool session_consumed_size_condition_applies_to_channel(
1382 const struct lttng_condition *condition,
1383 const struct channel_info *channel_info)
1384 {
1385 enum lttng_condition_status status;
1386 const char *condition_session_name = NULL;
1387
1388 status = lttng_condition_session_consumed_size_get_session_name(
1389 condition, &condition_session_name);
1390 assert((status == LTTNG_CONDITION_STATUS_OK) && condition_session_name);
1391
1392 if (strcmp(channel_info->session_info->name, condition_session_name)) {
1393 goto fail;
1394 }
1395
1396 return true;
1397 fail:
1398 return false;
1399 }
1400
1401 static
1402 bool trigger_applies_to_channel(const struct lttng_trigger *trigger,
1403 const struct channel_info *channel_info)
1404 {
1405 const struct lttng_condition *condition;
1406 bool trigger_applies;
1407
1408 condition = lttng_trigger_get_const_condition(trigger);
1409 if (!condition) {
1410 goto fail;
1411 }
1412
1413 switch (lttng_condition_get_type(condition)) {
1414 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
1415 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
1416 trigger_applies = buffer_usage_condition_applies_to_channel(
1417 condition, channel_info);
1418 break;
1419 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
1420 trigger_applies = session_consumed_size_condition_applies_to_channel(
1421 condition, channel_info);
1422 break;
1423 default:
1424 goto fail;
1425 }
1426
1427 return trigger_applies;
1428 fail:
1429 return false;
1430 }
1431
1432 /* Must be called with RCU read lock held. */
1433 static
1434 struct lttng_session_trigger_list *get_session_trigger_list(
1435 struct notification_thread_state *state,
1436 const char *session_name)
1437 {
1438 struct lttng_session_trigger_list *list = NULL;
1439 struct cds_lfht_node *node;
1440 struct cds_lfht_iter iter;
1441
1442 cds_lfht_lookup(state->session_triggers_ht,
1443 hash_key_str(session_name, lttng_ht_seed),
1444 match_session_trigger_list,
1445 session_name,
1446 &iter);
1447 node = cds_lfht_iter_get_node(&iter);
1448 if (!node) {
1449 /*
1450 * Not an error, the list of triggers applying to that session
1451 * will be initialized when the session is created.
1452 */
1453 DBG("[notification-thread] No trigger list found for session \"%s\" as it is not yet known to the notification system",
1454 session_name);
1455 goto end;
1456 }
1457
1458 list = caa_container_of(node,
1459 struct lttng_session_trigger_list,
1460 session_triggers_ht_node);
1461 end:
1462 return list;
1463 }
1464
1465 /*
1466 * Allocate an empty lttng_session_trigger_list for the session named
1467 * 'session_name'.
1468 *
1469 * No ownership of 'session_name' is assumed by the session trigger list.
1470 * It is the caller's responsability to ensure the session name is alive
1471 * for as long as this list is.
1472 */
1473 static
1474 struct lttng_session_trigger_list *lttng_session_trigger_list_create(
1475 const char *session_name,
1476 struct cds_lfht *session_triggers_ht)
1477 {
1478 struct lttng_session_trigger_list *list;
1479
1480 list = zmalloc(sizeof(*list));
1481 if (!list) {
1482 goto end;
1483 }
1484 list->session_name = session_name;
1485 CDS_INIT_LIST_HEAD(&list->list);
1486 cds_lfht_node_init(&list->session_triggers_ht_node);
1487 list->session_triggers_ht = session_triggers_ht;
1488
1489 rcu_read_lock();
1490 /* Publish the list through the session_triggers_ht. */
1491 cds_lfht_add(session_triggers_ht,
1492 hash_key_str(session_name, lttng_ht_seed),
1493 &list->session_triggers_ht_node);
1494 rcu_read_unlock();
1495 end:
1496 return list;
1497 }
1498
1499 static
1500 void free_session_trigger_list_rcu(struct rcu_head *node)
1501 {
1502 free(caa_container_of(node, struct lttng_session_trigger_list,
1503 rcu_node));
1504 }
1505
1506 static
1507 void lttng_session_trigger_list_destroy(struct lttng_session_trigger_list *list)
1508 {
1509 struct lttng_trigger_list_element *trigger_list_element, *tmp;
1510
1511 /* Empty the list element by element, and then free the list itself. */
1512 cds_list_for_each_entry_safe(trigger_list_element, tmp,
1513 &list->list, node) {
1514 cds_list_del(&trigger_list_element->node);
1515 free(trigger_list_element);
1516 }
1517 rcu_read_lock();
1518 /* Unpublish the list from the session_triggers_ht. */
1519 cds_lfht_del(list->session_triggers_ht,
1520 &list->session_triggers_ht_node);
1521 rcu_read_unlock();
1522 call_rcu(&list->rcu_node, free_session_trigger_list_rcu);
1523 }
1524
1525 static
1526 int lttng_session_trigger_list_add(struct lttng_session_trigger_list *list,
1527 struct lttng_trigger *trigger)
1528 {
1529 int ret = 0;
1530 struct lttng_trigger_list_element *new_element =
1531 zmalloc(sizeof(*new_element));
1532
1533 if (!new_element) {
1534 ret = -1;
1535 goto end;
1536 }
1537 CDS_INIT_LIST_HEAD(&new_element->node);
1538 new_element->trigger = trigger;
1539 cds_list_add(&new_element->node, &list->list);
1540 end:
1541 return ret;
1542 }
1543
1544 static
1545 bool trigger_applies_to_session(const struct lttng_trigger *trigger,
1546 const char *session_name)
1547 {
1548 bool applies = false;
1549 const struct lttng_condition *condition;
1550
1551 condition = lttng_trigger_get_const_condition(trigger);
1552 switch (lttng_condition_get_type(condition)) {
1553 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
1554 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
1555 {
1556 enum lttng_condition_status condition_status;
1557 const char *condition_session_name;
1558
1559 condition_status = lttng_condition_session_rotation_get_session_name(
1560 condition, &condition_session_name);
1561 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1562 ERR("[notification-thread] Failed to retrieve session rotation condition's session name");
1563 goto end;
1564 }
1565
1566 assert(condition_session_name);
1567 applies = !strcmp(condition_session_name, session_name);
1568 break;
1569 }
1570 default:
1571 goto end;
1572 }
1573 end:
1574 return applies;
1575 }
1576
1577 /*
1578 * Allocate and initialize an lttng_session_trigger_list which contains
1579 * all triggers that apply to the session named 'session_name'.
1580 *
1581 * No ownership of 'session_name' is assumed by the session trigger list.
1582 * It is the caller's responsability to ensure the session name is alive
1583 * for as long as this list is.
1584 */
1585 static
1586 struct lttng_session_trigger_list *lttng_session_trigger_list_build(
1587 const struct notification_thread_state *state,
1588 const char *session_name)
1589 {
1590 int trigger_count = 0;
1591 struct lttng_session_trigger_list *session_trigger_list = NULL;
1592 struct lttng_trigger_ht_element *trigger_ht_element = NULL;
1593 struct cds_lfht_iter iter;
1594
1595 session_trigger_list = lttng_session_trigger_list_create(session_name,
1596 state->session_triggers_ht);
1597
1598 /* Add all triggers applying to the session named 'session_name'. */
1599 cds_lfht_for_each_entry(state->triggers_ht, &iter, trigger_ht_element,
1600 node) {
1601 int ret;
1602
1603 if (!trigger_applies_to_session(trigger_ht_element->trigger,
1604 session_name)) {
1605 continue;
1606 }
1607
1608 ret = lttng_session_trigger_list_add(session_trigger_list,
1609 trigger_ht_element->trigger);
1610 if (ret) {
1611 goto error;
1612 }
1613
1614 trigger_count++;
1615 }
1616
1617 DBG("[notification-thread] Found %i triggers that apply to newly created session",
1618 trigger_count);
1619 return session_trigger_list;
1620 error:
1621 lttng_session_trigger_list_destroy(session_trigger_list);
1622 return NULL;
1623 }
1624
1625 static
1626 struct session_info *find_or_create_session_info(
1627 struct notification_thread_state *state,
1628 const char *name, uid_t uid, gid_t gid)
1629 {
1630 struct session_info *session = NULL;
1631 struct cds_lfht_node *node;
1632 struct cds_lfht_iter iter;
1633 struct lttng_session_trigger_list *trigger_list;
1634
1635 rcu_read_lock();
1636 cds_lfht_lookup(state->sessions_ht,
1637 hash_key_str(name, lttng_ht_seed),
1638 match_session,
1639 name,
1640 &iter);
1641 node = cds_lfht_iter_get_node(&iter);
1642 if (node) {
1643 DBG("[notification-thread] Found session info of session \"%s\" (uid = %i, gid = %i)",
1644 name, uid, gid);
1645 session = caa_container_of(node, struct session_info,
1646 sessions_ht_node);
1647 assert(session->uid == uid);
1648 assert(session->gid == gid);
1649 session_info_get(session);
1650 goto end;
1651 }
1652
1653 trigger_list = lttng_session_trigger_list_build(state, name);
1654 if (!trigger_list) {
1655 goto error;
1656 }
1657
1658 session = session_info_create(name, uid, gid, trigger_list,
1659 state->sessions_ht);
1660 if (!session) {
1661 ERR("[notification-thread] Failed to allocation session info for session \"%s\" (uid = %i, gid = %i)",
1662 name, uid, gid);
1663 lttng_session_trigger_list_destroy(trigger_list);
1664 goto error;
1665 }
1666 trigger_list = NULL;
1667
1668 cds_lfht_add(state->sessions_ht, hash_key_str(name, lttng_ht_seed),
1669 &session->sessions_ht_node);
1670 end:
1671 rcu_read_unlock();
1672 return session;
1673 error:
1674 rcu_read_unlock();
1675 session_info_put(session);
1676 return NULL;
1677 }
1678
1679 static
1680 int handle_notification_thread_command_add_channel(
1681 struct notification_thread_state *state,
1682 const char *session_name, uid_t session_uid, gid_t session_gid,
1683 const char *channel_name, enum lttng_domain_type channel_domain,
1684 uint64_t channel_key_int, uint64_t channel_capacity,
1685 enum lttng_error_code *cmd_result)
1686 {
1687 struct cds_list_head trigger_list;
1688 struct channel_info *new_channel_info = NULL;
1689 struct channel_key channel_key = {
1690 .key = channel_key_int,
1691 .domain = channel_domain,
1692 };
1693 struct lttng_channel_trigger_list *channel_trigger_list = NULL;
1694 struct lttng_trigger_ht_element *trigger_ht_element = NULL;
1695 int trigger_count = 0;
1696 struct cds_lfht_iter iter;
1697 struct session_info *session_info = NULL;
1698
1699 DBG("[notification-thread] Adding channel %s from session %s, channel key = %" PRIu64 " in %s domain",
1700 channel_name, session_name, channel_key_int,
1701 lttng_domain_type_str(channel_domain));
1702
1703 CDS_INIT_LIST_HEAD(&trigger_list);
1704
1705 session_info = find_or_create_session_info(state, session_name,
1706 session_uid, session_gid);
1707 if (!session_info) {
1708 /* Allocation error or an internal error occurred. */
1709 goto error;
1710 }
1711
1712 new_channel_info = channel_info_create(channel_name, &channel_key,
1713 channel_capacity, session_info);
1714 if (!new_channel_info) {
1715 goto error;
1716 }
1717
1718 rcu_read_lock();
1719 /* Build a list of all triggers applying to the new channel. */
1720 cds_lfht_for_each_entry(state->triggers_ht, &iter, trigger_ht_element,
1721 node) {
1722 struct lttng_trigger_list_element *new_element;
1723
1724 if (!trigger_applies_to_channel(trigger_ht_element->trigger,
1725 new_channel_info)) {
1726 continue;
1727 }
1728
1729 new_element = zmalloc(sizeof(*new_element));
1730 if (!new_element) {
1731 rcu_read_unlock();
1732 goto error;
1733 }
1734 CDS_INIT_LIST_HEAD(&new_element->node);
1735 new_element->trigger = trigger_ht_element->trigger;
1736 cds_list_add(&new_element->node, &trigger_list);
1737 trigger_count++;
1738 }
1739 rcu_read_unlock();
1740
1741 DBG("[notification-thread] Found %i triggers that apply to newly added channel",
1742 trigger_count);
1743 channel_trigger_list = zmalloc(sizeof(*channel_trigger_list));
1744 if (!channel_trigger_list) {
1745 goto error;
1746 }
1747 channel_trigger_list->channel_key = new_channel_info->key;
1748 CDS_INIT_LIST_HEAD(&channel_trigger_list->list);
1749 cds_lfht_node_init(&channel_trigger_list->channel_triggers_ht_node);
1750 cds_list_splice(&trigger_list, &channel_trigger_list->list);
1751
1752 rcu_read_lock();
1753 /* Add channel to the channel_ht which owns the channel_infos. */
1754 cds_lfht_add(state->channels_ht,
1755 hash_channel_key(&new_channel_info->key),
1756 &new_channel_info->channels_ht_node);
1757 /*
1758 * Add the list of triggers associated with this channel to the
1759 * channel_triggers_ht.
1760 */
1761 cds_lfht_add(state->channel_triggers_ht,
1762 hash_channel_key(&new_channel_info->key),
1763 &channel_trigger_list->channel_triggers_ht_node);
1764 rcu_read_unlock();
1765 session_info_put(session_info);
1766 *cmd_result = LTTNG_OK;
1767 return 0;
1768 error:
1769 channel_info_destroy(new_channel_info);
1770 session_info_put(session_info);
1771 return 1;
1772 }
1773
1774 static
1775 void free_channel_trigger_list_rcu(struct rcu_head *node)
1776 {
1777 free(caa_container_of(node, struct lttng_channel_trigger_list,
1778 rcu_node));
1779 }
1780
1781 static
1782 void free_channel_state_sample_rcu(struct rcu_head *node)
1783 {
1784 free(caa_container_of(node, struct channel_state_sample,
1785 rcu_node));
1786 }
1787
1788 static
1789 int handle_notification_thread_command_remove_channel(
1790 struct notification_thread_state *state,
1791 uint64_t channel_key, enum lttng_domain_type domain,
1792 enum lttng_error_code *cmd_result)
1793 {
1794 struct cds_lfht_node *node;
1795 struct cds_lfht_iter iter;
1796 struct lttng_channel_trigger_list *trigger_list;
1797 struct lttng_trigger_list_element *trigger_list_element, *tmp;
1798 struct channel_key key = { .key = channel_key, .domain = domain };
1799 struct channel_info *channel_info;
1800
1801 DBG("[notification-thread] Removing channel key = %" PRIu64 " in %s domain",
1802 channel_key, lttng_domain_type_str(domain));
1803
1804 rcu_read_lock();
1805
1806 cds_lfht_lookup(state->channel_triggers_ht,
1807 hash_channel_key(&key),
1808 match_channel_trigger_list,
1809 &key,
1810 &iter);
1811 node = cds_lfht_iter_get_node(&iter);
1812 /*
1813 * There is a severe internal error if we are being asked to remove a
1814 * channel that doesn't exist.
1815 */
1816 if (!node) {
1817 ERR("[notification-thread] Channel being removed is unknown to the notification thread");
1818 goto end;
1819 }
1820
1821 /* Free the list of triggers associated with this channel. */
1822 trigger_list = caa_container_of(node, struct lttng_channel_trigger_list,
1823 channel_triggers_ht_node);
1824 cds_list_for_each_entry_safe(trigger_list_element, tmp,
1825 &trigger_list->list, node) {
1826 cds_list_del(&trigger_list_element->node);
1827 free(trigger_list_element);
1828 }
1829 cds_lfht_del(state->channel_triggers_ht, node);
1830 call_rcu(&trigger_list->rcu_node, free_channel_trigger_list_rcu);
1831
1832 /* Free sampled channel state. */
1833 cds_lfht_lookup(state->channel_state_ht,
1834 hash_channel_key(&key),
1835 match_channel_state_sample,
1836 &key,
1837 &iter);
1838 node = cds_lfht_iter_get_node(&iter);
1839 /*
1840 * This is expected to be NULL if the channel is destroyed before we
1841 * received a sample.
1842 */
1843 if (node) {
1844 struct channel_state_sample *sample = caa_container_of(node,
1845 struct channel_state_sample,
1846 channel_state_ht_node);
1847
1848 cds_lfht_del(state->channel_state_ht, node);
1849 call_rcu(&sample->rcu_node, free_channel_state_sample_rcu);
1850 }
1851
1852 /* Remove the channel from the channels_ht and free it. */
1853 cds_lfht_lookup(state->channels_ht,
1854 hash_channel_key(&key),
1855 match_channel_info,
1856 &key,
1857 &iter);
1858 node = cds_lfht_iter_get_node(&iter);
1859 assert(node);
1860 channel_info = caa_container_of(node, struct channel_info,
1861 channels_ht_node);
1862 cds_lfht_del(state->channels_ht, node);
1863 channel_info_destroy(channel_info);
1864 end:
1865 rcu_read_unlock();
1866 *cmd_result = LTTNG_OK;
1867 return 0;
1868 }
1869
1870 static
1871 int handle_notification_thread_command_session_rotation(
1872 struct notification_thread_state *state,
1873 enum notification_thread_command_type cmd_type,
1874 const char *session_name, uid_t session_uid, gid_t session_gid,
1875 uint64_t trace_archive_chunk_id,
1876 struct lttng_trace_archive_location *location,
1877 enum lttng_error_code *_cmd_result)
1878 {
1879 int ret = 0;
1880 enum lttng_error_code cmd_result = LTTNG_OK;
1881 struct lttng_session_trigger_list *trigger_list;
1882 struct lttng_trigger_list_element *trigger_list_element;
1883 struct session_info *session_info;
1884 const struct lttng_credentials session_creds = {
1885 .uid = LTTNG_OPTIONAL_INIT_VALUE(session_uid),
1886 .gid = LTTNG_OPTIONAL_INIT_VALUE(session_gid),
1887 };
1888
1889 rcu_read_lock();
1890
1891 session_info = find_or_create_session_info(state, session_name,
1892 session_uid, session_gid);
1893 if (!session_info) {
1894 /* Allocation error or an internal error occurred. */
1895 ret = -1;
1896 cmd_result = LTTNG_ERR_NOMEM;
1897 goto end;
1898 }
1899
1900 session_info->rotation.ongoing =
1901 cmd_type == NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING;
1902 session_info->rotation.id = trace_archive_chunk_id;
1903 trigger_list = get_session_trigger_list(state, session_name);
1904 if (!trigger_list) {
1905 DBG("[notification-thread] No triggers applying to session \"%s\" found",
1906 session_name);
1907 goto end;
1908 }
1909
1910 cds_list_for_each_entry(trigger_list_element, &trigger_list->list,
1911 node) {
1912 const struct lttng_condition *condition;
1913 struct lttng_trigger *trigger;
1914 struct notification_client_list *client_list;
1915 struct lttng_evaluation *evaluation = NULL;
1916 enum lttng_condition_type condition_type;
1917 enum action_executor_status executor_status;
1918
1919 trigger = trigger_list_element->trigger;
1920 condition = lttng_trigger_get_const_condition(trigger);
1921 assert(condition);
1922 condition_type = lttng_condition_get_type(condition);
1923
1924 if (condition_type == LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING &&
1925 cmd_type != NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING) {
1926 continue;
1927 } else if (condition_type == LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED &&
1928 cmd_type != NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_COMPLETED) {
1929 continue;
1930 }
1931
1932 client_list = get_client_list_from_condition(state, condition);
1933 if (cmd_type == NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING) {
1934 evaluation = lttng_evaluation_session_rotation_ongoing_create(
1935 trace_archive_chunk_id);
1936 } else {
1937 evaluation = lttng_evaluation_session_rotation_completed_create(
1938 trace_archive_chunk_id, location);
1939 }
1940
1941 if (!evaluation) {
1942 /* Internal error */
1943 ret = -1;
1944 cmd_result = LTTNG_ERR_UNK;
1945 goto put_list;
1946 }
1947
1948 /*
1949 * Ownership of `evaluation` transferred to the action executor
1950 * no matter the result.
1951 */
1952 executor_status = action_executor_enqueue(state->executor,
1953 trigger, evaluation, &session_creds,
1954 client_list);
1955 evaluation = NULL;
1956 switch (executor_status) {
1957 case ACTION_EXECUTOR_STATUS_OK:
1958 break;
1959 case ACTION_EXECUTOR_STATUS_ERROR:
1960 case ACTION_EXECUTOR_STATUS_INVALID:
1961 /*
1962 * TODO Add trigger identification (name/id) when
1963 * it is added to the API.
1964 */
1965 ERR("Fatal error occurred while enqueuing action associated with session rotation trigger");
1966 ret = -1;
1967 goto put_list;
1968 case ACTION_EXECUTOR_STATUS_OVERFLOW:
1969 /*
1970 * TODO Add trigger identification (name/id) when
1971 * it is added to the API.
1972 *
1973 * Not a fatal error.
1974 */
1975 WARN("No space left when enqueuing action associated with session rotation trigger");
1976 ret = 0;
1977 goto put_list;
1978 default:
1979 abort();
1980 }
1981
1982 put_list:
1983 notification_client_list_put(client_list);
1984 if (caa_unlikely(ret)) {
1985 break;
1986 }
1987 }
1988 end:
1989 session_info_put(session_info);
1990 *_cmd_result = cmd_result;
1991 rcu_read_unlock();
1992 return ret;
1993 }
1994
1995 static
1996 int handle_notification_thread_command_add_tracer_event_source(
1997 struct notification_thread_state *state,
1998 int tracer_event_source_fd,
1999 enum lttng_domain_type domain_type,
2000 enum lttng_error_code *_cmd_result)
2001 {
2002 int ret = 0;
2003 enum lttng_error_code cmd_result = LTTNG_OK;
2004 struct notification_event_tracer_event_source_element *element = NULL;
2005
2006 element = zmalloc(sizeof(*element));
2007 if (!element) {
2008 cmd_result = LTTNG_ERR_NOMEM;
2009 ret = -1;
2010 goto end;
2011 }
2012
2013 element->fd = tracer_event_source_fd;
2014 element->domain = domain_type;
2015
2016 cds_list_add(&element->node, &state->tracer_event_sources_list);
2017
2018 DBG3("[notification-thread] Adding tracer event source fd to poll set: tracer_event_source_fd = %d, domain = '%s'",
2019 tracer_event_source_fd,
2020 lttng_domain_type_str(domain_type));
2021
2022 /* Adding the read side pipe to the event poll. */
2023 ret = lttng_poll_add(&state->events, tracer_event_source_fd, LPOLLIN | LPOLLERR);
2024 if (ret < 0) {
2025 ERR("[notification-thread] Failed to add tracer event source to poll set: tracer_event_source_fd = %d, domain = '%s'",
2026 tracer_event_source_fd,
2027 lttng_domain_type_str(element->domain));
2028 cds_list_del(&element->node);
2029 free(element);
2030 goto end;
2031 }
2032
2033 element->is_fd_in_poll_set = true;
2034
2035 end:
2036 *_cmd_result = cmd_result;
2037 return ret;
2038 }
2039
2040 static
2041 int drain_event_notifier_notification_pipe(
2042 struct notification_thread_state *state,
2043 int pipe, enum lttng_domain_type domain)
2044 {
2045 struct lttng_poll_event events = {0};
2046 int ret;
2047
2048 ret = lttng_poll_create(&events, 1, LTTNG_CLOEXEC);
2049 if (ret < 0) {
2050 ERR("[notification-thread] Error creating lttng_poll_event");
2051 goto end;
2052 }
2053
2054 ret = lttng_poll_add(&events, pipe, LPOLLIN);
2055 if (ret < 0) {
2056 ERR("[notification-thread] Error adding fd event notifier notification pipe to lttng_poll_event: fd = %d",
2057 pipe);
2058 goto end;
2059 }
2060
2061 while (true) {
2062 /*
2063 * Continue to consume notifications as long as there are new
2064 * ones coming in. The tracer has been asked to stop producing
2065 * them.
2066 *
2067 * LPOLLIN is explicitly checked since LPOLLHUP is implicitly
2068 * monitored (on Linux, at least) and will be returned when
2069 * the pipe is closed but empty.
2070 */
2071 ret = lttng_poll_wait_interruptible(&events, 0);
2072 if (ret == 0 || (LTTNG_POLL_GETEV(&events, 0) & LPOLLIN) == 0) {
2073 /* No more notification to be read on this pipe. */
2074 ret = 0;
2075 goto end;
2076 } else if (ret < 0) {
2077 PERROR("Failed on lttng_poll_wait_interruptible() call");
2078 ret = -1;
2079 goto end;
2080 }
2081
2082 ret = handle_one_event_notifier_notification(state, pipe, domain);
2083 if (ret) {
2084 ERR("[notification-thread] Error consuming an event notifier notification from pipe: fd = %d",
2085 pipe);
2086 }
2087 }
2088 end:
2089 lttng_poll_clean(&events);
2090 return ret;
2091 }
2092
2093 static
2094 int handle_notification_thread_command_remove_tracer_event_source(
2095 struct notification_thread_state *state,
2096 int tracer_event_source_fd,
2097 enum lttng_error_code *_cmd_result)
2098 {
2099 int ret = 0;
2100 bool found = false;
2101 enum lttng_error_code cmd_result = LTTNG_OK;
2102 struct notification_event_tracer_event_source_element *source_element = NULL, *tmp;
2103
2104 cds_list_for_each_entry_safe(source_element, tmp,
2105 &state->tracer_event_sources_list, node) {
2106 if (source_element->fd != tracer_event_source_fd) {
2107 continue;
2108 }
2109
2110 DBG("[notification-thread] Removed tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
2111 tracer_event_source_fd,
2112 lttng_domain_type_str(source_element->domain));
2113 cds_list_del(&source_element->node);
2114 found = true;
2115 break;
2116 }
2117
2118 if (!found) {
2119 /*
2120 * This is temporarily allowed since the poll activity set is
2121 * not properly cleaned-up for the moment. This is adressed in
2122 * an upcoming fix.
2123 */
2124 source_element = NULL;
2125 goto end;
2126 }
2127
2128 if (!source_element->is_fd_in_poll_set) {
2129 /* Skip the poll set removal. */
2130 goto end;
2131 }
2132
2133 DBG3("[notification-thread] Removing tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
2134 tracer_event_source_fd,
2135 lttng_domain_type_str(source_element->domain));
2136
2137 /* Removing the fd from the event poll set. */
2138 ret = lttng_poll_del(&state->events, tracer_event_source_fd);
2139 if (ret < 0) {
2140 ERR("[notification-thread] Failed to remove tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
2141 tracer_event_source_fd,
2142 lttng_domain_type_str(source_element->domain));
2143 cmd_result = LTTNG_ERR_FATAL;
2144 goto end;
2145 }
2146
2147 source_element->is_fd_in_poll_set = false;
2148
2149 ret = drain_event_notifier_notification_pipe(state, tracer_event_source_fd,
2150 source_element->domain);
2151 if (ret) {
2152 ERR("[notification-thread] Error draining event notifier notification: tracer_event_source_fd = %d, domain = %s",
2153 tracer_event_source_fd,
2154 lttng_domain_type_str(source_element->domain));
2155 cmd_result = LTTNG_ERR_FATAL;
2156 goto end;
2157 }
2158
2159 /*
2160 * The drain_event_notifier_notification_pipe() call might have read
2161 * data from an fd that we received in event in the latest _poll_wait()
2162 * call. Make sure the thread call poll_wait() again to ensure we have
2163 * a clean state.
2164 */
2165 state->restart_poll = true;
2166
2167 end:
2168 free(source_element);
2169 *_cmd_result = cmd_result;
2170 return ret;
2171 }
2172
2173 static
2174 int condition_on_event_update_error_count(struct lttng_trigger *trigger)
2175 {
2176 int ret = 0;
2177 uint64_t error_count = 0;
2178 struct lttng_condition *condition;
2179 enum event_notifier_error_accounting_status status;
2180
2181 condition = lttng_trigger_get_condition(trigger);
2182 assert(lttng_condition_get_type(condition) ==
2183 LTTNG_CONDITION_TYPE_ON_EVENT);
2184
2185 status = event_notifier_error_accounting_get_count(trigger, &error_count);
2186 if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
2187 uid_t trigger_owner_uid;
2188 const char *trigger_name;
2189 const enum lttng_trigger_status trigger_status =
2190 lttng_trigger_get_owner_uid(
2191 trigger, &trigger_owner_uid);
2192
2193 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
2194 if (lttng_trigger_get_name(trigger, &trigger_name) != LTTNG_TRIGGER_STATUS_OK) {
2195 trigger_name = "(unnamed)";
2196 }
2197
2198 ERR("Failed to get event notifier error count of trigger for update: trigger owner = %d, trigger name = '%s'",
2199 trigger_owner_uid, trigger_name);
2200 ret = -1;
2201 }
2202
2203 lttng_condition_on_event_set_error_count(condition, error_count);
2204 return ret;
2205 }
2206
2207 int handle_notification_thread_remove_tracer_event_source_no_result(
2208 struct notification_thread_state *state,
2209 int tracer_event_source_fd)
2210 {
2211 int ret;
2212 enum lttng_error_code cmd_result;
2213
2214 ret = handle_notification_thread_command_remove_tracer_event_source(
2215 state, tracer_event_source_fd, &cmd_result);
2216 (void) cmd_result;
2217 return ret;
2218 }
2219
2220 static int handle_notification_thread_command_list_triggers(
2221 struct notification_thread_handle *handle,
2222 struct notification_thread_state *state,
2223 uid_t client_uid,
2224 struct lttng_triggers **triggers,
2225 enum lttng_error_code *_cmd_result)
2226 {
2227 int ret = 0;
2228 enum lttng_error_code cmd_result = LTTNG_OK;
2229 struct cds_lfht_iter iter;
2230 struct lttng_trigger_ht_element *trigger_ht_element;
2231 struct lttng_triggers *local_triggers = NULL;
2232 const struct lttng_credentials *creds;
2233
2234 rcu_read_lock();
2235
2236 local_triggers = lttng_triggers_create();
2237 if (!local_triggers) {
2238 /* Not a fatal error. */
2239 cmd_result = LTTNG_ERR_NOMEM;
2240 goto end;
2241 }
2242
2243 cds_lfht_for_each_entry(state->triggers_ht, &iter,
2244 trigger_ht_element, node) {
2245 /*
2246 * Only return the triggers to which the client has access.
2247 * The root user has visibility over all triggers.
2248 */
2249 creds = lttng_trigger_get_credentials(trigger_ht_element->trigger);
2250 if (client_uid != lttng_credentials_get_uid(creds) && client_uid != 0) {
2251 continue;
2252 }
2253
2254 if (lttng_trigger_needs_tracer_notifier(trigger_ht_element->trigger)) {
2255 ret = condition_on_event_update_error_count(
2256 trigger_ht_element->trigger);
2257 assert(!ret);
2258 }
2259
2260 ret = lttng_triggers_add(local_triggers,
2261 trigger_ht_element->trigger);
2262 if (ret < 0) {
2263 /* Not a fatal error. */
2264 ret = 0;
2265 cmd_result = LTTNG_ERR_NOMEM;
2266 goto end;
2267 }
2268 }
2269
2270 /* Transferring ownership to the caller. */
2271 *triggers = local_triggers;
2272 local_triggers = NULL;
2273
2274 end:
2275 rcu_read_unlock();
2276 lttng_triggers_destroy(local_triggers);
2277 *_cmd_result = cmd_result;
2278 return ret;
2279 }
2280
2281 static
2282 bool condition_is_supported(struct lttng_condition *condition)
2283 {
2284 bool is_supported;
2285
2286 switch (lttng_condition_get_type(condition)) {
2287 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
2288 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
2289 {
2290 int ret;
2291 enum lttng_domain_type domain;
2292
2293 ret = lttng_condition_buffer_usage_get_domain_type(condition,
2294 &domain);
2295 assert(ret == 0);
2296
2297 if (domain != LTTNG_DOMAIN_KERNEL) {
2298 is_supported = true;
2299 goto end;
2300 }
2301
2302 /*
2303 * Older kernel tracers don't expose the API to monitor their
2304 * buffers. Therefore, we reject triggers that require that
2305 * mechanism to be available to be evaluated.
2306 *
2307 * Assume unsupported on error.
2308 */
2309 is_supported = kernel_supports_ring_buffer_snapshot_sample_positions() == 1;
2310 break;
2311 }
2312 case LTTNG_CONDITION_TYPE_ON_EVENT:
2313 {
2314 const struct lttng_event_rule *event_rule;
2315 enum lttng_domain_type domain;
2316 const enum lttng_condition_status status =
2317 lttng_condition_on_event_get_rule(
2318 condition, &event_rule);
2319
2320 assert(status == LTTNG_CONDITION_STATUS_OK);
2321
2322 domain = lttng_event_rule_get_domain_type(event_rule);
2323 if (domain != LTTNG_DOMAIN_KERNEL) {
2324 is_supported = true;
2325 goto end;
2326 }
2327
2328 /*
2329 * Older kernel tracers can't emit notification. Therefore, we
2330 * reject triggers that require that mechanism to be available
2331 * to be evaluated.
2332 *
2333 * Assume unsupported on error.
2334 */
2335 is_supported = kernel_supports_event_notifiers() == 1;
2336 break;
2337 }
2338 default:
2339 is_supported = true;
2340 }
2341 end:
2342 return is_supported;
2343 }
2344
2345 /* Must be called with RCU read lock held. */
2346 static
2347 int bind_trigger_to_matching_session(struct lttng_trigger *trigger,
2348 struct notification_thread_state *state)
2349 {
2350 int ret = 0;
2351 const struct lttng_condition *condition;
2352 const char *session_name;
2353 struct lttng_session_trigger_list *trigger_list;
2354
2355 condition = lttng_trigger_get_const_condition(trigger);
2356 switch (lttng_condition_get_type(condition)) {
2357 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
2358 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
2359 {
2360 enum lttng_condition_status status;
2361
2362 status = lttng_condition_session_rotation_get_session_name(
2363 condition, &session_name);
2364 if (status != LTTNG_CONDITION_STATUS_OK) {
2365 ERR("[notification-thread] Failed to bind trigger to session: unable to get 'session_rotation' condition's session name");
2366 ret = -1;
2367 goto end;
2368 }
2369 break;
2370 }
2371 default:
2372 ret = -1;
2373 goto end;
2374 }
2375
2376 trigger_list = get_session_trigger_list(state, session_name);
2377 if (!trigger_list) {
2378 DBG("[notification-thread] Unable to bind trigger applying to session \"%s\" as it is not yet known to the notification system",
2379 session_name);
2380 goto end;
2381
2382 }
2383
2384 DBG("[notification-thread] Newly registered trigger bound to session \"%s\"",
2385 session_name);
2386 ret = lttng_session_trigger_list_add(trigger_list, trigger);
2387 end:
2388 return ret;
2389 }
2390
2391 /* Must be called with RCU read lock held. */
2392 static
2393 int bind_trigger_to_matching_channels(struct lttng_trigger *trigger,
2394 struct notification_thread_state *state)
2395 {
2396 int ret = 0;
2397 struct cds_lfht_node *node;
2398 struct cds_lfht_iter iter;
2399 struct channel_info *channel;
2400
2401 cds_lfht_for_each_entry(state->channels_ht, &iter, channel,
2402 channels_ht_node) {
2403 struct lttng_trigger_list_element *trigger_list_element;
2404 struct lttng_channel_trigger_list *trigger_list;
2405 struct cds_lfht_iter lookup_iter;
2406
2407 if (!trigger_applies_to_channel(trigger, channel)) {
2408 continue;
2409 }
2410
2411 cds_lfht_lookup(state->channel_triggers_ht,
2412 hash_channel_key(&channel->key),
2413 match_channel_trigger_list,
2414 &channel->key,
2415 &lookup_iter);
2416 node = cds_lfht_iter_get_node(&lookup_iter);
2417 assert(node);
2418 trigger_list = caa_container_of(node,
2419 struct lttng_channel_trigger_list,
2420 channel_triggers_ht_node);
2421
2422 trigger_list_element = zmalloc(sizeof(*trigger_list_element));
2423 if (!trigger_list_element) {
2424 ret = -1;
2425 goto end;
2426 }
2427 CDS_INIT_LIST_HEAD(&trigger_list_element->node);
2428 trigger_list_element->trigger = trigger;
2429 cds_list_add(&trigger_list_element->node, &trigger_list->list);
2430 DBG("[notification-thread] Newly registered trigger bound to channel \"%s\"",
2431 channel->name);
2432 }
2433 end:
2434 return ret;
2435 }
2436
2437 static
2438 bool is_trigger_action_notify(const struct lttng_trigger *trigger)
2439 {
2440 bool is_notify = false;
2441 unsigned int i, count;
2442 enum lttng_action_status action_status;
2443 const struct lttng_action *action =
2444 lttng_trigger_get_const_action(trigger);
2445 enum lttng_action_type action_type;
2446
2447 assert(action);
2448 action_type = lttng_action_get_type(action);
2449 if (action_type == LTTNG_ACTION_TYPE_NOTIFY) {
2450 is_notify = true;
2451 goto end;
2452 } else if (action_type != LTTNG_ACTION_TYPE_GROUP) {
2453 goto end;
2454 }
2455
2456 action_status = lttng_action_group_get_count(action, &count);
2457 assert(action_status == LTTNG_ACTION_STATUS_OK);
2458
2459 for (i = 0; i < count; i++) {
2460 const struct lttng_action *inner_action =
2461 lttng_action_group_get_at_index(
2462 action, i);
2463
2464 action_type = lttng_action_get_type(inner_action);
2465 if (action_type == LTTNG_ACTION_TYPE_NOTIFY) {
2466 is_notify = true;
2467 goto end;
2468 }
2469 }
2470
2471 end:
2472 return is_notify;
2473 }
2474
2475 static bool trigger_name_taken(struct notification_thread_state *state,
2476 const struct lttng_trigger *trigger)
2477 {
2478 struct cds_lfht_iter iter;
2479
2480 /*
2481 * No duplicata is allowed in the triggers_by_name_uid_ht.
2482 * The match is done against the trigger name and uid.
2483 */
2484 cds_lfht_lookup(state->triggers_by_name_uid_ht,
2485 hash_trigger_by_name_uid(trigger),
2486 match_trigger_by_name_uid,
2487 trigger,
2488 &iter);
2489 return !!cds_lfht_iter_get_node(&iter);
2490 }
2491
2492 static
2493 enum lttng_error_code generate_trigger_name(
2494 struct notification_thread_state *state,
2495 struct lttng_trigger *trigger, const char **name)
2496 {
2497 enum lttng_error_code ret_code = LTTNG_OK;
2498 bool taken = false;
2499 enum lttng_trigger_status status;
2500
2501 do {
2502 const int ret = lttng_trigger_generate_name(trigger,
2503 state->trigger_id.name_offset++);
2504 if (ret) {
2505 /* The only reason this can fail right now. */
2506 ret_code = LTTNG_ERR_NOMEM;
2507 break;
2508 }
2509
2510 status = lttng_trigger_get_name(trigger, name);
2511 assert(status == LTTNG_TRIGGER_STATUS_OK);
2512
2513 taken = trigger_name_taken(state, trigger);
2514 } while (taken || state->trigger_id.name_offset == UINT64_MAX);
2515
2516 return ret_code;
2517 }
2518
2519 static inline
2520 void notif_thread_state_remove_trigger_ht_elem(
2521 struct notification_thread_state *state,
2522 struct lttng_trigger_ht_element *trigger_ht_element)
2523 {
2524 assert(state);
2525 assert(trigger_ht_element);
2526
2527 cds_lfht_del(state->triggers_ht, &trigger_ht_element->node);
2528 cds_lfht_del(state->triggers_by_name_uid_ht, &trigger_ht_element->node_by_name_uid);
2529 }
2530
2531 static
2532 enum lttng_error_code setup_tracer_notifier(
2533 struct notification_thread_state *state,
2534 struct lttng_trigger *trigger)
2535 {
2536 enum lttng_error_code ret;
2537 enum event_notifier_error_accounting_status error_accounting_status;
2538 struct cds_lfht_node *node;
2539 uint64_t error_counter_index = 0;
2540 struct lttng_condition *condition = lttng_trigger_get_condition(trigger);
2541 struct notification_trigger_tokens_ht_element *trigger_tokens_ht_element = NULL;
2542
2543 trigger_tokens_ht_element = zmalloc(sizeof(*trigger_tokens_ht_element));
2544 if (!trigger_tokens_ht_element) {
2545 ret = LTTNG_ERR_NOMEM;
2546 goto end;
2547 }
2548
2549 /* Add trigger token to the trigger_tokens_ht. */
2550 cds_lfht_node_init(&trigger_tokens_ht_element->node);
2551 trigger_tokens_ht_element->token = LTTNG_OPTIONAL_GET(trigger->tracer_token);
2552 trigger_tokens_ht_element->trigger = trigger;
2553
2554 node = cds_lfht_add_unique(state->trigger_tokens_ht,
2555 hash_key_u64(&trigger_tokens_ht_element->token, lttng_ht_seed),
2556 match_trigger_token,
2557 &trigger_tokens_ht_element->token,
2558 &trigger_tokens_ht_element->node);
2559 if (node != &trigger_tokens_ht_element->node) {
2560 ret = LTTNG_ERR_TRIGGER_EXISTS;
2561 goto error_free_ht_element;
2562 }
2563
2564 error_accounting_status = event_notifier_error_accounting_register_event_notifier(
2565 trigger, &error_counter_index);
2566 if (error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
2567 if (error_accounting_status == EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_NO_INDEX_AVAILABLE) {
2568 DBG("Trigger group error accounting counter full.");
2569 ret = LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING_FULL;
2570 } else {
2571 ERR("Error registering trigger for error accounting");
2572 ret = LTTNG_ERR_EVENT_NOTIFIER_REGISTRATION;
2573 }
2574
2575 goto error_remove_ht_element;
2576 }
2577
2578 lttng_condition_on_event_set_error_counter_index(
2579 condition, error_counter_index);
2580
2581 ret = LTTNG_OK;
2582 goto end;
2583
2584 error_remove_ht_element:
2585 cds_lfht_del(state->trigger_tokens_ht, &trigger_tokens_ht_element->node);
2586 error_free_ht_element:
2587 free(trigger_tokens_ht_element);
2588 end:
2589 return ret;
2590 }
2591
2592 /*
2593 * FIXME A client's credentials are not checked when registering a trigger.
2594 *
2595 * The effects of this are benign since:
2596 * - The client will succeed in registering the trigger, as it is valid,
2597 * - The trigger will, internally, be bound to the channel/session,
2598 * - The notifications will not be sent since the client's credentials
2599 * are checked against the channel at that moment.
2600 *
2601 * If this function returns a non-zero value, it means something is
2602 * fundamentally broken and the whole subsystem/thread will be torn down.
2603 *
2604 * If a non-fatal error occurs, just set the cmd_result to the appropriate
2605 * error code.
2606 */
2607 static
2608 int handle_notification_thread_command_register_trigger(
2609 struct notification_thread_state *state,
2610 struct lttng_trigger *trigger,
2611 enum lttng_error_code *cmd_result)
2612 {
2613 int ret = 0;
2614 struct lttng_condition *condition;
2615 struct notification_client_list *client_list = NULL;
2616 struct lttng_trigger_ht_element *trigger_ht_element = NULL;
2617 struct cds_lfht_node *node;
2618 const char* trigger_name;
2619 bool free_trigger = true;
2620 struct lttng_evaluation *evaluation = NULL;
2621 struct lttng_credentials object_creds;
2622 uid_t object_uid;
2623 gid_t object_gid;
2624 enum action_executor_status executor_status;
2625 const uint64_t trigger_tracer_token =
2626 state->trigger_id.next_tracer_token++;
2627
2628 rcu_read_lock();
2629
2630 /* Set the trigger's tracer token. */
2631 lttng_trigger_set_tracer_token(trigger, trigger_tracer_token);
2632
2633 if (lttng_trigger_get_name(trigger, &trigger_name) ==
2634 LTTNG_TRIGGER_STATUS_UNSET) {
2635 const enum lttng_error_code ret_code = generate_trigger_name(
2636 state, trigger, &trigger_name);
2637
2638 if (ret_code != LTTNG_OK) {
2639 /* Fatal error. */
2640 ret = -1;
2641 *cmd_result = ret_code;
2642 goto error;
2643 }
2644 } else if (trigger_name_taken(state, trigger)) {
2645 /* Not a fatal error. */
2646 *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
2647 ret = 0;
2648 goto error;
2649 }
2650
2651 condition = lttng_trigger_get_condition(trigger);
2652 assert(condition);
2653
2654 /* Some conditions require tracers to implement a minimal ABI version. */
2655 if (!condition_is_supported(condition)) {
2656 *cmd_result = LTTNG_ERR_NOT_SUPPORTED;
2657 goto error;
2658 }
2659
2660 trigger_ht_element = zmalloc(sizeof(*trigger_ht_element));
2661 if (!trigger_ht_element) {
2662 ret = -1;
2663 goto error;
2664 }
2665
2666 /* Add trigger to the trigger_ht. */
2667 cds_lfht_node_init(&trigger_ht_element->node);
2668 cds_lfht_node_init(&trigger_ht_element->node_by_name_uid);
2669 trigger_ht_element->trigger = trigger;
2670
2671 node = cds_lfht_add_unique(state->triggers_ht,
2672 lttng_condition_hash(condition),
2673 match_trigger,
2674 trigger,
2675 &trigger_ht_element->node);
2676 if (node != &trigger_ht_element->node) {
2677 /* Not a fatal error, simply report it to the client. */
2678 *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
2679 goto error_free_ht_element;
2680 }
2681
2682 node = cds_lfht_add_unique(state->triggers_by_name_uid_ht,
2683 hash_trigger_by_name_uid(trigger),
2684 match_trigger_by_name_uid,
2685 trigger,
2686 &trigger_ht_element->node_by_name_uid);
2687 if (node != &trigger_ht_element->node_by_name_uid) {
2688 /* Not a fatal error, simply report it to the client. */
2689 cds_lfht_del(state->triggers_ht, &trigger_ht_element->node);
2690 *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
2691 goto error_free_ht_element;
2692 }
2693
2694 /*
2695 * Some triggers might need a tracer notifier depending on its
2696 * condition and actions.
2697 */
2698 if (lttng_trigger_needs_tracer_notifier(trigger)) {
2699 enum lttng_error_code error_code;
2700
2701 error_code = setup_tracer_notifier(state, trigger);
2702 if (error_code != LTTNG_OK) {
2703 notif_thread_state_remove_trigger_ht_elem(state,
2704 trigger_ht_element);
2705 if (error_code == LTTNG_ERR_NOMEM) {
2706 ret = -1;
2707 } else {
2708 *cmd_result = error_code;
2709 ret = 0;
2710 }
2711
2712 goto error_free_ht_element;
2713 }
2714 }
2715
2716 /*
2717 * The rest only applies to triggers that have a "notify" action.
2718 * It is not skipped as this is the only action type currently
2719 * supported.
2720 */
2721 if (is_trigger_action_notify(trigger)) {
2722 /*
2723 * Find or create the client list of this condition. It may
2724 * already be present if another trigger is already registered
2725 * with the same condition.
2726 */
2727 client_list = get_client_list_from_condition(state, condition);
2728 if (!client_list) {
2729 /*
2730 * No client list for this condition yet. We create new
2731 * one and build it up.
2732 */
2733 client_list = notification_client_list_create(state, condition);
2734 if (!client_list) {
2735 ERR("Error creating notification client list for trigger %s", trigger->name);
2736 goto error_free_ht_element;
2737 }
2738 }
2739
2740 CDS_INIT_LIST_HEAD(&trigger_ht_element->client_list_trigger_node);
2741
2742 pthread_mutex_lock(&client_list->lock);
2743 cds_list_add(&trigger_ht_element->client_list_trigger_node, &client_list->triggers_list);
2744 pthread_mutex_unlock(&client_list->lock);
2745 }
2746
2747 /*
2748 * Ownership of the trigger and of its wrapper was transfered to
2749 * the triggers_ht. Same for token ht element if necessary.
2750 */
2751 trigger_ht_element = NULL;
2752 free_trigger = false;
2753
2754 switch (get_condition_binding_object(condition)) {
2755 case LTTNG_OBJECT_TYPE_SESSION:
2756 /* Add the trigger to the list if it matches a known session. */
2757 ret = bind_trigger_to_matching_session(trigger, state);
2758 if (ret) {
2759 goto error_free_ht_element;
2760 }
2761 break;
2762 case LTTNG_OBJECT_TYPE_CHANNEL:
2763 /*
2764 * Add the trigger to list of triggers bound to the channels
2765 * currently known.
2766 */
2767 ret = bind_trigger_to_matching_channels(trigger, state);
2768 if (ret) {
2769 goto error_free_ht_element;
2770 }
2771 break;
2772 case LTTNG_OBJECT_TYPE_NONE:
2773 break;
2774 default:
2775 ERR("Unknown object type on which to bind a newly registered trigger was encountered");
2776 ret = -1;
2777 goto error_free_ht_element;
2778 }
2779
2780 /*
2781 * The new trigger's condition must be evaluated against the current
2782 * state.
2783 *
2784 * In the case of `notify` action, nothing preventing clients from
2785 * subscribing to a condition before the corresponding trigger is
2786 * registered, we have to evaluate this new condition right away.
2787 *
2788 * At some point, we were waiting for the next "evaluation" (e.g. on
2789 * reception of a channel sample) to evaluate this new condition, but
2790 * that was broken.
2791 *
2792 * The reason it was broken is that waiting for the next sample
2793 * does not allow us to properly handle transitions for edge-triggered
2794 * conditions.
2795 *
2796 * Consider this example: when we handle a new channel sample, we
2797 * evaluate each conditions twice: once with the previous state, and
2798 * again with the newest state. We then use those two results to
2799 * determine whether a state change happened: a condition was false and
2800 * became true. If a state change happened, we have to notify clients.
2801 *
2802 * Now, if a client subscribes to a given notification and registers
2803 * a trigger *after* that subscription, we have to make sure the
2804 * condition is evaluated at this point while considering only the
2805 * current state. Otherwise, the next evaluation cycle may only see
2806 * that the evaluations remain the same (true for samples n-1 and n) and
2807 * the client will never know that the condition has been met.
2808 */
2809 switch (get_condition_binding_object(condition)) {
2810 case LTTNG_OBJECT_TYPE_SESSION:
2811 ret = evaluate_session_condition_for_client(condition, state,
2812 &evaluation, &object_uid,
2813 &object_gid);
2814 LTTNG_OPTIONAL_SET(&object_creds.uid, object_uid);
2815 LTTNG_OPTIONAL_SET(&object_creds.gid, object_gid);
2816 break;
2817 case LTTNG_OBJECT_TYPE_CHANNEL:
2818 ret = evaluate_channel_condition_for_client(condition, state,
2819 &evaluation, &object_uid,
2820 &object_gid);
2821 LTTNG_OPTIONAL_SET(&object_creds.uid, object_uid);
2822 LTTNG_OPTIONAL_SET(&object_creds.gid, object_gid);
2823 break;
2824 case LTTNG_OBJECT_TYPE_NONE:
2825 ret = 0;
2826 break;
2827 case LTTNG_OBJECT_TYPE_UNKNOWN:
2828 default:
2829 ret = -1;
2830 break;
2831 }
2832
2833 if (ret) {
2834 /* Fatal error. */
2835 goto error_free_ht_element;
2836 }
2837
2838 DBG("Newly registered trigger's condition evaluated to %s",
2839 evaluation ? "true" : "false");
2840 if (!evaluation) {
2841 /* Evaluation yielded nothing. Normal exit. */
2842 ret = 0;
2843 goto success;
2844 }
2845
2846 /*
2847 * Ownership of `evaluation` transferred to the action executor
2848 * no matter the result.
2849 */
2850 executor_status = action_executor_enqueue(state->executor, trigger,
2851 evaluation, &object_creds, client_list);
2852 evaluation = NULL;
2853 switch (executor_status) {
2854 case ACTION_EXECUTOR_STATUS_OK:
2855 break;
2856 case ACTION_EXECUTOR_STATUS_ERROR:
2857 case ACTION_EXECUTOR_STATUS_INVALID:
2858 /*
2859 * TODO Add trigger identification (name/id) when
2860 * it is added to the API.
2861 */
2862 ERR("Fatal error occurred while enqueuing action associated to newly registered trigger");
2863 ret = -1;
2864 goto error_free_ht_element;
2865 case ACTION_EXECUTOR_STATUS_OVERFLOW:
2866 /*
2867 * TODO Add trigger identification (name/id) when
2868 * it is added to the API.
2869 *
2870 * Not a fatal error.
2871 */
2872 WARN("No space left when enqueuing action associated to newly registered trigger");
2873 ret = 0;
2874 goto success;
2875 default:
2876 abort();
2877 }
2878
2879 success:
2880 *cmd_result = LTTNG_OK;
2881 DBG("Registered trigger: name = `%s`, tracer token = %" PRIu64,
2882 trigger_name, trigger_tracer_token);
2883 goto end;
2884
2885 error_free_ht_element:
2886 if (trigger_ht_element) {
2887 /* Delayed removal due to RCU constraint on delete. */
2888 call_rcu(&trigger_ht_element->rcu_node,
2889 free_lttng_trigger_ht_element_rcu);
2890 }
2891 error:
2892 if (free_trigger) {
2893 lttng_trigger_destroy(trigger);
2894 }
2895 end:
2896 rcu_read_unlock();
2897 return ret;
2898 }
2899
2900 static
2901 void free_lttng_trigger_ht_element_rcu(struct rcu_head *node)
2902 {
2903 free(caa_container_of(node, struct lttng_trigger_ht_element,
2904 rcu_node));
2905 }
2906
2907 static
2908 void free_notification_trigger_tokens_ht_element_rcu(struct rcu_head *node)
2909 {
2910 free(caa_container_of(node, struct notification_trigger_tokens_ht_element,
2911 rcu_node));
2912 }
2913
2914 static
2915 void teardown_tracer_notifier(struct notification_thread_state *state,
2916 const struct lttng_trigger *trigger)
2917 {
2918 struct cds_lfht_iter iter;
2919 struct notification_trigger_tokens_ht_element *trigger_tokens_ht_element;
2920
2921 cds_lfht_for_each_entry(state->trigger_tokens_ht, &iter,
2922 trigger_tokens_ht_element, node) {
2923
2924 if (!lttng_trigger_is_equal(trigger,
2925 trigger_tokens_ht_element->trigger)) {
2926 continue;
2927 }
2928
2929 event_notifier_error_accounting_unregister_event_notifier(
2930 trigger_tokens_ht_element->trigger);
2931
2932 /* TODO talk to all app and remove it */
2933 DBG("[notification-thread] Removed trigger from tokens_ht");
2934 cds_lfht_del(state->trigger_tokens_ht,
2935 &trigger_tokens_ht_element->node);
2936
2937 call_rcu(&trigger_tokens_ht_element->rcu_node,
2938 free_notification_trigger_tokens_ht_element_rcu);
2939
2940 break;
2941 }
2942 }
2943
2944 static
2945 int handle_notification_thread_command_unregister_trigger(
2946 struct notification_thread_state *state,
2947 const struct lttng_trigger *trigger,
2948 enum lttng_error_code *_cmd_reply)
2949 {
2950 struct cds_lfht_iter iter;
2951 struct cds_lfht_node *triggers_ht_node;
2952 struct lttng_channel_trigger_list *trigger_list;
2953 struct notification_client_list *client_list;
2954 struct lttng_trigger_ht_element *trigger_ht_element = NULL;
2955 const struct lttng_condition *condition = lttng_trigger_get_const_condition(
2956 trigger);
2957 enum lttng_error_code cmd_reply;
2958
2959 rcu_read_lock();
2960
2961 cds_lfht_lookup(state->triggers_ht,
2962 lttng_condition_hash(condition),
2963 match_trigger,
2964 trigger,
2965 &iter);
2966 triggers_ht_node = cds_lfht_iter_get_node(&iter);
2967 if (!triggers_ht_node) {
2968 cmd_reply = LTTNG_ERR_TRIGGER_NOT_FOUND;
2969 goto end;
2970 } else {
2971 cmd_reply = LTTNG_OK;
2972 }
2973
2974 /* Remove trigger from channel_triggers_ht. */
2975 cds_lfht_for_each_entry(state->channel_triggers_ht, &iter, trigger_list,
2976 channel_triggers_ht_node) {
2977 struct lttng_trigger_list_element *trigger_element, *tmp;
2978
2979 cds_list_for_each_entry_safe(trigger_element, tmp,
2980 &trigger_list->list, node) {
2981 if (!lttng_trigger_is_equal(trigger, trigger_element->trigger)) {
2982 continue;
2983 }
2984
2985 DBG("[notification-thread] Removed trigger from channel_triggers_ht");
2986 cds_list_del(&trigger_element->node);
2987 /* A trigger can only appear once per channel */
2988 break;
2989 }
2990 }
2991
2992 if (lttng_trigger_needs_tracer_notifier(trigger)) {
2993 teardown_tracer_notifier(state, trigger);
2994 }
2995
2996 trigger_ht_element = caa_container_of(triggers_ht_node,
2997 struct lttng_trigger_ht_element, node);
2998
2999 if (is_trigger_action_notify(trigger)) {
3000 /*
3001 * Remove and release the client list from
3002 * notification_trigger_clients_ht.
3003 */
3004 client_list = get_client_list_from_condition(state, condition);
3005 assert(client_list);
3006
3007 pthread_mutex_lock(&client_list->lock);
3008 cds_list_del(&trigger_ht_element->client_list_trigger_node);
3009 pthread_mutex_unlock(&client_list->lock);
3010
3011 /* Put new reference and the hashtable's reference. */
3012 notification_client_list_put(client_list);
3013 notification_client_list_put(client_list);
3014 client_list = NULL;
3015 }
3016
3017 /* Remove trigger from triggers_ht. */
3018 notif_thread_state_remove_trigger_ht_elem(state, trigger_ht_element);
3019
3020 /* Release the ownership of the trigger. */
3021 lttng_trigger_destroy(trigger_ht_element->trigger);
3022 call_rcu(&trigger_ht_element->rcu_node, free_lttng_trigger_ht_element_rcu);
3023 end:
3024 rcu_read_unlock();
3025 if (_cmd_reply) {
3026 *_cmd_reply = cmd_reply;
3027 }
3028 return 0;
3029 }
3030
3031 /* Returns 0 on success, 1 on exit requested, negative value on error. */
3032 int handle_notification_thread_command(
3033 struct notification_thread_handle *handle,
3034 struct notification_thread_state *state)
3035 {
3036 int ret;
3037 uint64_t counter;
3038 struct notification_thread_command *cmd;
3039
3040 /* Read the event pipe to put it back into a quiescent state. */
3041 ret = lttng_read(lttng_pipe_get_readfd(handle->cmd_queue.event_pipe), &counter,
3042 sizeof(counter));
3043 if (ret != sizeof(counter)) {
3044 goto error;
3045 }
3046
3047 pthread_mutex_lock(&handle->cmd_queue.lock);
3048 cmd = cds_list_first_entry(&handle->cmd_queue.list,
3049 struct notification_thread_command, cmd_list_node);
3050 cds_list_del(&cmd->cmd_list_node);
3051 pthread_mutex_unlock(&handle->cmd_queue.lock);
3052
3053 DBG("[notification-thread] Received `%s` command",
3054 notification_command_type_str(cmd->type));
3055 switch (cmd->type) {
3056