Commit | Line | Data |
---|---|---|
b579acd9 DG |
1 | /* |
2 | * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca> | |
3 | * | |
1e307fab DG |
4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the Free | |
6 | * Software Foundation; only version 2 of the License. | |
b579acd9 | 7 | * |
1e307fab DG |
8 | * This program is distributed in the hope that it will be useful, but WITHOUT |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
11 | * more details. | |
b579acd9 | 12 | * |
1e307fab DG |
13 | * You should have received a copy of the GNU General Public License along with |
14 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | |
15 | * Place - Suite 330, Boston, MA 02111-1307, USA. | |
b579acd9 DG |
16 | */ |
17 | ||
18 | #define _GNU_SOURCE | |
19 | #include <stdio.h> | |
20 | #include <stdlib.h> | |
21 | #include <string.h> | |
22 | #include <unistd.h> | |
54d01ffb | 23 | #include <urcu/list.h> |
1e307fab DG |
24 | |
25 | #include <lttng-sessiond-comm.h> | |
54d01ffb | 26 | #include <lttngerr.h> |
b579acd9 | 27 | |
2bdd86d4 MD |
28 | #ifdef CONFIG_LTTNG_TOOLS_HAVE_UST |
29 | #include <ust/lttng-ust-ctl.h> | |
30 | #include <ust/lttng-ust-abi.h> | |
31 | #else | |
32 | #include "lttng-ust-ctl.h" | |
33 | #include "lttng-ust-abi.h" | |
34 | #endif | |
35 | ||
b579acd9 | 36 | #include "context.h" |
48842b30 | 37 | #include "hashtable.h" |
1e307fab | 38 | #include "kernel-ctl.h" |
b579acd9 DG |
39 | |
40 | /* | |
41 | * Add kernel context to an event of a specific channel. | |
42 | */ | |
43 | static int add_kctx_to_event(struct lttng_kernel_context *kctx, | |
44 | struct ltt_kernel_channel *kchan, char *event_name) | |
45 | { | |
46 | int ret, found = 0; | |
47 | struct ltt_kernel_event *kevent; | |
48 | ||
49 | DBG("Add kernel context to event %s", event_name); | |
50 | ||
62499ad6 | 51 | kevent = trace_kernel_get_event_by_name(event_name, kchan); |
b579acd9 DG |
52 | if (kevent != NULL) { |
53 | ret = kernel_add_event_context(kevent, kctx); | |
54 | if (ret < 0) { | |
55 | goto error; | |
56 | } | |
57 | found = 1; | |
58 | } | |
59 | ||
60 | ret = found; | |
61 | ||
62 | error: | |
63 | return ret; | |
64 | } | |
65 | ||
66 | /* | |
67 | * Add kernel context to all channel. | |
68 | * | |
69 | * If event_name is specified, add context to event instead. | |
70 | */ | |
71 | static int add_kctx_all_channels(struct ltt_kernel_session *ksession, | |
72 | struct lttng_kernel_context *kctx, char *event_name) | |
73 | { | |
74 | int ret, no_event = 0, found = 0; | |
75 | struct ltt_kernel_channel *kchan; | |
76 | ||
77 | if (strlen(event_name) == 0) { | |
78 | no_event = 1; | |
79 | } | |
80 | ||
81 | DBG("Adding kernel context to all channels (event: %s)", event_name); | |
82 | ||
83 | /* Go over all channels */ | |
84 | cds_list_for_each_entry(kchan, &ksession->channel_list.head, list) { | |
85 | if (no_event) { | |
86 | ret = kernel_add_channel_context(kchan, kctx); | |
87 | if (ret < 0) { | |
88 | ret = LTTCOMM_KERN_CONTEXT_FAIL; | |
89 | goto error; | |
90 | } | |
91 | } else { | |
92 | ret = add_kctx_to_event(kctx, kchan, event_name); | |
93 | if (ret < 0) { | |
94 | ret = LTTCOMM_KERN_CONTEXT_FAIL; | |
95 | goto error; | |
96 | } else if (ret == 1) { | |
97 | /* Event found and context added */ | |
98 | found = 1; | |
99 | break; | |
100 | } | |
101 | } | |
102 | } | |
103 | ||
104 | if (!found && !no_event) { | |
105 | ret = LTTCOMM_NO_EVENT; | |
106 | goto error; | |
107 | } | |
108 | ||
109 | ret = LTTCOMM_OK; | |
110 | ||
111 | error: | |
112 | return ret; | |
113 | } | |
114 | ||
115 | /* | |
116 | * Add kernel context to a specific channel. | |
117 | * | |
118 | * If event_name is specified, add context to that event. | |
119 | */ | |
120 | static int add_kctx_to_channel(struct lttng_kernel_context *kctx, | |
121 | struct ltt_kernel_channel *kchan, char *event_name) | |
122 | { | |
123 | int ret, no_event = 0, found = 0; | |
124 | ||
125 | if (strlen(event_name) == 0) { | |
126 | no_event = 1; | |
127 | } | |
128 | ||
129 | DBG("Add kernel context to channel '%s', event '%s'", | |
130 | kchan->channel->name, event_name); | |
131 | ||
132 | if (no_event) { | |
133 | ret = kernel_add_channel_context(kchan, kctx); | |
134 | if (ret < 0) { | |
135 | ret = LTTCOMM_KERN_CONTEXT_FAIL; | |
136 | goto error; | |
137 | } | |
138 | } else { | |
139 | ret = add_kctx_to_event(kctx, kchan, event_name); | |
140 | if (ret < 0) { | |
141 | ret = LTTCOMM_KERN_CONTEXT_FAIL; | |
142 | goto error; | |
143 | } else if (ret == 1) { | |
144 | /* Event found and context added */ | |
145 | found = 1; | |
146 | } | |
147 | } | |
148 | ||
149 | if (!found && !no_event) { | |
150 | ret = LTTCOMM_NO_EVENT; | |
151 | goto error; | |
152 | } | |
153 | ||
154 | ret = LTTCOMM_OK; | |
155 | ||
156 | error: | |
157 | return ret; | |
158 | } | |
159 | ||
160 | /* | |
161 | * Add kernel context to tracer. | |
162 | */ | |
54d01ffb DG |
163 | int context_kernel_add(struct ltt_kernel_session *ksession, |
164 | struct lttng_event_context *ctx, char *event_name, | |
b579acd9 DG |
165 | char *channel_name) |
166 | { | |
167 | int ret; | |
168 | struct ltt_kernel_channel *kchan; | |
54d01ffb DG |
169 | struct lttng_kernel_context kctx; |
170 | ||
171 | /* Setup kernel context structure */ | |
172 | kctx.ctx = ctx->ctx; | |
173 | kctx.u.perf_counter.type = ctx->u.perf_counter.type; | |
174 | kctx.u.perf_counter.config = ctx->u.perf_counter.config; | |
175 | strncpy(kctx.u.perf_counter.name, ctx->u.perf_counter.name, | |
176 | LTTNG_SYMBOL_NAME_LEN); | |
177 | kctx.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; | |
b579acd9 DG |
178 | |
179 | if (strlen(channel_name) == 0) { | |
54d01ffb | 180 | ret = add_kctx_all_channels(ksession, &kctx, event_name); |
b579acd9 DG |
181 | if (ret != LTTCOMM_OK) { |
182 | goto error; | |
183 | } | |
184 | } else { | |
185 | /* Get kernel channel */ | |
62499ad6 | 186 | kchan = trace_kernel_get_channel_by_name(channel_name, ksession); |
b579acd9 DG |
187 | if (kchan == NULL) { |
188 | ret = LTTCOMM_KERN_CHAN_NOT_FOUND; | |
189 | goto error; | |
190 | } | |
191 | ||
54d01ffb | 192 | ret = add_kctx_to_channel(&kctx, kchan, event_name); |
b579acd9 DG |
193 | if (ret != LTTCOMM_OK) { |
194 | goto error; | |
195 | } | |
196 | } | |
197 | ||
198 | ret = LTTCOMM_OK; | |
199 | ||
200 | error: | |
201 | return ret; | |
202 | } | |
2bdd86d4 MD |
203 | |
204 | /* | |
205 | * UST support. | |
206 | */ | |
207 | ||
208 | /* | |
209 | * Add UST context to an event of a specific channel. | |
210 | */ | |
48842b30 | 211 | #ifdef DISABLE |
2bdd86d4 MD |
212 | static int add_ustctx_to_event(struct ltt_ust_session *ustsession, |
213 | struct lttng_ust_context *ustctx, | |
214 | struct ltt_ust_channel *ustchan, char *event_name) | |
215 | { | |
216 | int ret, found = 0; | |
217 | struct ltt_ust_event *ustevent; | |
218 | struct object_data *context_data; /* FIXME: currently a memleak */ | |
219 | ||
220 | DBG("Add UST context to event %s", event_name); | |
221 | ||
48842b30 | 222 | ustevent = trace_ust_find_event_by_name(ustchan->events, event_name); |
2bdd86d4 MD |
223 | if (ustevent != NULL) { |
224 | ret = ustctl_add_context(ustsession->sock, ustctx, | |
225 | ustevent->obj, &context_data); | |
226 | if (ret < 0) { | |
227 | goto error; | |
228 | } | |
229 | found = 1; | |
230 | } | |
231 | ||
232 | ret = found; | |
233 | ||
234 | error: | |
235 | return ret; | |
236 | } | |
48842b30 | 237 | #endif |
2bdd86d4 MD |
238 | |
239 | /* | |
240 | * Add UST context to all channel. | |
241 | * | |
242 | * If event_name is specified, add context to event instead. | |
243 | */ | |
244 | static int add_ustctx_all_channels(struct ltt_ust_session *ustsession, | |
48842b30 DG |
245 | struct lttng_ust_context *ustctx, char *event_name, |
246 | struct cds_lfht *channels) | |
2bdd86d4 | 247 | { |
48842b30 | 248 | #ifdef DISABLE |
2bdd86d4 MD |
249 | int ret, no_event = 0, found = 0; |
250 | struct ltt_ust_channel *ustchan; | |
251 | struct object_data *context_data; /* FIXME: currently a memleak */ | |
252 | ||
253 | if (strlen(event_name) == 0) { | |
254 | no_event = 1; | |
255 | } | |
256 | ||
257 | DBG("Adding ust context to all channels (event: %s)", event_name); | |
258 | ||
48842b30 DG |
259 | struct cds_lfht_node *node; |
260 | struct cds_lfht_iter iter; | |
261 | ||
262 | rcu_read_lock(); | |
263 | hashtable_get_first(channels, &iter); | |
264 | while ((node = hashtable_iter_get_node(&iter)) != NULL) { | |
265 | ustchan = caa_container_of(node, struct ltt_ust_channel, node); | |
2bdd86d4 | 266 | if (no_event) { |
48842b30 DG |
267 | //ret = ustctl_add_context(ustsession->sock, |
268 | // ustctx, ustchan->obj, &context_data); | |
2bdd86d4 MD |
269 | if (ret < 0) { |
270 | ret = LTTCOMM_UST_CONTEXT_FAIL; | |
271 | goto error; | |
272 | } | |
273 | } else { | |
274 | ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name); | |
275 | if (ret < 0) { | |
276 | ret = LTTCOMM_UST_CONTEXT_FAIL; | |
277 | goto error; | |
278 | } else if (ret == 1) { | |
279 | /* Event found and context added */ | |
280 | found = 1; | |
281 | break; | |
282 | } | |
283 | } | |
48842b30 | 284 | hashtable_get_next(channels, &iter); |
2bdd86d4 | 285 | } |
48842b30 | 286 | rcu_read_unlock(); |
2bdd86d4 MD |
287 | |
288 | if (!found && !no_event) { | |
289 | ret = LTTCOMM_NO_EVENT; | |
290 | goto error; | |
291 | } | |
292 | ||
293 | ret = LTTCOMM_OK; | |
294 | ||
295 | error: | |
296 | return ret; | |
48842b30 DG |
297 | #endif |
298 | return 0; | |
2bdd86d4 MD |
299 | } |
300 | ||
301 | /* | |
302 | * Add UST context to a specific channel. | |
303 | * | |
304 | * If event_name is specified, add context to that event. | |
305 | */ | |
306 | static int add_ustctx_to_channel(struct ltt_ust_session *ustsession, | |
307 | struct lttng_ust_context *ustctx, | |
308 | struct ltt_ust_channel *ustchan, char *event_name) | |
309 | { | |
48842b30 | 310 | #ifdef DISABLE |
2bdd86d4 MD |
311 | int ret, no_event = 0, found = 0; |
312 | struct object_data *context_data; /* FIXME: currently a memleak */ | |
313 | ||
314 | if (strlen(event_name) == 0) { | |
315 | no_event = 1; | |
316 | } | |
317 | ||
318 | DBG("Add UST context to channel '%s', event '%s'", | |
319 | ustchan->name, event_name); | |
320 | ||
321 | if (no_event) { | |
48842b30 DG |
322 | //ret = ustctl_add_context(ustsession->sock, ustctx, |
323 | // ustchan->obj, &context_data); | |
2bdd86d4 MD |
324 | if (ret < 0) { |
325 | ret = LTTCOMM_UST_CONTEXT_FAIL; | |
326 | goto error; | |
327 | } | |
328 | } else { | |
329 | ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name); | |
330 | if (ret < 0) { | |
331 | ret = LTTCOMM_UST_CONTEXT_FAIL; | |
332 | goto error; | |
333 | } else if (ret == 1) { | |
334 | /* Event found and context added */ | |
335 | found = 1; | |
336 | } | |
337 | } | |
338 | ||
339 | if (!found && !no_event) { | |
340 | ret = LTTCOMM_NO_EVENT; | |
341 | goto error; | |
342 | } | |
343 | ||
344 | ret = LTTCOMM_OK; | |
345 | ||
346 | error: | |
347 | return ret; | |
48842b30 DG |
348 | #endif |
349 | return 0; | |
2bdd86d4 MD |
350 | } |
351 | ||
352 | /* | |
353 | * Add UST context to tracer. | |
354 | */ | |
355 | int context_ust_add(struct ltt_ust_session *ustsession, | |
356 | struct lttng_event_context *ctx, char *event_name, | |
48842b30 | 357 | char *channel_name, int domain) |
2bdd86d4 MD |
358 | { |
359 | int ret; | |
48842b30 | 360 | struct cds_lfht *chan_ht = NULL; |
2bdd86d4 MD |
361 | struct ltt_ust_channel *ustchan; |
362 | struct lttng_ust_context ustctx; | |
363 | ||
364 | /* Setup UST context structure */ | |
365 | ustctx.ctx = ctx->ctx; | |
366 | ||
48842b30 DG |
367 | switch (domain) { |
368 | case LTTNG_DOMAIN_UST: | |
369 | chan_ht = ustsession->domain_global.channels; | |
370 | break; | |
371 | } | |
372 | ||
2bdd86d4 | 373 | if (strlen(channel_name) == 0) { |
48842b30 | 374 | ret = add_ustctx_all_channels(ustsession, &ustctx, event_name, chan_ht); |
2bdd86d4 MD |
375 | if (ret != LTTCOMM_OK) { |
376 | goto error; | |
377 | } | |
378 | } else { | |
379 | /* Get UST channel */ | |
48842b30 | 380 | ustchan = trace_ust_find_channel_by_name(chan_ht, channel_name); |
2bdd86d4 MD |
381 | if (ustchan == NULL) { |
382 | ret = LTTCOMM_UST_CHAN_NOT_FOUND; | |
383 | goto error; | |
384 | } | |
385 | ||
386 | ret = add_ustctx_to_channel(ustsession, &ustctx, ustchan, event_name); | |
387 | if (ret != LTTCOMM_OK) { | |
388 | goto error; | |
389 | } | |
390 | } | |
391 | ||
392 | ret = LTTCOMM_OK; | |
393 | ||
394 | error: | |
395 | return ret; | |
396 | } |