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