event-rule: introduce event rule uprobe
[lttng-tools.git] / src / common / event-rule / event-rule.c
1 /*
2 * Copyright (C) 2019 Jonathan Rajotte
3 * <jonathan.rajotte-julien@efficios.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.1-only
6 *
7 */
8
9 #include <assert.h>
10 #include <common/error.h>
11 #include <common/macros.h>
12 #include <common/payload.h>
13 #include <common/payload-view.h>
14 #include <lttng/event-rule/event-rule-internal.h>
15 #include <lttng/event-rule/kprobe-internal.h>
16 #include <lttng/event-rule/syscall-internal.h>
17 #include <lttng/event-rule/uprobe-internal.h>
18 #include <stdbool.h>
19
20 enum lttng_event_rule_type lttng_event_rule_get_type(
21 const struct lttng_event_rule *event_rule)
22 {
23 return event_rule ? event_rule->type : LTTNG_EVENT_RULE_TYPE_UNKNOWN;
24 }
25
26 LTTNG_HIDDEN
27 enum lttng_domain_type lttng_event_rule_get_domain_type(
28 const struct lttng_event_rule *event_rule)
29 {
30 enum lttng_domain_type domain_type = LTTNG_DOMAIN_NONE;
31
32 switch (lttng_event_rule_get_type(event_rule)) {
33 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
34 /* TODO */
35 domain_type = LTTNG_DOMAIN_NONE;
36 break;
37 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
38 case LTTNG_EVENT_RULE_TYPE_KPROBE:
39 case LTTNG_EVENT_RULE_TYPE_KRETPROBE:
40 case LTTNG_EVENT_RULE_TYPE_UPROBE:
41 domain_type = LTTNG_DOMAIN_KERNEL;
42 break;
43 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
44 domain_type = LTTNG_DOMAIN_NONE;
45 break;
46 }
47
48 return domain_type;
49 }
50
51 static void lttng_event_rule_release(struct urcu_ref *ref)
52 {
53 struct lttng_event_rule *event_rule =
54 container_of(ref, typeof(*event_rule), ref);
55
56 assert(event_rule->destroy);
57 event_rule->destroy(event_rule);
58 }
59
60 void lttng_event_rule_destroy(struct lttng_event_rule *event_rule)
61 {
62 lttng_event_rule_put(event_rule);
63 }
64
65 LTTNG_HIDDEN
66 bool lttng_event_rule_validate(const struct lttng_event_rule *event_rule)
67 {
68 bool valid;
69
70 if (!event_rule) {
71 valid = false;
72 goto end;
73 }
74
75 if (!event_rule->validate) {
76 /* Sub-class guarantees that it can never be invalid. */
77 valid = true;
78 goto end;
79 }
80
81 valid = event_rule->validate(event_rule);
82 end:
83 return valid;
84 }
85
86 LTTNG_HIDDEN
87 int lttng_event_rule_serialize(const struct lttng_event_rule *event_rule,
88 struct lttng_payload *payload)
89 {
90 int ret;
91 struct lttng_event_rule_comm event_rule_comm = {};
92
93 if (!event_rule) {
94 ret = -1;
95 goto end;
96 }
97
98 event_rule_comm.event_rule_type = (int8_t) event_rule->type;
99
100 ret = lttng_dynamic_buffer_append(
101 &payload->buffer, &event_rule_comm, sizeof(event_rule_comm));
102 if (ret) {
103 goto end;
104 }
105
106 ret = event_rule->serialize(event_rule, payload);
107 if (ret) {
108 goto end;
109 }
110 end:
111 return ret;
112 }
113
114 LTTNG_HIDDEN
115 bool lttng_event_rule_is_equal(const struct lttng_event_rule *a,
116 const struct lttng_event_rule *b)
117 {
118 bool is_equal = false;
119
120 if (!a || !b) {
121 goto end;
122 }
123
124 if (a->type != b->type) {
125 goto end;
126 }
127
128 if (a == b) {
129 is_equal = true;
130 goto end;
131 }
132
133 is_equal = a->equal ? a->equal(a, b) : true;
134 end:
135 return is_equal;
136 }
137
138 LTTNG_HIDDEN
139 ssize_t lttng_event_rule_create_from_payload(
140 struct lttng_payload_view *view,
141 struct lttng_event_rule **event_rule)
142 {
143 ssize_t ret, consumed = 0;
144 const struct lttng_event_rule_comm *event_rule_comm;
145 event_rule_create_from_payload_cb create_from_payload = NULL;
146
147 if (!view || !event_rule) {
148 ret = -1;
149 goto end;
150 }
151
152 DBG("Deserializing event_rule from payload.");
153 event_rule_comm = (const struct lttng_event_rule_comm *) view->buffer.data;
154 consumed += sizeof(*event_rule_comm);
155
156 switch ((enum lttng_event_rule_type) event_rule_comm->event_rule_type) {
157 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
158 /* TODO */
159 break;
160 case LTTNG_EVENT_RULE_TYPE_KPROBE:
161 create_from_payload = lttng_event_rule_kprobe_create_from_payload;
162 break;
163 case LTTNG_EVENT_RULE_TYPE_KRETPROBE:
164 /* TODO */
165 break;
166 case LTTNG_EVENT_RULE_TYPE_UPROBE:
167 create_from_payload = lttng_event_rule_uprobe_create_from_payload;
168 break;
169 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
170 create_from_payload =
171 lttng_event_rule_syscall_create_from_payload;
172 break;
173 default:
174 ERR("Attempted to create event rule of unknown type (%i)",
175 (int) event_rule_comm->event_rule_type);
176 ret = -1;
177 goto end;
178 }
179
180 assert(create_from_payload);
181
182 {
183 struct lttng_payload_view child_view =
184 lttng_payload_view_from_view(
185 view, consumed, -1);
186
187 ret = create_from_payload(&child_view, event_rule);
188 if (ret < 0) {
189 goto end;
190 }
191
192 consumed += ret;
193 }
194
195 if (!lttng_event_rule_validate(*event_rule)) {
196 ret = -1;
197 goto end;
198 }
199
200 ret = consumed;
201 end:
202 return ret;
203 }
204
205 LTTNG_HIDDEN
206 void lttng_event_rule_init(struct lttng_event_rule *event_rule,
207 enum lttng_event_rule_type type)
208 {
209 urcu_ref_init(&event_rule->ref);
210 event_rule->type = type;
211 }
212
213 LTTNG_HIDDEN
214 bool lttng_event_rule_get(struct lttng_event_rule *event_rule)
215 {
216 return urcu_ref_get_unless_zero(&event_rule->ref);
217 }
218
219 LTTNG_HIDDEN
220 void lttng_event_rule_put(struct lttng_event_rule *event_rule)
221 {
222 if (!event_rule) {
223 return;
224 }
225
226 assert(event_rule->ref.refcount);
227 urcu_ref_put(&event_rule->ref, lttng_event_rule_release);
228 }
229
230 LTTNG_HIDDEN
231 enum lttng_error_code lttng_event_rule_generate_filter_bytecode(
232 struct lttng_event_rule *rule, uid_t uid, gid_t gid)
233 {
234 assert(rule->generate_filter_bytecode);
235 return rule->generate_filter_bytecode(rule, uid, gid);
236 }
237
238 LTTNG_HIDDEN
239 const char *lttng_event_rule_get_filter(const struct lttng_event_rule *rule)
240 {
241 assert(rule->get_filter);
242 return rule->get_filter(rule);
243 }
244
245 LTTNG_HIDDEN
246 const struct lttng_filter_bytecode *lttng_event_rule_get_filter_bytecode(
247 const struct lttng_event_rule *rule)
248 {
249 assert(rule->get_filter_bytecode);
250 return rule->get_filter_bytecode(rule);
251 }
252
253 LTTNG_HIDDEN
254 struct lttng_event_exclusion *lttng_event_rule_generate_exclusions(
255 const struct lttng_event_rule *rule)
256 {
257 assert(rule->generate_exclusions);
258 return rule->generate_exclusions(rule);
259 }
260
261 LTTNG_HIDDEN
262 const char *lttng_event_rule_type_str(enum lttng_event_rule_type type)
263 {
264 switch (type) {
265 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
266 return "unknown";
267 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
268 return "tracepoint";
269 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
270 return "syscall";
271 case LTTNG_EVENT_RULE_TYPE_KPROBE:
272 return "probe";
273 case LTTNG_EVENT_RULE_TYPE_KRETPROBE:
274 return "function";
275 case LTTNG_EVENT_RULE_TYPE_UPROBE:
276 return "userspace-probe";
277 default:
278 abort();
279 }
280 }
This page took 0.036172 seconds and 5 git commands to generate.