c7765c0e851056a329a97594164e8815ca5409ec
[lttng-tools.git] / ltt-sessiond / context.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
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.
7 *
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.
12 *
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.
16 */
17
18 #define _GNU_SOURCE
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <urcu/list.h>
24
25 #include <lttng-sessiond-comm.h>
26 #include <lttngerr.h>
27
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
36 #include "context.h"
37 #include "kernel-ctl.h"
38
39 /*
40 * Add kernel context to an event of a specific channel.
41 */
42 static int add_kctx_to_event(struct lttng_kernel_context *kctx,
43 struct ltt_kernel_channel *kchan, char *event_name)
44 {
45 int ret, found = 0;
46 struct ltt_kernel_event *kevent;
47
48 DBG("Add kernel context to event %s", event_name);
49
50 kevent = trace_kernel_get_event_by_name(event_name, kchan);
51 if (kevent != NULL) {
52 ret = kernel_add_event_context(kevent, kctx);
53 if (ret < 0) {
54 goto error;
55 }
56 found = 1;
57 }
58
59 ret = found;
60
61 error:
62 return ret;
63 }
64
65 /*
66 * Add kernel context to all channel.
67 *
68 * If event_name is specified, add context to event instead.
69 */
70 static int add_kctx_all_channels(struct ltt_kernel_session *ksession,
71 struct lttng_kernel_context *kctx, char *event_name)
72 {
73 int ret, no_event = 0, found = 0;
74 struct ltt_kernel_channel *kchan;
75
76 if (strlen(event_name) == 0) {
77 no_event = 1;
78 }
79
80 DBG("Adding kernel context to all channels (event: %s)", event_name);
81
82 /* Go over all channels */
83 cds_list_for_each_entry(kchan, &ksession->channel_list.head, list) {
84 if (no_event) {
85 ret = kernel_add_channel_context(kchan, kctx);
86 if (ret < 0) {
87 ret = LTTCOMM_KERN_CONTEXT_FAIL;
88 goto error;
89 }
90 } else {
91 ret = add_kctx_to_event(kctx, kchan, event_name);
92 if (ret < 0) {
93 ret = LTTCOMM_KERN_CONTEXT_FAIL;
94 goto error;
95 } else if (ret == 1) {
96 /* Event found and context added */
97 found = 1;
98 break;
99 }
100 }
101 }
102
103 if (!found && !no_event) {
104 ret = LTTCOMM_NO_EVENT;
105 goto error;
106 }
107
108 ret = LTTCOMM_OK;
109
110 error:
111 return ret;
112 }
113
114 /*
115 * Add kernel context to a specific channel.
116 *
117 * If event_name is specified, add context to that event.
118 */
119 static int add_kctx_to_channel(struct lttng_kernel_context *kctx,
120 struct ltt_kernel_channel *kchan, char *event_name)
121 {
122 int ret, no_event = 0, found = 0;
123
124 if (strlen(event_name) == 0) {
125 no_event = 1;
126 }
127
128 DBG("Add kernel context to channel '%s', event '%s'",
129 kchan->channel->name, event_name);
130
131 if (no_event) {
132 ret = kernel_add_channel_context(kchan, kctx);
133 if (ret < 0) {
134 ret = LTTCOMM_KERN_CONTEXT_FAIL;
135 goto error;
136 }
137 } else {
138 ret = add_kctx_to_event(kctx, kchan, event_name);
139 if (ret < 0) {
140 ret = LTTCOMM_KERN_CONTEXT_FAIL;
141 goto error;
142 } else if (ret == 1) {
143 /* Event found and context added */
144 found = 1;
145 }
146 }
147
148 if (!found && !no_event) {
149 ret = LTTCOMM_NO_EVENT;
150 goto error;
151 }
152
153 ret = LTTCOMM_OK;
154
155 error:
156 return ret;
157 }
158
159 /*
160 * Add kernel context to tracer.
161 */
162 int context_kernel_add(struct ltt_kernel_session *ksession,
163 struct lttng_event_context *ctx, char *event_name,
164 char *channel_name)
165 {
166 int ret;
167 struct ltt_kernel_channel *kchan;
168 struct lttng_kernel_context kctx;
169
170 /* Setup kernel context structure */
171 kctx.ctx = ctx->ctx;
172 kctx.u.perf_counter.type = ctx->u.perf_counter.type;
173 kctx.u.perf_counter.config = ctx->u.perf_counter.config;
174 strncpy(kctx.u.perf_counter.name, ctx->u.perf_counter.name,
175 LTTNG_SYMBOL_NAME_LEN);
176 kctx.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
177
178 if (strlen(channel_name) == 0) {
179 ret = add_kctx_all_channels(ksession, &kctx, event_name);
180 if (ret != LTTCOMM_OK) {
181 goto error;
182 }
183 } else {
184 /* Get kernel channel */
185 kchan = trace_kernel_get_channel_by_name(channel_name, ksession);
186 if (kchan == NULL) {
187 ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
188 goto error;
189 }
190
191 ret = add_kctx_to_channel(&kctx, kchan, event_name);
192 if (ret != LTTCOMM_OK) {
193 goto error;
194 }
195 }
196
197 ret = LTTCOMM_OK;
198
199 error:
200 return ret;
201 }
202
203 /*
204 * UST support.
205 */
206
207 /*
208 * Add UST context to an event of a specific channel.
209 */
210 static int add_ustctx_to_event(struct ltt_ust_session *ustsession,
211 struct lttng_ust_context *ustctx,
212 struct ltt_ust_channel *ustchan, char *event_name)
213 {
214 int ret, found = 0;
215 struct ltt_ust_event *ustevent;
216 struct object_data *context_data; /* FIXME: currently a memleak */
217
218 DBG("Add UST context to event %s", event_name);
219
220 ustevent = trace_ust_get_event_by_name(event_name, ustchan);
221 if (ustevent != NULL) {
222 ret = ustctl_add_context(ustsession->sock, ustctx,
223 ustevent->obj, &context_data);
224 if (ret < 0) {
225 goto error;
226 }
227 found = 1;
228 }
229
230 ret = found;
231
232 error:
233 return ret;
234 }
235
236 /*
237 * Add UST context to all channel.
238 *
239 * If event_name is specified, add context to event instead.
240 */
241 static int add_ustctx_all_channels(struct ltt_ust_session *ustsession,
242 struct lttng_ust_context *ustctx, char *event_name)
243 {
244 int ret, no_event = 0, found = 0;
245 struct ltt_ust_channel *ustchan;
246 struct object_data *context_data; /* FIXME: currently a memleak */
247
248 if (strlen(event_name) == 0) {
249 no_event = 1;
250 }
251
252 DBG("Adding ust context to all channels (event: %s)", event_name);
253
254 /* Go over all channels */
255 cds_list_for_each_entry(ustchan, &ustsession->channels.head, list) {
256 if (no_event) {
257 ret = ustctl_add_context(ustsession->sock,
258 ustctx, ustchan->obj, &context_data);
259 if (ret < 0) {
260 ret = LTTCOMM_UST_CONTEXT_FAIL;
261 goto error;
262 }
263 } else {
264 ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name);
265 if (ret < 0) {
266 ret = LTTCOMM_UST_CONTEXT_FAIL;
267 goto error;
268 } else if (ret == 1) {
269 /* Event found and context added */
270 found = 1;
271 break;
272 }
273 }
274 }
275
276 if (!found && !no_event) {
277 ret = LTTCOMM_NO_EVENT;
278 goto error;
279 }
280
281 ret = LTTCOMM_OK;
282
283 error:
284 return ret;
285 }
286
287 /*
288 * Add UST context to a specific channel.
289 *
290 * If event_name is specified, add context to that event.
291 */
292 static int add_ustctx_to_channel(struct ltt_ust_session *ustsession,
293 struct lttng_ust_context *ustctx,
294 struct ltt_ust_channel *ustchan, char *event_name)
295 {
296 int ret, no_event = 0, found = 0;
297 struct object_data *context_data; /* FIXME: currently a memleak */
298
299 if (strlen(event_name) == 0) {
300 no_event = 1;
301 }
302
303 DBG("Add UST context to channel '%s', event '%s'",
304 ustchan->name, event_name);
305
306 if (no_event) {
307 ret = ustctl_add_context(ustsession->sock, ustctx,
308 ustchan->obj, &context_data);
309 if (ret < 0) {
310 ret = LTTCOMM_UST_CONTEXT_FAIL;
311 goto error;
312 }
313 } else {
314 ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name);
315 if (ret < 0) {
316 ret = LTTCOMM_UST_CONTEXT_FAIL;
317 goto error;
318 } else if (ret == 1) {
319 /* Event found and context added */
320 found = 1;
321 }
322 }
323
324 if (!found && !no_event) {
325 ret = LTTCOMM_NO_EVENT;
326 goto error;
327 }
328
329 ret = LTTCOMM_OK;
330
331 error:
332 return ret;
333 }
334
335 /*
336 * Add UST context to tracer.
337 */
338 int context_ust_add(struct ltt_ust_session *ustsession,
339 struct lttng_event_context *ctx, char *event_name,
340 char *channel_name)
341 {
342 int ret;
343 struct ltt_ust_channel *ustchan;
344 struct lttng_ust_context ustctx;
345
346 /* Setup UST context structure */
347 ustctx.ctx = ctx->ctx;
348
349 if (strlen(channel_name) == 0) {
350 ret = add_ustctx_all_channels(ustsession, &ustctx, event_name);
351 if (ret != LTTCOMM_OK) {
352 goto error;
353 }
354 } else {
355 /* Get UST channel */
356 ustchan = trace_ust_get_channel_by_name(channel_name, ustsession);
357 if (ustchan == NULL) {
358 ret = LTTCOMM_UST_CHAN_NOT_FOUND;
359 goto error;
360 }
361
362 ret = add_ustctx_to_channel(ustsession, &ustctx, ustchan, event_name);
363 if (ret != LTTCOMM_OK) {
364 goto error;
365 }
366 }
367
368 ret = LTTCOMM_OK;
369
370 error:
371 return ret;
372 }
This page took 0.055121 seconds and 3 git commands to generate.