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