Tests: Add test to check shared-memory FD leaks after relayd dies
[lttng-tools.git] / src / common / log-level-rule.cpp
CommitLineData
85b05318
JR
1/*
2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
c9e313bc
SM
8#include <common/dynamic-buffer.hpp>
9#include <common/error.hpp>
10#include <common/hashtable/hashtable.hpp>
11#include <common/hashtable/utils.hpp>
12#include <common/macros.hpp>
13#include <common/mi-lttng.hpp>
28ab034a 14
c9e313bc 15#include <lttng/log-level-rule-internal.hpp>
85b05318 16#include <lttng/log-level-rule.h>
28ab034a 17
85b05318
JR
18#include <stdbool.h>
19#include <stdlib.h>
20
21static bool is_log_level_rule_exactly_type(const struct lttng_log_level_rule *rule)
22{
28ab034a 23 enum lttng_log_level_rule_type type = lttng_log_level_rule_get_type(rule);
85b05318
JR
24
25 return type == LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY;
26}
27
28static bool is_log_level_rule_at_least_as_severe_type(const struct lttng_log_level_rule *rule)
29{
28ab034a 30 enum lttng_log_level_rule_type type = lttng_log_level_rule_get_type(rule);
85b05318
JR
31
32 return type == LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS;
33}
34
28ab034a
JG
35enum lttng_log_level_rule_type
36lttng_log_level_rule_get_type(const struct lttng_log_level_rule *rule)
85b05318
JR
37{
38 return rule ? rule->type : LTTNG_LOG_LEVEL_RULE_TYPE_UNKNOWN;
39}
40
28ab034a 41struct lttng_log_level_rule *lttng_log_level_rule_exactly_create(int level)
85b05318 42{
cd9adb8b 43 struct lttng_log_level_rule *rule = nullptr;
85b05318 44
64803277 45 rule = zmalloc<lttng_log_level_rule>();
85b05318
JR
46 if (!rule) {
47 goto end;
48 }
49
50 rule->type = LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY;
51 rule->level = level;
52
53end:
54 return rule;
55}
56
28ab034a
JG
57enum lttng_log_level_rule_status
58lttng_log_level_rule_exactly_get_level(const struct lttng_log_level_rule *rule, int *level)
85b05318 59{
28ab034a 60 enum lttng_log_level_rule_status status = LTTNG_LOG_LEVEL_RULE_STATUS_OK;
85b05318
JR
61
62 if (!rule || !level || !is_log_level_rule_exactly_type(rule)) {
63 status = LTTNG_LOG_LEVEL_RULE_STATUS_INVALID;
64 goto end;
65 }
66
67 *level = rule->level;
68end:
69 return status;
70}
71
28ab034a 72struct lttng_log_level_rule *lttng_log_level_rule_at_least_as_severe_as_create(int level)
85b05318 73{
cd9adb8b 74 struct lttng_log_level_rule *rule = nullptr;
85b05318 75
64803277 76 rule = zmalloc<lttng_log_level_rule>();
85b05318
JR
77 if (!rule) {
78 goto end;
79 }
80
81 rule->type = LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS;
82 rule->level = level;
83
84end:
85 return rule;
86}
87
88enum lttng_log_level_rule_status
28ab034a
JG
89lttng_log_level_rule_at_least_as_severe_as_get_level(const struct lttng_log_level_rule *rule,
90 int *level)
85b05318
JR
91{
92 enum lttng_log_level_rule_status status = LTTNG_LOG_LEVEL_RULE_STATUS_OK;
93
28ab034a 94 if (!rule || !level || !is_log_level_rule_at_least_as_severe_type(rule)) {
85b05318
JR
95 status = LTTNG_LOG_LEVEL_RULE_STATUS_INVALID;
96 goto end;
97 }
98
99 *level = rule->level;
100end:
101 return status;
102}
103
104void lttng_log_level_rule_destroy(struct lttng_log_level_rule *log_level_rule)
105{
106 free(log_level_rule);
107}
108
28ab034a
JG
109ssize_t lttng_log_level_rule_create_from_payload(struct lttng_payload_view *view,
110 struct lttng_log_level_rule **_rule)
85b05318
JR
111{
112 ssize_t ret;
113 size_t offset = 0;
cd9adb8b 114 struct lttng_log_level_rule *rule = nullptr;
85b05318 115 const struct lttng_log_level_rule_comm *comm =
28ab034a 116 (const struct lttng_log_level_rule_comm *) view->buffer.data;
85b05318
JR
117
118 offset += sizeof(*comm);
119
120 if (!_rule) {
121 ret = -1;
122 goto end;
123 }
124
125 if (view->buffer.size < sizeof(*comm)) {
126 ret = -1;
127 goto end;
128 }
129
130 switch (comm->type) {
131 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
132 rule = lttng_log_level_rule_exactly_create((int) comm->level);
133 break;
134 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
28ab034a 135 rule = lttng_log_level_rule_at_least_as_severe_as_create((int) comm->level);
85b05318
JR
136 break;
137 default:
138 abort();
139 }
140
141 if (!rule) {
142 ret = -1;
143 goto end;
144 }
145
146 *_rule = rule;
147 ret = offset;
148
149end:
150 return ret;
151}
152
85b05318 153int lttng_log_level_rule_serialize(const struct lttng_log_level_rule *rule,
28ab034a 154 struct lttng_payload *payload)
85b05318
JR
155{
156 int ret;
157 struct lttng_log_level_rule_comm comm;
158
85b05318
JR
159 if (!rule) {
160 ret = 0;
161 goto end;
162 }
163
164 comm.type = (int8_t) rule->type;
165 comm.level = (int32_t) rule->level;
166
167 DBG("Serializing log level rule of type %d", rule->type);
28ab034a 168 ret = lttng_dynamic_buffer_append(&payload->buffer, &comm, sizeof(comm));
85b05318
JR
169 if (ret) {
170 goto end;
171 }
172
173end:
174 return ret;
175}
176
85b05318 177bool lttng_log_level_rule_is_equal(const struct lttng_log_level_rule *a,
28ab034a 178 const struct lttng_log_level_rule *b)
85b05318
JR
179{
180 bool is_equal = false;
181
cd9adb8b 182 if (a == nullptr && b == nullptr) {
85b05318
JR
183 /* Both are null. */
184 is_equal = true;
185 goto end;
186 }
187
cd9adb8b 188 if (a == nullptr || b == nullptr) {
85b05318
JR
189 /* One is NULL.*/
190 goto end;
191 }
192
193 if (a == b) {
194 /* Same object.*/
195 is_equal = true;
196 goto end;
197 }
198
199 if (a->type != b->type) {
200 goto end;
201 }
202
203 if (a->level != b->level) {
204 goto end;
205 }
206
207 is_equal = true;
208
209end:
210 return is_equal;
211}
212
28ab034a 213struct lttng_log_level_rule *lttng_log_level_rule_copy(const struct lttng_log_level_rule *source)
85b05318 214{
cd9adb8b 215 struct lttng_log_level_rule *copy = nullptr;
85b05318 216
a0377dfe 217 LTTNG_ASSERT(source);
85b05318 218
64803277 219 copy = zmalloc<lttng_log_level_rule>();
85b05318
JR
220 if (!copy) {
221 goto end;
222 }
223
224 copy->type = source->type;
225 copy->level = source->level;
226end:
227 return copy;
228}
229
28ab034a
JG
230void lttng_log_level_rule_to_loglevel(const struct lttng_log_level_rule *log_level_rule,
231 enum lttng_loglevel_type *loglevel_type,
232 int *loglevel_value)
85b05318 233{
a0377dfe 234 LTTNG_ASSERT(log_level_rule);
85b05318
JR
235
236 switch (log_level_rule->type) {
237 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
238 *loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
239 break;
240 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
241 *loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
242 break;
243 default:
244 abort();
245 }
246
247 *loglevel_value = log_level_rule->level;
248}
249
28ab034a 250unsigned long lttng_log_level_rule_hash(const struct lttng_log_level_rule *log_level_rule)
85b05318
JR
251{
252 unsigned long hash;
253 enum lttng_log_level_rule_status llr_status;
254 int log_level_value;
255 enum lttng_log_level_rule_type type;
256
a0377dfe 257 LTTNG_ASSERT(log_level_rule);
85b05318
JR
258
259 type = lttng_log_level_rule_get_type(log_level_rule);
260
261 switch (type) {
262 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
28ab034a
JG
263 llr_status =
264 lttng_log_level_rule_exactly_get_level(log_level_rule, &log_level_value);
85b05318
JR
265 break;
266 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
28ab034a
JG
267 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(log_level_rule,
268 &log_level_value);
85b05318
JR
269 break;
270 default:
271 abort();
272 break;
273 }
274
a0377dfe 275 LTTNG_ASSERT(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
85b05318
JR
276
277 hash = hash_key_ulong((void *) (unsigned long) type, lttng_ht_seed);
278
28ab034a 279 hash ^= hash_key_ulong((void *) (unsigned long) log_level_value, lttng_ht_seed);
85b05318
JR
280
281 return hash;
282}
6a751b95 283
28ab034a
JG
284enum lttng_error_code lttng_log_level_rule_mi_serialize(const struct lttng_log_level_rule *rule,
285 struct mi_writer *writer)
6a751b95
JR
286{
287 int ret;
288 enum lttng_error_code ret_code;
289 enum lttng_log_level_rule_status status;
cd9adb8b 290 const char *element_str = nullptr;
6a751b95
JR
291 int level;
292
a0377dfe
FD
293 LTTNG_ASSERT(rule);
294 LTTNG_ASSERT(writer);
6a751b95
JR
295
296 switch (lttng_log_level_rule_get_type(rule)) {
297 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
298 status = lttng_log_level_rule_exactly_get_level(rule, &level);
299 element_str = mi_lttng_element_log_level_rule_exactly;
300 break;
301 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
302 element_str = mi_lttng_element_log_level_rule_at_least_as_severe_as;
28ab034a 303 status = lttng_log_level_rule_at_least_as_severe_as_get_level(rule, &level);
6a751b95
JR
304 break;
305 default:
306 abort();
307 break;
308 }
309
a0377dfe 310 LTTNG_ASSERT(status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
6a751b95
JR
311
312 /* Open log level rule element. */
28ab034a 313 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_log_level_rule);
6a751b95
JR
314 if (ret) {
315 goto mi_error;
316 }
317
318 /* Log level rule type element. */
319 ret = mi_lttng_writer_open_element(writer, element_str);
320 if (ret) {
321 goto mi_error;
322 }
323
324 /* Level. */
325 ret = mi_lttng_writer_write_element_signed_int(
28ab034a 326 writer, mi_lttng_element_log_level_rule_level, level);
6a751b95
JR
327 if (ret) {
328 goto mi_error;
329 }
330
331 /* Close log level rule type element. */
332 ret = mi_lttng_writer_close_element(writer);
333 if (ret) {
334 goto mi_error;
335 }
336
337 /* Close log level rule element. */
338 ret = mi_lttng_writer_close_element(writer);
339 if (ret) {
340 goto mi_error;
341 }
342
343 ret_code = LTTNG_OK;
344 goto end;
345
346mi_error:
347 ret_code = LTTNG_ERR_MI_IO_FAIL;
348end:
349 return ret_code;
350}
This page took 0.065187 seconds and 4 git commands to generate.