Commit | Line | Data |
---|---|---|
54d01ffb DG |
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 | ||
d87bfb32 | 18 | #include <errno.h> |
54d01ffb | 19 | #include <urcu/list.h> |
2bdd86d4 | 20 | #include <string.h> |
54d01ffb DG |
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" | |
48842b30 | 28 | #include "hashtable.h" |
54d01ffb | 29 | #include "kernel-ctl.h" |
9df8df5e | 30 | #include "ust-ctl.h" |
54d01ffb | 31 | |
8c9ae521 DG |
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 | ||
54d01ffb | 45 | /* |
7a3d1328 | 46 | * Disable kernel tracepoint event for a channel from the kernel session. |
54d01ffb | 47 | */ |
7a3d1328 | 48 | int event_kernel_disable_tracepoint(struct ltt_kernel_session *ksession, |
54d01ffb DG |
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 | /* | |
7a3d1328 | 76 | * Disable kernel tracepoint events for a channel from the kernel session. |
54d01ffb | 77 | */ |
7a3d1328 | 78 | int event_kernel_disable_all_tracepoints(struct ltt_kernel_session *ksession, |
54d01ffb DG |
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 | } | |
54d01ffb | 92 | ret = LTTCOMM_OK; |
7a3d1328 MD |
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 | } | |
54d01ffb | 105 | |
7a3d1328 MD |
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); | |
54d01ffb DG |
118 | return ret; |
119 | } | |
120 | ||
121 | /* | |
7a3d1328 | 122 | * Enable kernel tracepoint event for a channel from the kernel session. |
54d01ffb | 123 | */ |
7a3d1328 | 124 | int event_kernel_enable_tracepoint(struct ltt_kernel_session *ksession, |
54d01ffb DG |
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) { | |
d87bfb32 DG |
134 | if (ret == -EEXIST) { |
135 | ret = LTTCOMM_KERN_EVENT_EXIST; | |
136 | } else { | |
137 | ret = LTTCOMM_KERN_ENABLE_FAIL; | |
138 | } | |
7a3d1328 | 139 | goto end; |
54d01ffb DG |
140 | } |
141 | } else if (kevent->enabled == 0) { | |
142 | ret = kernel_enable_event(kevent); | |
143 | if (ret < 0) { | |
144 | ret = LTTCOMM_KERN_ENABLE_FAIL; | |
7a3d1328 | 145 | goto end; |
54d01ffb DG |
146 | } |
147 | } | |
54d01ffb | 148 | ret = LTTCOMM_OK; |
7a3d1328 | 149 | end: |
54d01ffb DG |
150 | return ret; |
151 | } | |
152 | ||
153 | /* | |
7a3d1328 | 154 | * Enable all kernel tracepoint events of a channel of the kernel session. |
54d01ffb | 155 | */ |
7a3d1328 | 156 | int event_kernel_enable_all_tracepoints(struct ltt_kernel_session *ksession, |
54d01ffb DG |
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; | |
7a3d1328 | 175 | goto end; |
54d01ffb DG |
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 | } | |
54d01ffb | 190 | free(event_list); |
54d01ffb | 191 | ret = LTTCOMM_OK; |
7a3d1328 | 192 | end: |
54d01ffb | 193 | return ret; |
7a3d1328 | 194 | |
54d01ffb | 195 | } |
8c9ae521 DG |
196 | |
197 | /* | |
7a3d1328 | 198 | * Enable all kernel tracepoint events of a channel of the kernel session. |
8c9ae521 | 199 | */ |
7a3d1328 | 200 | int event_kernel_enable_all_syscalls(struct ltt_kernel_session *ksession, |
8c9ae521 DG |
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) { | |
7a3d1328 | 212 | goto end; |
8c9ae521 | 213 | } |
8c9ae521 | 214 | ret = LTTCOMM_OK; |
7a3d1328 MD |
215 | end: |
216 | return ret; | |
217 | } | |
8c9ae521 | 218 | |
7a3d1328 MD |
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: | |
8c9ae521 DG |
233 | return ret; |
234 | } | |
2bdd86d4 MD |
235 | |
236 | /* | |
237 | * Enable UST tracepoint event for a channel from a UST session. | |
238 | */ | |
48842b30 DG |
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) | |
2bdd86d4 MD |
242 | { |
243 | int ret; | |
48842b30 DG |
244 | struct lttng_ust_event ltt_uevent; |
245 | struct object_data *obj_event; | |
2bdd86d4 | 246 | |
48842b30 DG |
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, <t_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; | |
2bdd86d4 | 258 | } |
48842b30 DG |
259 | |
260 | uevent->obj = obj_event; | |
261 | uevent->handle = obj_event->handle; | |
262 | uevent->enabled = 1; | |
2bdd86d4 MD |
263 | ret = LTTCOMM_OK; |
264 | end: | |
265 | return ret; | |
266 | } | |
48842b30 | 267 | #endif |
2bdd86d4 | 268 | |
48842b30 | 269 | #ifdef DISABLE |
2bdd86d4 MD |
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 | ||
48842b30 | 276 | ustevent = trace_ust_find_event_by_name(ustchan->events, event_name); |
2bdd86d4 MD |
277 | if (ustevent == NULL) { |
278 | ret = LTTCOMM_NO_EVENT; | |
279 | goto end; | |
280 | } | |
48842b30 | 281 | //ret = ustctl_disable(ustsession->sock, ustevent->obj); |
2bdd86d4 MD |
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 | } | |
48842b30 | 291 | #endif |