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