Preliminary work for full UST support
[lttng-tools.git] / ltt-sessiond / event.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 #include <errno.h>
19 #include <urcu/list.h>
20 #include <string.h>
21
22 #include <lttng/lttng.h>
23 #include <lttng-sessiond-comm.h>
24 #include <lttngerr.h>
25
26 #ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
27 #include <ust/lttng-ust-ctl.h>
28 #else
29 #include "lttng-ust-ctl.h"
30 #endif
31
32 #include "channel.h"
33 #include "event.h"
34 #include "hashtable.h"
35 #include "kernel-ctl.h"
36
37 /*
38 * Setup a lttng_event used to enable *all* syscall tracing.
39 */
40 static void init_syscalls_kernel_event(struct lttng_event *event)
41 {
42 event->name[0] = '\0';
43 /*
44 * We use LTTNG_EVENT* here since the trace kernel creation will make the
45 * right changes for the kernel.
46 */
47 event->type = LTTNG_EVENT_SYSCALL;
48 }
49
50 /*
51 * Disable kernel tracepoint event for a channel from the kernel session.
52 */
53 int event_kernel_disable_tracepoint(struct ltt_kernel_session *ksession,
54 struct ltt_kernel_channel *kchan, char *event_name)
55 {
56 int ret;
57 struct ltt_kernel_event *kevent;
58
59 kevent = trace_kernel_get_event_by_name(event_name, kchan);
60 if (kevent == NULL) {
61 ret = LTTCOMM_NO_EVENT;
62 goto error;
63 }
64
65 ret = kernel_disable_event(kevent);
66 if (ret < 0) {
67 ret = LTTCOMM_KERN_DISABLE_FAIL;
68 goto error;
69 }
70
71 DBG("Kernel event %s disable for channel %s.",
72 kevent->event->name, kchan->channel->name);
73
74 ret = LTTCOMM_OK;
75
76 error:
77 return ret;
78 }
79
80 /*
81 * Disable kernel tracepoint events for a channel from the kernel session.
82 */
83 int event_kernel_disable_all_tracepoints(struct ltt_kernel_session *ksession,
84 struct ltt_kernel_channel *kchan)
85 {
86 int ret;
87 struct ltt_kernel_event *kevent;
88
89 /* For each event in the kernel session */
90 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
91 ret = kernel_disable_event(kevent);
92 if (ret < 0) {
93 /* We continue disabling the rest */
94 continue;
95 }
96 }
97 ret = LTTCOMM_OK;
98 return ret;
99 }
100
101 /*
102 * Disable kernel syscall events for a channel from the kernel session.
103 */
104 int event_kernel_disable_all_syscalls(struct ltt_kernel_session *ksession,
105 struct ltt_kernel_channel *kchan)
106 {
107 ERR("Cannot disable syscall tracing for existing session. Please destroy session instead.");
108 return LTTCOMM_OK; /* Return OK so disable all succeeds */
109 }
110
111 /*
112 * Disable all kernel event for a channel from the kernel session.
113 */
114 int event_kernel_disable_all(struct ltt_kernel_session *ksession,
115 struct ltt_kernel_channel *kchan)
116 {
117 int ret;
118
119 ret = event_kernel_disable_all_tracepoints(ksession, kchan);
120 if (ret != LTTCOMM_OK)
121 return ret;
122 ret = event_kernel_disable_all_syscalls(ksession, kchan);
123 return ret;
124 }
125
126 /*
127 * Enable kernel tracepoint event for a channel from the kernel session.
128 */
129 int event_kernel_enable_tracepoint(struct ltt_kernel_session *ksession,
130 struct ltt_kernel_channel *kchan, struct lttng_event *event)
131 {
132 int ret;
133 struct ltt_kernel_event *kevent;
134
135 kevent = trace_kernel_get_event_by_name(event->name, kchan);
136 if (kevent == NULL) {
137 ret = kernel_create_event(event, kchan);
138 if (ret < 0) {
139 if (ret == -EEXIST) {
140 ret = LTTCOMM_KERN_EVENT_EXIST;
141 } else {
142 ret = LTTCOMM_KERN_ENABLE_FAIL;
143 }
144 goto end;
145 }
146 } else if (kevent->enabled == 0) {
147 ret = kernel_enable_event(kevent);
148 if (ret < 0) {
149 ret = LTTCOMM_KERN_ENABLE_FAIL;
150 goto end;
151 }
152 }
153 ret = LTTCOMM_OK;
154 end:
155 return ret;
156 }
157
158 /*
159 * Enable all kernel tracepoint events of a channel of the kernel session.
160 */
161 int event_kernel_enable_all_tracepoints(struct ltt_kernel_session *ksession,
162 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
163 {
164 int size, i, ret;
165 struct ltt_kernel_event *kevent;
166 struct lttng_event *event_list;
167
168 /* For each event in the kernel session */
169 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
170 ret = kernel_enable_event(kevent);
171 if (ret < 0) {
172 /* Enable failed but still continue */
173 continue;
174 }
175 }
176
177 size = kernel_list_events(kernel_tracer_fd, &event_list);
178 if (size < 0) {
179 ret = LTTCOMM_KERN_LIST_FAIL;
180 goto end;
181 }
182
183 for (i = 0; i < size; i++) {
184 kevent = trace_kernel_get_event_by_name(event_list[i].name, kchan);
185 if (kevent == NULL) {
186 /* Default event type for enable all */
187 event_list[i].type = LTTNG_EVENT_TRACEPOINT;
188 /* Enable each single tracepoint event */
189 ret = kernel_create_event(&event_list[i], kchan);
190 if (ret < 0) {
191 /* Ignore error here and continue */
192 }
193 }
194 }
195 free(event_list);
196 ret = LTTCOMM_OK;
197 end:
198 return ret;
199
200 }
201
202 /*
203 * Enable all kernel tracepoint events of a channel of the kernel session.
204 */
205 int event_kernel_enable_all_syscalls(struct ltt_kernel_session *ksession,
206 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
207 {
208 int ret;
209 struct lttng_event event;
210
211 init_syscalls_kernel_event(&event);
212
213 DBG("Enabling all syscall tracing");
214
215 ret = kernel_create_event(&event, kchan);
216 if (ret < 0) {
217 goto end;
218 }
219 ret = LTTCOMM_OK;
220 end:
221 return ret;
222 }
223
224 /*
225 * Enable all kernel events of a channel of the kernel session.
226 */
227 int event_kernel_enable_all(struct ltt_kernel_session *ksession,
228 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
229 {
230 int ret;
231
232 ret = event_kernel_enable_all_tracepoints(ksession, kchan, kernel_tracer_fd);
233 if (ret != LTTCOMM_OK) {
234 goto end;
235 }
236 ret = event_kernel_enable_all_syscalls(ksession, kchan, kernel_tracer_fd);
237 end:
238 return ret;
239 }
240
241 /*
242 * Enable UST tracepoint event for a channel from a UST session.
243 */
244 #ifdef DISABLE
245 int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
246 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
247 {
248 int ret;
249 struct lttng_ust_event ltt_uevent;
250 struct object_data *obj_event;
251
252 strncpy(ltt_uevent.name, uevent->attr.name, sizeof(ltt_uevent.name));
253 ltt_uevent.name[sizeof(ltt_uevent.name) - 1] = '\0';
254 /* TODO: adjust to other instrumentation types */
255 ltt_uevent.instrumentation = LTTNG_UST_TRACEPOINT;
256
257 ret = ustctl_create_event(app->key.sock, &ltt_uevent,
258 uchan->obj, &obj_event);
259 if (ret < 0) {
260 DBG("Error ustctl create event %s for app pid: %d, sock: %d ret %d",
261 uevent->attr.name, app->key.pid, app->key.sock, ret);
262 goto next;
263 }
264
265 uevent->obj = obj_event;
266 uevent->handle = obj_event->handle;
267 uevent->enabled = 1;
268 ret = LTTCOMM_OK;
269 end:
270 return ret;
271 }
272 #endif
273
274 #ifdef DISABLE
275 int event_ust_disable_tracepoint(struct ltt_ust_session *ustsession,
276 struct ltt_ust_channel *ustchan, char *event_name)
277 {
278 int ret;
279 struct ltt_ust_event *ustevent;
280
281 ustevent = trace_ust_find_event_by_name(ustchan->events, event_name);
282 if (ustevent == NULL) {
283 ret = LTTCOMM_NO_EVENT;
284 goto end;
285 }
286 //ret = ustctl_disable(ustsession->sock, ustevent->obj);
287 if (ret < 0) {
288 ret = LTTCOMM_UST_ENABLE_FAIL;
289 goto end;
290 }
291 ustevent->enabled = 0;
292 ret = LTTCOMM_OK;
293 end:
294 return ret;
295 }
296 #endif
This page took 0.051856 seconds and 4 git commands to generate.