Preliminary work for full UST support
[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 "hashtable.h"
38 #include "kernel-ctl.h"
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
51 kevent = trace_kernel_get_event_by_name(event_name, kchan);
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 */
163 int context_kernel_add(struct ltt_kernel_session *ksession,
164 struct lttng_event_context *ctx, char *event_name,
165 char *channel_name)
166 {
167 int ret;
168 struct ltt_kernel_channel *kchan;
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';
178
179 if (strlen(channel_name) == 0) {
180 ret = add_kctx_all_channels(ksession, &kctx, event_name);
181 if (ret != LTTCOMM_OK) {
182 goto error;
183 }
184 } else {
185 /* Get kernel channel */
186 kchan = trace_kernel_get_channel_by_name(channel_name, ksession);
187 if (kchan == NULL) {
188 ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
189 goto error;
190 }
191
192 ret = add_kctx_to_channel(&kctx, kchan, event_name);
193 if (ret != LTTCOMM_OK) {
194 goto error;
195 }
196 }
197
198 ret = LTTCOMM_OK;
199
200 error:
201 return ret;
202 }
203
204 /*
205 * UST support.
206 */
207
208 /*
209 * Add UST context to an event of a specific channel.
210 */
211 #ifdef DISABLE
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
222 ustevent = trace_ust_find_event_by_name(ustchan->events, event_name);
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 }
237 #endif
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,
245 struct lttng_ust_context *ustctx, char *event_name,
246 struct cds_lfht *channels)
247 {
248 #ifdef DISABLE
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
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);
266 if (no_event) {
267 //ret = ustctl_add_context(ustsession->sock,
268 // ustctx, ustchan->obj, &context_data);
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 }
284 hashtable_get_next(channels, &iter);
285 }
286 rcu_read_unlock();
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;
297 #endif
298 return 0;
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 {
310 #ifdef DISABLE
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) {
322 //ret = ustctl_add_context(ustsession->sock, ustctx,
323 // ustchan->obj, &context_data);
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;
348 #endif
349 return 0;
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,
357 char *channel_name, int domain)
358 {
359 int ret;
360 struct cds_lfht *chan_ht = NULL;
361 struct ltt_ust_channel *ustchan;
362 struct lttng_ust_context ustctx;
363
364 /* Setup UST context structure */
365 ustctx.ctx = ctx->ctx;
366
367 switch (domain) {
368 case LTTNG_DOMAIN_UST:
369 chan_ht = ustsession->domain_global.channels;
370 break;
371 }
372
373 if (strlen(channel_name) == 0) {
374 ret = add_ustctx_all_channels(ustsession, &ustctx, event_name, chan_ht);
375 if (ret != LTTCOMM_OK) {
376 goto error;
377 }
378 } else {
379 /* Get UST channel */
380 ustchan = trace_ust_find_channel_by_name(chan_ht, channel_name);
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 }
This page took 0.037306 seconds and 4 git commands to generate.