Fix possible NULL pointer dereference
[lttng-tools.git] / lttng-sessiond / context.c
CommitLineData
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
b579acd9 28#include "context.h"
48842b30 29#include "hashtable.h"
1e307fab 30#include "kernel-ctl.h"
b579acd9
DG
31
32/*
33 * Add kernel context to an event of a specific channel.
34 */
35static 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
62499ad6 43 kevent = trace_kernel_get_event_by_name(event_name, kchan);
b579acd9
DG
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
54error:
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 */
63static 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
103error:
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 */
112static 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
148error:
149 return ret;
150}
151
152/*
153 * Add kernel context to tracer.
154 */
54d01ffb
DG
155int context_kernel_add(struct ltt_kernel_session *ksession,
156 struct lttng_event_context *ctx, char *event_name,
b579acd9
DG
157 char *channel_name)
158{
159 int ret;
160 struct ltt_kernel_channel *kchan;
54d01ffb
DG
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';
b579acd9
DG
170
171 if (strlen(channel_name) == 0) {
54d01ffb 172 ret = add_kctx_all_channels(ksession, &kctx, event_name);
b579acd9
DG
173 if (ret != LTTCOMM_OK) {
174 goto error;
175 }
176 } else {
177 /* Get kernel channel */
62499ad6 178 kchan = trace_kernel_get_channel_by_name(channel_name, ksession);
b579acd9
DG
179 if (kchan == NULL) {
180 ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
181 goto error;
182 }
183
54d01ffb 184 ret = add_kctx_to_channel(&kctx, kchan, event_name);
b579acd9
DG
185 if (ret != LTTCOMM_OK) {
186 goto error;
187 }
188 }
189
190 ret = LTTCOMM_OK;
191
192error:
193 return ret;
194}
2bdd86d4
MD
195
196/*
197 * UST support.
198 */
199
200/*
201 * Add UST context to an event of a specific channel.
202 */
48842b30 203#ifdef DISABLE
2bdd86d4
MD
204static 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
48842b30 214 ustevent = trace_ust_find_event_by_name(ustchan->events, event_name);
2bdd86d4
MD
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
226error:
227 return ret;
228}
48842b30 229#endif
2bdd86d4
MD
230
231/*
232 * Add UST context to all channel.
233 *
234 * If event_name is specified, add context to event instead.
235 */
236static int add_ustctx_all_channels(struct ltt_ust_session *ustsession,
48842b30
DG
237 struct lttng_ust_context *ustctx, char *event_name,
238 struct cds_lfht *channels)
2bdd86d4 239{
48842b30 240#ifdef DISABLE
2bdd86d4
MD
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
48842b30
DG
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);
2bdd86d4 258 if (no_event) {
48842b30
DG
259 //ret = ustctl_add_context(ustsession->sock,
260 // ustctx, ustchan->obj, &context_data);
2bdd86d4
MD
261 if (ret < 0) {
262 ret = LTTCOMM_UST_CONTEXT_FAIL;
5485f822 263 rcu_read_unlock();
2bdd86d4
MD
264 goto error;
265 }
266 } else {
267 ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name);
268 if (ret < 0) {
269 ret = LTTCOMM_UST_CONTEXT_FAIL;
5485f822 270 rcu_read_unlock();
2bdd86d4
MD
271 goto error;
272 } else if (ret == 1) {
273 /* Event found and context added */
274 found = 1;
275 break;
276 }
277 }
48842b30 278 hashtable_get_next(channels, &iter);
2bdd86d4 279 }
48842b30 280 rcu_read_unlock();
2bdd86d4
MD
281
282 if (!found && !no_event) {
283 ret = LTTCOMM_NO_EVENT;
284 goto error;
285 }
286
287 ret = LTTCOMM_OK;
288
289error:
290 return ret;
48842b30
DG
291#endif
292 return 0;
2bdd86d4
MD
293}
294
295/*
296 * Add UST context to a specific channel.
297 *
298 * If event_name is specified, add context to that event.
299 */
300static int add_ustctx_to_channel(struct ltt_ust_session *ustsession,
301 struct lttng_ust_context *ustctx,
302 struct ltt_ust_channel *ustchan, char *event_name)
303{
48842b30 304#ifdef DISABLE
2bdd86d4
MD
305 int ret, no_event = 0, found = 0;
306 struct object_data *context_data; /* FIXME: currently a memleak */
307
308 if (strlen(event_name) == 0) {
309 no_event = 1;
310 }
311
312 DBG("Add UST context to channel '%s', event '%s'",
313 ustchan->name, event_name);
314
315 if (no_event) {
48842b30
DG
316 //ret = ustctl_add_context(ustsession->sock, ustctx,
317 // ustchan->obj, &context_data);
2bdd86d4
MD
318 if (ret < 0) {
319 ret = LTTCOMM_UST_CONTEXT_FAIL;
320 goto error;
321 }
322 } else {
323 ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name);
324 if (ret < 0) {
325 ret = LTTCOMM_UST_CONTEXT_FAIL;
326 goto error;
327 } else if (ret == 1) {
328 /* Event found and context added */
329 found = 1;
330 }
331 }
332
333 if (!found && !no_event) {
334 ret = LTTCOMM_NO_EVENT;
335 goto error;
336 }
337
338 ret = LTTCOMM_OK;
339
340error:
341 return ret;
48842b30
DG
342#endif
343 return 0;
2bdd86d4
MD
344}
345
346/*
347 * Add UST context to tracer.
348 */
349int context_ust_add(struct ltt_ust_session *ustsession,
350 struct lttng_event_context *ctx, char *event_name,
48842b30 351 char *channel_name, int domain)
2bdd86d4
MD
352{
353 int ret;
48842b30 354 struct cds_lfht *chan_ht = NULL;
2bdd86d4
MD
355 struct ltt_ust_channel *ustchan;
356 struct lttng_ust_context ustctx;
357
358 /* Setup UST context structure */
359 ustctx.ctx = ctx->ctx;
360
48842b30
DG
361 switch (domain) {
362 case LTTNG_DOMAIN_UST:
363 chan_ht = ustsession->domain_global.channels;
364 break;
365 }
366
2bdd86d4 367 if (strlen(channel_name) == 0) {
48842b30 368 ret = add_ustctx_all_channels(ustsession, &ustctx, event_name, chan_ht);
2bdd86d4
MD
369 if (ret != LTTCOMM_OK) {
370 goto error;
371 }
372 } else {
373 /* Get UST channel */
48842b30 374 ustchan = trace_ust_find_channel_by_name(chan_ht, channel_name);
2bdd86d4
MD
375 if (ustchan == NULL) {
376 ret = LTTCOMM_UST_CHAN_NOT_FOUND;
377 goto error;
378 }
379
380 ret = add_ustctx_to_channel(ustsession, &ustctx, ustchan, event_name);
381 if (ret != LTTCOMM_OK) {
382 goto error;
383 }
384 }
385
386 ret = LTTCOMM_OK;
387
388error:
389 return ret;
390}
This page took 0.039865 seconds and 4 git commands to generate.