2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/dynamic-buffer.h>
10 #include <common/error.h>
11 #include <common/hashtable/hashtable.h>
12 #include <common/hashtable/utils.h>
13 #include <common/macros.h>
14 #include <common/mi-lttng.h>
15 #include <lttng/log-level-rule-internal.h>
16 #include <lttng/log-level-rule.h>
20 static bool is_log_level_rule_exactly_type(const struct lttng_log_level_rule
*rule
)
22 enum lttng_log_level_rule_type type
=
23 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
)
31 enum lttng_log_level_rule_type type
=
32 lttng_log_level_rule_get_type(rule
);
34 return type
== LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
;
37 enum lttng_log_level_rule_type
lttng_log_level_rule_get_type(
38 const struct lttng_log_level_rule
*rule
)
40 return rule
? rule
->type
: LTTNG_LOG_LEVEL_RULE_TYPE_UNKNOWN
;
43 struct lttng_log_level_rule
*lttng_log_level_rule_exactly_create(
46 struct lttng_log_level_rule
*rule
= NULL
;
48 rule
= zmalloc(sizeof(struct lttng_log_level_rule
));
53 rule
->type
= LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
;
60 enum lttng_log_level_rule_status
lttng_log_level_rule_exactly_get_level(
61 const struct lttng_log_level_rule
*rule
, int *level
)
63 enum lttng_log_level_rule_status status
=
64 LTTNG_LOG_LEVEL_RULE_STATUS_OK
;
66 if (!rule
|| !level
|| !is_log_level_rule_exactly_type(rule
)) {
67 status
= LTTNG_LOG_LEVEL_RULE_STATUS_INVALID
;
76 struct lttng_log_level_rule
*
77 lttng_log_level_rule_at_least_as_severe_as_create(int level
)
79 struct lttng_log_level_rule
*rule
= NULL
;
81 rule
= zmalloc(sizeof(struct lttng_log_level_rule
));
86 rule
->type
= LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
;
93 enum lttng_log_level_rule_status
94 lttng_log_level_rule_at_least_as_severe_as_get_level(
95 const struct lttng_log_level_rule
*rule
, int *level
)
97 enum lttng_log_level_rule_status status
= LTTNG_LOG_LEVEL_RULE_STATUS_OK
;
99 if (!rule
|| !level
||
100 !is_log_level_rule_at_least_as_severe_type(rule
)) {
101 status
= LTTNG_LOG_LEVEL_RULE_STATUS_INVALID
;
105 *level
= rule
->level
;
110 void lttng_log_level_rule_destroy(struct lttng_log_level_rule
*log_level_rule
)
112 free(log_level_rule
);
116 ssize_t
lttng_log_level_rule_create_from_payload(
117 struct lttng_payload_view
*view
,
118 struct lttng_log_level_rule
**_rule
)
122 struct lttng_log_level_rule
*rule
= NULL
;
123 const struct lttng_log_level_rule_comm
*comm
=
124 (const struct lttng_log_level_rule_comm
*)
127 offset
+= sizeof(*comm
);
134 if (view
->buffer
.size
< sizeof(*comm
)) {
139 switch (comm
->type
) {
140 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
141 rule
= lttng_log_level_rule_exactly_create((int) comm
->level
);
143 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
144 rule
= lttng_log_level_rule_at_least_as_severe_as_create(
164 int lttng_log_level_rule_serialize(const struct lttng_log_level_rule
*rule
,
165 struct lttng_payload
*payload
)
168 struct lttng_log_level_rule_comm comm
;
176 comm
.type
= (int8_t) rule
->type
;
177 comm
.level
= (int32_t) rule
->level
;
179 DBG("Serializing log level rule of type %d", rule
->type
);
180 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &comm
,
191 bool lttng_log_level_rule_is_equal(const struct lttng_log_level_rule
*a
,
192 const struct lttng_log_level_rule
*b
)
194 bool is_equal
= false;
196 if (a
== NULL
&& b
== NULL
) {
202 if (a
== NULL
|| b
== NULL
) {
213 if (a
->type
!= b
->type
) {
217 if (a
->level
!= b
->level
) {
228 struct lttng_log_level_rule
*lttng_log_level_rule_copy(
229 const struct lttng_log_level_rule
*source
)
231 struct lttng_log_level_rule
*copy
= NULL
;
235 copy
= zmalloc(sizeof(struct lttng_log_level_rule
));
240 copy
->type
= source
->type
;
241 copy
->level
= source
->level
;
247 void lttng_log_level_rule_to_loglevel(
248 const struct lttng_log_level_rule
*log_level_rule
,
249 enum lttng_loglevel_type
*loglevel_type
,
252 assert(log_level_rule
);
254 switch (log_level_rule
->type
) {
255 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
256 *loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
258 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
259 *loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
265 *loglevel_value
= log_level_rule
->level
;
269 unsigned long lttng_log_level_rule_hash(
270 const struct lttng_log_level_rule
*log_level_rule
)
273 enum lttng_log_level_rule_status llr_status
;
275 enum lttng_log_level_rule_type type
;
277 assert(log_level_rule
);
279 type
= lttng_log_level_rule_get_type(log_level_rule
);
282 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
283 llr_status
= lttng_log_level_rule_exactly_get_level(
284 log_level_rule
, &log_level_value
);
286 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
287 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
288 log_level_rule
, &log_level_value
);
295 assert(llr_status
== LTTNG_LOG_LEVEL_RULE_STATUS_OK
);
297 hash
= hash_key_ulong((void *) (unsigned long) type
, lttng_ht_seed
);
299 hash
^= hash_key_ulong((void *) (unsigned long) log_level_value
,
306 enum lttng_error_code
lttng_log_level_rule_mi_serialize(
307 const struct lttng_log_level_rule
*rule
,
308 struct mi_writer
*writer
)
311 enum lttng_error_code ret_code
;
312 enum lttng_log_level_rule_status status
;
313 const char *element_str
= NULL
;
319 switch (lttng_log_level_rule_get_type(rule
)) {
320 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
321 status
= lttng_log_level_rule_exactly_get_level(rule
, &level
);
322 element_str
= mi_lttng_element_log_level_rule_exactly
;
324 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
325 element_str
= mi_lttng_element_log_level_rule_at_least_as_severe_as
;
326 status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
334 assert(status
== LTTNG_LOG_LEVEL_RULE_STATUS_OK
);
336 /* Open log level rule element. */
337 ret
= mi_lttng_writer_open_element(
338 writer
, mi_lttng_element_log_level_rule
);
343 /* Log level rule type element. */
344 ret
= mi_lttng_writer_open_element(writer
, element_str
);
350 ret
= mi_lttng_writer_write_element_signed_int(
351 writer
, mi_lttng_element_log_level_rule_level
, level
);
356 /* Close log level rule type element. */
357 ret
= mi_lttng_writer_close_element(writer
);
362 /* Close log level rule element. */
363 ret
= mi_lttng_writer_close_element(writer
);
372 ret_code
= LTTNG_ERR_MI_IO_FAIL
;