sessiond: add support for anonymous triggers
[lttng-tools.git] / src / bin / lttng-sessiond / condition-internal.c
1 /*
2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <common/hashtable/utils.h>
9 #include <common/hashtable/hashtable.h>
10
11 #include <lttng/condition/condition.h>
12 #include <lttng/condition/condition-internal.h>
13 #include <lttng/condition/buffer-usage-internal.h>
14 #include <lttng/condition/session-consumed-size-internal.h>
15 #include <lttng/condition/session-rotation-internal.h>
16 #include <lttng/condition/event-rule-matches-internal.h>
17 #include <lttng/condition/event-rule-matches.h>
18 #include <lttng/event-rule/event-rule-internal.h>
19 #include <lttng/condition/event-rule-matches-internal.h>
20 #include "condition-internal.h"
21
22 static
23 unsigned long lttng_condition_buffer_usage_hash(
24 const struct lttng_condition *_condition)
25 {
26 unsigned long hash;
27 unsigned long condition_type;
28 struct lttng_condition_buffer_usage *condition;
29
30 condition = container_of(_condition,
31 struct lttng_condition_buffer_usage, parent);
32
33 condition_type = (unsigned long) condition->parent.type;
34 hash = hash_key_ulong((void *) condition_type, lttng_ht_seed);
35 if (condition->session_name) {
36 hash ^= hash_key_str(condition->session_name, lttng_ht_seed);
37 }
38 if (condition->channel_name) {
39 hash ^= hash_key_str(condition->channel_name, lttng_ht_seed);
40 }
41 if (condition->domain.set) {
42 hash ^= hash_key_ulong(
43 (void *) condition->domain.type,
44 lttng_ht_seed);
45 }
46 if (condition->threshold_ratio.set) {
47 uint64_t val;
48
49 val = condition->threshold_ratio.value * (double) UINT32_MAX;
50 hash ^= hash_key_u64(&val, lttng_ht_seed);
51 } else if (condition->threshold_bytes.set) {
52 uint64_t val;
53
54 val = condition->threshold_bytes.value;
55 hash ^= hash_key_u64(&val, lttng_ht_seed);
56 }
57 return hash;
58 }
59
60 static
61 unsigned long lttng_condition_session_consumed_size_hash(
62 const struct lttng_condition *_condition)
63 {
64 unsigned long hash;
65 unsigned long condition_type =
66 (unsigned long) LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE;
67 struct lttng_condition_session_consumed_size *condition;
68 uint64_t val;
69
70 condition = container_of(_condition,
71 struct lttng_condition_session_consumed_size, parent);
72
73 hash = hash_key_ulong((void *) condition_type, lttng_ht_seed);
74 if (condition->session_name) {
75 hash ^= hash_key_str(condition->session_name, lttng_ht_seed);
76 }
77 val = condition->consumed_threshold_bytes.value;
78 hash ^= hash_key_u64(&val, lttng_ht_seed);
79 return hash;
80 }
81
82 static
83 unsigned long lttng_condition_session_rotation_hash(
84 const struct lttng_condition *_condition)
85 {
86 unsigned long hash, condition_type;
87 struct lttng_condition_session_rotation *condition;
88
89 condition = container_of(_condition,
90 struct lttng_condition_session_rotation, parent);
91 condition_type = (unsigned long) condition->parent.type;
92 hash = hash_key_ulong((void *) condition_type, lttng_ht_seed);
93 assert(condition->session_name);
94 hash ^= hash_key_str(condition->session_name, lttng_ht_seed);
95 return hash;
96 }
97
98 static unsigned long lttng_condition_event_rule_matches_hash(
99 const struct lttng_condition *condition)
100 {
101 unsigned long hash, condition_type;
102 enum lttng_condition_status condition_status;
103 const struct lttng_event_rule *event_rule;
104
105 condition_type = (unsigned long) condition->type;
106 condition_status = lttng_condition_event_rule_matches_get_rule(
107 condition, &event_rule);
108 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
109
110 hash = hash_key_ulong((void *) condition_type, lttng_ht_seed);
111 return hash ^ lttng_event_rule_hash(event_rule);
112 }
113
114 /*
115 * The lttng_condition hashing code is kept in this file (rather than
116 * condition.c) since it makes use of GPLv2 code (hashtable utils), which we
117 * don't want to link in liblttng-ctl.
118 */
119 unsigned long lttng_condition_hash(const struct lttng_condition *condition)
120 {
121 switch (condition->type) {
122 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
123 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
124 return lttng_condition_buffer_usage_hash(condition);
125 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
126 return lttng_condition_session_consumed_size_hash(condition);
127 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
128 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
129 return lttng_condition_session_rotation_hash(condition);
130 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
131 return lttng_condition_event_rule_matches_hash(condition);
132 default:
133 //ERR("[notification-thread] Unexpected condition type caught");
134 abort();
135 }
136 }
137
138 LTTNG_HIDDEN
139 struct lttng_condition *lttng_condition_copy(const struct lttng_condition *condition)
140 {
141 int ret;
142 struct lttng_payload copy_buffer;
143 struct lttng_condition *copy = NULL;
144
145 lttng_payload_init(&copy_buffer);
146
147 ret = lttng_condition_serialize(condition, &copy_buffer);
148 if (ret < 0) {
149 goto end;
150 }
151
152 {
153 struct lttng_payload_view view =
154 lttng_payload_view_from_payload(
155 &copy_buffer, 0, -1);
156
157 ret = lttng_condition_create_from_payload(
158 &view, &copy);
159 if (ret < 0) {
160 copy = NULL;
161 goto end;
162 }
163 }
164
165 end:
166 lttng_payload_reset(&copy_buffer);
167 return copy;
168 }
This page took 0.031868 seconds and 4 git commands to generate.