2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
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>
15 #include <lttng/log-level-rule-internal.hpp>
16 #include <lttng/log-level-rule.h>
21 static bool is_log_level_rule_exactly_type(const struct lttng_log_level_rule
*rule
)
23 enum lttng_log_level_rule_type type
= lttng_log_level_rule_get_type(rule
);
25 return type
== LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
;
28 static bool is_log_level_rule_at_least_as_severe_type(const struct lttng_log_level_rule
*rule
)
30 enum lttng_log_level_rule_type type
= lttng_log_level_rule_get_type(rule
);
32 return type
== LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
;
35 enum lttng_log_level_rule_type
36 lttng_log_level_rule_get_type(const struct lttng_log_level_rule
*rule
)
38 return rule
? rule
->type
: LTTNG_LOG_LEVEL_RULE_TYPE_UNKNOWN
;
41 struct lttng_log_level_rule
*lttng_log_level_rule_exactly_create(int level
)
43 struct lttng_log_level_rule
*rule
= nullptr;
45 rule
= zmalloc
<lttng_log_level_rule
>();
50 rule
->type
= LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
;
57 enum lttng_log_level_rule_status
58 lttng_log_level_rule_exactly_get_level(const struct lttng_log_level_rule
*rule
, int *level
)
60 enum lttng_log_level_rule_status status
= LTTNG_LOG_LEVEL_RULE_STATUS_OK
;
62 if (!rule
|| !level
|| !is_log_level_rule_exactly_type(rule
)) {
63 status
= LTTNG_LOG_LEVEL_RULE_STATUS_INVALID
;
72 struct lttng_log_level_rule
*lttng_log_level_rule_at_least_as_severe_as_create(int level
)
74 struct lttng_log_level_rule
*rule
= nullptr;
76 rule
= zmalloc
<lttng_log_level_rule
>();
81 rule
->type
= LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
;
88 enum lttng_log_level_rule_status
89 lttng_log_level_rule_at_least_as_severe_as_get_level(const struct lttng_log_level_rule
*rule
,
92 enum lttng_log_level_rule_status status
= LTTNG_LOG_LEVEL_RULE_STATUS_OK
;
94 if (!rule
|| !level
|| !is_log_level_rule_at_least_as_severe_type(rule
)) {
95 status
= LTTNG_LOG_LEVEL_RULE_STATUS_INVALID
;
104 void lttng_log_level_rule_destroy(struct lttng_log_level_rule
*log_level_rule
)
106 free(log_level_rule
);
109 ssize_t
lttng_log_level_rule_create_from_payload(struct lttng_payload_view
*view
,
110 struct lttng_log_level_rule
**_rule
)
114 struct lttng_log_level_rule
*rule
= nullptr;
115 const struct lttng_log_level_rule_comm
*comm
=
116 (const struct lttng_log_level_rule_comm
*) view
->buffer
.data
;
118 offset
+= sizeof(*comm
);
125 if (view
->buffer
.size
< sizeof(*comm
)) {
130 switch (comm
->type
) {
131 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
132 rule
= lttng_log_level_rule_exactly_create((int) comm
->level
);
134 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
135 rule
= lttng_log_level_rule_at_least_as_severe_as_create((int) comm
->level
);
153 int lttng_log_level_rule_serialize(const struct lttng_log_level_rule
*rule
,
154 struct lttng_payload
*payload
)
157 struct lttng_log_level_rule_comm comm
;
164 comm
.type
= (int8_t) rule
->type
;
165 comm
.level
= (int32_t) rule
->level
;
167 DBG("Serializing log level rule of type %d", rule
->type
);
168 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &comm
, sizeof(comm
));
177 bool lttng_log_level_rule_is_equal(const struct lttng_log_level_rule
*a
,
178 const struct lttng_log_level_rule
*b
)
180 bool is_equal
= false;
182 if (a
== nullptr && b
== nullptr) {
188 if (a
== nullptr || b
== nullptr) {
199 if (a
->type
!= b
->type
) {
203 if (a
->level
!= b
->level
) {
213 struct lttng_log_level_rule
*lttng_log_level_rule_copy(const struct lttng_log_level_rule
*source
)
215 struct lttng_log_level_rule
*copy
= nullptr;
217 LTTNG_ASSERT(source
);
219 copy
= zmalloc
<lttng_log_level_rule
>();
224 copy
->type
= source
->type
;
225 copy
->level
= source
->level
;
230 void lttng_log_level_rule_to_loglevel(const struct lttng_log_level_rule
*log_level_rule
,
231 enum lttng_loglevel_type
*loglevel_type
,
234 LTTNG_ASSERT(log_level_rule
);
236 switch (log_level_rule
->type
) {
237 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
238 *loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
240 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
241 *loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
247 *loglevel_value
= log_level_rule
->level
;
250 unsigned long lttng_log_level_rule_hash(const struct lttng_log_level_rule
*log_level_rule
)
253 enum lttng_log_level_rule_status llr_status
;
255 enum lttng_log_level_rule_type type
;
257 LTTNG_ASSERT(log_level_rule
);
259 type
= lttng_log_level_rule_get_type(log_level_rule
);
262 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
264 lttng_log_level_rule_exactly_get_level(log_level_rule
, &log_level_value
);
266 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
267 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(log_level_rule
,
275 LTTNG_ASSERT(llr_status
== LTTNG_LOG_LEVEL_RULE_STATUS_OK
);
277 hash
= hash_key_ulong((void *) (unsigned long) type
, lttng_ht_seed
);
279 hash
^= hash_key_ulong((void *) (unsigned long) log_level_value
, lttng_ht_seed
);
284 enum lttng_error_code
lttng_log_level_rule_mi_serialize(const struct lttng_log_level_rule
*rule
,
285 struct mi_writer
*writer
)
288 enum lttng_error_code ret_code
;
289 enum lttng_log_level_rule_status status
;
290 const char *element_str
= nullptr;
294 LTTNG_ASSERT(writer
);
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
;
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
;
303 status
= lttng_log_level_rule_at_least_as_severe_as_get_level(rule
, &level
);
310 LTTNG_ASSERT(status
== LTTNG_LOG_LEVEL_RULE_STATUS_OK
);
312 /* Open log level rule element. */
313 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_log_level_rule
);
318 /* Log level rule type element. */
319 ret
= mi_lttng_writer_open_element(writer
, element_str
);
325 ret
= mi_lttng_writer_write_element_signed_int(
326 writer
, mi_lttng_element_log_level_rule_level
, level
);
331 /* Close log level rule type element. */
332 ret
= mi_lttng_writer_close_element(writer
);
337 /* Close log level rule element. */
338 ret
= mi_lttng_writer_close_element(writer
);
347 ret_code
= LTTNG_ERR_MI_IO_FAIL
;