2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/buffer-view.h>
9 #include <common/dynamic-buffer.h>
10 #include <common/error.h>
11 #include <common/macros.h>
12 #include <common/mi-lttng.h>
13 #include <lttng/condition/buffer-usage-internal.h>
14 #include <lttng/condition/condition-internal.h>
15 #include <lttng/condition/event-rule-matches-internal.h>
16 #include <lttng/condition/session-consumed-size-internal.h>
17 #include <lttng/condition/session-rotation-internal.h>
18 #include <lttng/error-query-internal.h>
21 enum lttng_condition_type
lttng_condition_get_type(
22 const struct lttng_condition
*condition
)
24 return condition
? condition
->type
: LTTNG_CONDITION_TYPE_UNKNOWN
;
27 void lttng_condition_destroy(struct lttng_condition
*condition
)
29 lttng_condition_put(condition
);
32 static void condition_destroy_ref(struct urcu_ref
*ref
)
34 struct lttng_condition
*condition
=
35 container_of(ref
, struct lttng_condition
, ref
);
37 condition
->destroy(condition
);
41 void lttng_condition_get(struct lttng_condition
*condition
)
43 urcu_ref_get(&condition
->ref
);
47 void lttng_condition_put(struct lttng_condition
*condition
)
53 LTTNG_ASSERT(condition
->destroy
);
54 urcu_ref_put(&condition
->ref
, condition_destroy_ref
);
59 bool lttng_condition_validate(const struct lttng_condition
*condition
)
68 if (!condition
->validate
) {
69 /* Sub-class guarantees that it can never be invalid. */
74 valid
= condition
->validate(condition
);
80 int lttng_condition_serialize(const struct lttng_condition
*condition
,
81 struct lttng_payload
*payload
)
84 struct lttng_condition_comm condition_comm
= {};
91 condition_comm
.condition_type
= (int8_t) condition
->type
;
93 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &condition_comm
,
94 sizeof(condition_comm
));
99 ret
= condition
->serialize(condition
, payload
);
108 bool lttng_condition_is_equal(const struct lttng_condition
*a
,
109 const struct lttng_condition
*b
)
111 bool is_equal
= false;
117 if (a
->type
!= b
->type
) {
126 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
132 ssize_t
lttng_condition_create_from_payload(
133 struct lttng_payload_view
*view
,
134 struct lttng_condition
**condition
)
136 ssize_t ret
, condition_size
= 0;
137 condition_create_from_payload_cb create_from_payload
= NULL
;
138 const struct lttng_condition_comm
*condition_comm
;
139 const struct lttng_payload_view condition_comm_view
=
140 lttng_payload_view_from_view(
141 view
, 0, sizeof(*condition_comm
));
143 if (!view
|| !condition
) {
148 if (!lttng_payload_view_is_valid(&condition_comm_view
)) {
149 /* Payload not large enough to contain the header. */
154 DBG("Deserializing condition from buffer");
155 condition_comm
= (typeof(condition_comm
)) condition_comm_view
.buffer
.data
;
156 condition_size
+= sizeof(*condition_comm
);
158 switch ((enum lttng_condition_type
) condition_comm
->condition_type
) {
159 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
160 create_from_payload
= lttng_condition_buffer_usage_low_create_from_payload
;
162 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
163 create_from_payload
= lttng_condition_buffer_usage_high_create_from_payload
;
165 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
166 create_from_payload
= lttng_condition_session_consumed_size_create_from_payload
;
168 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
169 create_from_payload
= lttng_condition_session_rotation_ongoing_create_from_payload
;
171 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
172 create_from_payload
= lttng_condition_session_rotation_completed_create_from_payload
;
174 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
175 create_from_payload
=
176 lttng_condition_event_rule_matches_create_from_payload
;
179 ERR("Attempted to create condition of unknown type (%i)",
180 (int) condition_comm
->condition_type
);
185 if (create_from_payload
) {
186 struct lttng_payload_view condition_view
=
187 lttng_payload_view_from_view(view
,
188 sizeof(*condition_comm
), -1);
190 ret
= create_from_payload(&condition_view
, condition
);
194 condition_size
+= ret
;
200 ret
= condition_size
;
206 void lttng_condition_init(struct lttng_condition
*condition
,
207 enum lttng_condition_type type
)
209 condition
->type
= type
;
210 urcu_ref_init(&condition
->ref
);
214 const char *lttng_condition_type_str(enum lttng_condition_type type
)
217 case LTTNG_CONDITION_TYPE_UNKNOWN
:
220 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
221 return "session consumed size";
223 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
224 return "buffer usage high";
226 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
227 return "buffer usage low";
229 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
230 return "session rotation ongoing";
232 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
233 return "session rotation completed";
235 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
236 return "event rule matches";
244 enum lttng_error_code
lttng_condition_mi_serialize(
245 const struct lttng_trigger
*trigger
,
246 const struct lttng_condition
*condition
,
247 struct mi_writer
*writer
,
248 const struct mi_lttng_error_query_callbacks
*error_query_callbacks
)
251 enum lttng_error_code ret_code
;
252 struct lttng_error_query_results
*error_query_results
= NULL
;
254 LTTNG_ASSERT(condition
);
255 LTTNG_ASSERT(writer
);
256 LTTNG_ASSERT(condition
->mi_serialize
);
258 /* Open condition element. */
259 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_condition
);
264 /* Serialize underlying condition. */
265 ret_code
= condition
->mi_serialize(condition
, writer
);
266 if (ret_code
!= LTTNG_OK
) {
270 /* Serialize error query results for the action. */
271 if (error_query_callbacks
&& error_query_callbacks
->action_cb
) {
272 ret_code
= error_query_callbacks
->condition_cb(
273 trigger
, &error_query_results
);
274 if (ret_code
!= LTTNG_OK
) {
278 ret_code
= lttng_error_query_results_mi_serialize(
279 error_query_results
, writer
);
280 if (ret_code
!= LTTNG_OK
) {
285 /* Close condition element. */
286 ret
= mi_lttng_writer_close_element(writer
);
295 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
297 lttng_error_query_results_destroy(error_query_results
);