2 * Copyright (C) 2019 Jonathan Rajotte
3 * <jonathan.rajotte-julien@efficios.com>
5 * SPDX-License-Identifier: LGPL-2.1-only
10 #include <common/error.h>
11 #include <common/macros.h>
12 #include <common/payload.h>
13 #include <common/payload-view.h>
14 #include <common/hashtable/hashtable.h>
15 #include <common/hashtable/utils.h>
16 #include <lttng/event-rule/event-rule-internal.h>
17 #include <lttng/event-rule/kprobe-internal.h>
18 #include <lttng/event-rule/syscall-internal.h>
19 #include <lttng/event-rule/tracepoint-internal.h>
20 #include <lttng/event-rule/uprobe-internal.h>
23 enum lttng_event_rule_type
lttng_event_rule_get_type(
24 const struct lttng_event_rule
*event_rule
)
26 return event_rule
? event_rule
->type
: LTTNG_EVENT_RULE_TYPE_UNKNOWN
;
30 enum lttng_domain_type
lttng_event_rule_get_domain_type(
31 const struct lttng_event_rule
*event_rule
)
33 enum lttng_domain_type domain_type
= LTTNG_DOMAIN_NONE
;
35 switch (lttng_event_rule_get_type(event_rule
)) {
36 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
38 enum lttng_event_rule_status status
;
39 status
= lttng_event_rule_tracepoint_get_domain_type(event_rule
, &domain_type
);
40 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
);
43 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
44 case LTTNG_EVENT_RULE_TYPE_KPROBE
:
45 case LTTNG_EVENT_RULE_TYPE_KRETPROBE
:
46 case LTTNG_EVENT_RULE_TYPE_UPROBE
:
47 domain_type
= LTTNG_DOMAIN_KERNEL
;
49 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
50 domain_type
= LTTNG_DOMAIN_NONE
;
57 static void lttng_event_rule_release(struct urcu_ref
*ref
)
59 struct lttng_event_rule
*event_rule
=
60 container_of(ref
, typeof(*event_rule
), ref
);
62 assert(event_rule
->destroy
);
63 event_rule
->destroy(event_rule
);
66 void lttng_event_rule_destroy(struct lttng_event_rule
*event_rule
)
68 lttng_event_rule_put(event_rule
);
72 bool lttng_event_rule_validate(const struct lttng_event_rule
*event_rule
)
81 if (!event_rule
->validate
) {
82 /* Sub-class guarantees that it can never be invalid. */
87 valid
= event_rule
->validate(event_rule
);
93 int lttng_event_rule_serialize(const struct lttng_event_rule
*event_rule
,
94 struct lttng_payload
*payload
)
97 struct lttng_event_rule_comm event_rule_comm
= {};
104 event_rule_comm
.event_rule_type
= (int8_t) event_rule
->type
;
106 ret
= lttng_dynamic_buffer_append(
107 &payload
->buffer
, &event_rule_comm
, sizeof(event_rule_comm
));
112 ret
= event_rule
->serialize(event_rule
, payload
);
121 bool lttng_event_rule_is_equal(const struct lttng_event_rule
*a
,
122 const struct lttng_event_rule
*b
)
124 bool is_equal
= false;
130 if (a
->type
!= b
->type
) {
139 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
145 ssize_t
lttng_event_rule_create_from_payload(
146 struct lttng_payload_view
*view
,
147 struct lttng_event_rule
**event_rule
)
149 ssize_t ret
, consumed
= 0;
150 event_rule_create_from_payload_cb create_from_payload
= NULL
;
151 const struct lttng_event_rule_comm
*event_rule_comm
;
152 const struct lttng_payload_view event_rule_comm_view
=
153 lttng_payload_view_from_view(
154 view
, 0, sizeof(*event_rule_comm
));
156 if (!view
|| !event_rule
) {
161 if (!lttng_payload_view_is_valid(&event_rule_comm_view
)) {
166 DBG("Deserializing event_rule from payload");
167 event_rule_comm
= (const struct lttng_event_rule_comm
*) event_rule_comm_view
.buffer
.data
;
168 consumed
+= sizeof(*event_rule_comm
);
170 switch ((enum lttng_event_rule_type
) event_rule_comm
->event_rule_type
) {
171 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
172 create_from_payload
=
173 lttng_event_rule_tracepoint_create_from_payload
;
175 case LTTNG_EVENT_RULE_TYPE_KPROBE
:
176 create_from_payload
= lttng_event_rule_kprobe_create_from_payload
;
178 case LTTNG_EVENT_RULE_TYPE_KRETPROBE
:
181 case LTTNG_EVENT_RULE_TYPE_UPROBE
:
182 create_from_payload
= lttng_event_rule_uprobe_create_from_payload
;
184 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
185 create_from_payload
=
186 lttng_event_rule_syscall_create_from_payload
;
189 ERR("Attempted to create event rule of unknown type (%i)",
190 (int) event_rule_comm
->event_rule_type
);
195 assert(create_from_payload
);
198 struct lttng_payload_view child_view
=
199 lttng_payload_view_from_view(
202 ret
= create_from_payload(&child_view
, event_rule
);
210 if (!lttng_event_rule_validate(*event_rule
)) {
221 void lttng_event_rule_init(struct lttng_event_rule
*event_rule
,
222 enum lttng_event_rule_type type
)
224 urcu_ref_init(&event_rule
->ref
);
225 event_rule
->type
= type
;
229 bool lttng_event_rule_get(struct lttng_event_rule
*event_rule
)
231 return urcu_ref_get_unless_zero(&event_rule
->ref
);
235 void lttng_event_rule_put(struct lttng_event_rule
*event_rule
)
241 assert(event_rule
->ref
.refcount
);
242 urcu_ref_put(&event_rule
->ref
, lttng_event_rule_release
);
246 enum lttng_error_code
lttng_event_rule_generate_filter_bytecode(
247 struct lttng_event_rule
*rule
,
248 const struct lttng_credentials
*creds
)
250 assert(rule
->generate_filter_bytecode
);
251 return rule
->generate_filter_bytecode(rule
, creds
);
255 const char *lttng_event_rule_get_filter(const struct lttng_event_rule
*rule
)
257 assert(rule
->get_filter
);
258 return rule
->get_filter(rule
);
262 const struct lttng_filter_bytecode
*lttng_event_rule_get_filter_bytecode(
263 const struct lttng_event_rule
*rule
)
265 assert(rule
->get_filter_bytecode
);
266 return rule
->get_filter_bytecode(rule
);
270 struct lttng_event_exclusion
*lttng_event_rule_generate_exclusions(
271 const struct lttng_event_rule
*rule
)
273 assert(rule
->generate_exclusions
);
274 return rule
->generate_exclusions(rule
);
278 const char *lttng_event_rule_type_str(enum lttng_event_rule_type type
)
281 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
283 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
285 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
287 case LTTNG_EVENT_RULE_TYPE_KPROBE
:
289 case LTTNG_EVENT_RULE_TYPE_KRETPROBE
:
291 case LTTNG_EVENT_RULE_TYPE_UPROBE
:
292 return "userspace-probe";
299 unsigned long lttng_event_rule_hash(const struct lttng_event_rule
*rule
)
302 return rule
->hash(rule
);