Implement enable all vs enable tracepoints vs enable syscalls
[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 <urcu/list.h>
19
20 #include <lttng/lttng.h>
21 #include <lttng-sessiond-comm.h>
22 #include <lttngerr.h>
23
24 #include "channel.h"
25 #include "event.h"
26 #include "kernel-ctl.h"
27
28 /*
29 * Setup a lttng_event used to enable *all* syscall tracing.
30 */
31 static void init_syscalls_kernel_event(struct lttng_event *event)
32 {
33 event->name[0] = '\0';
34 /*
35 * We use LTTNG_EVENT* here since the trace kernel creation will make the
36 * right changes for the kernel.
37 */
38 event->type = LTTNG_EVENT_SYSCALL;
39 }
40
41 /*
42 * Disable kernel tracepoint event for a channel from the kernel session.
43 */
44 int event_kernel_disable_tracepoint(struct ltt_kernel_session *ksession,
45 struct ltt_kernel_channel *kchan, char *event_name)
46 {
47 int ret;
48 struct ltt_kernel_event *kevent;
49
50 kevent = trace_kernel_get_event_by_name(event_name, kchan);
51 if (kevent == NULL) {
52 ret = LTTCOMM_NO_EVENT;
53 goto error;
54 }
55
56 ret = kernel_disable_event(kevent);
57 if (ret < 0) {
58 ret = LTTCOMM_KERN_DISABLE_FAIL;
59 goto error;
60 }
61
62 DBG("Kernel event %s disable for channel %s.",
63 kevent->event->name, kchan->channel->name);
64
65 ret = LTTCOMM_OK;
66
67 error:
68 return ret;
69 }
70
71 /*
72 * Disable kernel tracepoint events for a channel from the kernel session.
73 */
74 int event_kernel_disable_all_tracepoints(struct ltt_kernel_session *ksession,
75 struct ltt_kernel_channel *kchan)
76 {
77 int ret;
78 struct ltt_kernel_event *kevent;
79
80 /* For each event in the kernel session */
81 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
82 ret = kernel_disable_event(kevent);
83 if (ret < 0) {
84 /* We continue disabling the rest */
85 continue;
86 }
87 }
88 ret = LTTCOMM_OK;
89 return ret;
90 }
91
92 /*
93 * Disable kernel syscall events for a channel from the kernel session.
94 */
95 int event_kernel_disable_all_syscalls(struct ltt_kernel_session *ksession,
96 struct ltt_kernel_channel *kchan)
97 {
98 ERR("Cannot disable syscall tracing for existing session. Please destroy session instead.");
99 return LTTCOMM_OK; /* Return OK so disable all succeeds */
100 }
101
102 /*
103 * Disable all kernel event for a channel from the kernel session.
104 */
105 int event_kernel_disable_all(struct ltt_kernel_session *ksession,
106 struct ltt_kernel_channel *kchan)
107 {
108 int ret;
109
110 ret = event_kernel_disable_all_tracepoints(ksession, kchan);
111 if (ret != LTTCOMM_OK)
112 return ret;
113 ret = event_kernel_disable_all_syscalls(ksession, kchan);
114 return ret;
115 }
116
117 /*
118 * Enable kernel tracepoint event for a channel from the kernel session.
119 */
120 int event_kernel_enable_tracepoint(struct ltt_kernel_session *ksession,
121 struct ltt_kernel_channel *kchan, struct lttng_event *event)
122 {
123 int ret;
124 struct ltt_kernel_event *kevent;
125
126 kevent = trace_kernel_get_event_by_name(event->name, kchan);
127 if (kevent == NULL) {
128 ret = kernel_create_event(event, kchan);
129 if (ret < 0) {
130 ret = LTTCOMM_KERN_ENABLE_FAIL;
131 goto end;
132 }
133 } else if (kevent->enabled == 0) {
134 ret = kernel_enable_event(kevent);
135 if (ret < 0) {
136 ret = LTTCOMM_KERN_ENABLE_FAIL;
137 goto end;
138 }
139 }
140 ret = LTTCOMM_OK;
141 end:
142 return ret;
143 }
144
145 /*
146 * Enable all kernel tracepoint events of a channel of the kernel session.
147 */
148 int event_kernel_enable_all_tracepoints(struct ltt_kernel_session *ksession,
149 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
150 {
151 int size, i, ret;
152 struct ltt_kernel_event *kevent;
153 struct lttng_event *event_list;
154
155 /* For each event in the kernel session */
156 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
157 ret = kernel_enable_event(kevent);
158 if (ret < 0) {
159 /* Enable failed but still continue */
160 continue;
161 }
162 }
163
164 size = kernel_list_events(kernel_tracer_fd, &event_list);
165 if (size < 0) {
166 ret = LTTCOMM_KERN_LIST_FAIL;
167 goto end;
168 }
169
170 for (i = 0; i < size; i++) {
171 kevent = trace_kernel_get_event_by_name(event_list[i].name, kchan);
172 if (kevent == NULL) {
173 /* Default event type for enable all */
174 event_list[i].type = LTTNG_EVENT_TRACEPOINT;
175 /* Enable each single tracepoint event */
176 ret = kernel_create_event(&event_list[i], kchan);
177 if (ret < 0) {
178 /* Ignore error here and continue */
179 }
180 }
181 }
182 free(event_list);
183 ret = LTTCOMM_OK;
184 end:
185 return ret;
186
187 }
188
189 /*
190 * Enable all kernel tracepoint events of a channel of the kernel session.
191 */
192 int event_kernel_enable_all_syscalls(struct ltt_kernel_session *ksession,
193 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
194 {
195 int ret;
196 struct lttng_event event;
197
198 init_syscalls_kernel_event(&event);
199
200 DBG("Enabling all syscall tracing");
201
202 ret = kernel_create_event(&event, kchan);
203 if (ret < 0) {
204 goto end;
205 }
206 ret = LTTCOMM_OK;
207 end:
208 return ret;
209 }
210
211 /*
212 * Enable all kernel events of a channel of the kernel session.
213 */
214 int event_kernel_enable_all(struct ltt_kernel_session *ksession,
215 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
216 {
217 int ret;
218
219 ret = event_kernel_enable_all_tracepoints(ksession, kchan, kernel_tracer_fd);
220 if (ret != LTTCOMM_OK) {
221 goto end;
222 }
223 ret = event_kernel_enable_all_syscalls(ksession, kchan, kernel_tracer_fd);
224 end:
225 return ret;
226 }
This page took 0.049493 seconds and 4 git commands to generate.