2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
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.
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
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.
19 #include <urcu/list.h>
21 #include <lttng/lttng.h>
22 #include <lttng-sessiond-comm.h>
27 #include "kernel-ctl.h"
30 * Setup a lttng_event used to enable *all* syscall tracing.
32 static void init_syscalls_kernel_event(struct lttng_event
*event
)
34 event
->name
[0] = '\0';
36 * We use LTTNG_EVENT* here since the trace kernel creation will make the
37 * right changes for the kernel.
39 event
->type
= LTTNG_EVENT_SYSCALL
;
43 * Disable kernel tracepoint event for a channel from the kernel session.
45 int event_kernel_disable_tracepoint(struct ltt_kernel_session
*ksession
,
46 struct ltt_kernel_channel
*kchan
, char *event_name
)
49 struct ltt_kernel_event
*kevent
;
51 kevent
= trace_kernel_get_event_by_name(event_name
, kchan
);
53 ret
= LTTCOMM_NO_EVENT
;
57 ret
= kernel_disable_event(kevent
);
59 ret
= LTTCOMM_KERN_DISABLE_FAIL
;
63 DBG("Kernel event %s disable for channel %s.",
64 kevent
->event
->name
, kchan
->channel
->name
);
73 * Disable kernel tracepoint events for a channel from the kernel session.
75 int event_kernel_disable_all_tracepoints(struct ltt_kernel_session
*ksession
,
76 struct ltt_kernel_channel
*kchan
)
79 struct ltt_kernel_event
*kevent
;
81 /* For each event in the kernel session */
82 cds_list_for_each_entry(kevent
, &kchan
->events_list
.head
, list
) {
83 ret
= kernel_disable_event(kevent
);
85 /* We continue disabling the rest */
94 * Disable kernel syscall events for a channel from the kernel session.
96 int event_kernel_disable_all_syscalls(struct ltt_kernel_session
*ksession
,
97 struct ltt_kernel_channel
*kchan
)
99 ERR("Cannot disable syscall tracing for existing session. Please destroy session instead.");
100 return LTTCOMM_OK
; /* Return OK so disable all succeeds */
104 * Disable all kernel event for a channel from the kernel session.
106 int event_kernel_disable_all(struct ltt_kernel_session
*ksession
,
107 struct ltt_kernel_channel
*kchan
)
111 ret
= event_kernel_disable_all_tracepoints(ksession
, kchan
);
112 if (ret
!= LTTCOMM_OK
)
114 ret
= event_kernel_disable_all_syscalls(ksession
, kchan
);
119 * Enable kernel tracepoint event for a channel from the kernel session.
121 int event_kernel_enable_tracepoint(struct ltt_kernel_session
*ksession
,
122 struct ltt_kernel_channel
*kchan
, struct lttng_event
*event
)
125 struct ltt_kernel_event
*kevent
;
127 kevent
= trace_kernel_get_event_by_name(event
->name
, kchan
);
128 if (kevent
== NULL
) {
129 ret
= kernel_create_event(event
, kchan
);
131 if (ret
== -EEXIST
) {
132 ret
= LTTCOMM_KERN_EVENT_EXIST
;
134 ret
= LTTCOMM_KERN_ENABLE_FAIL
;
138 } else if (kevent
->enabled
== 0) {
139 ret
= kernel_enable_event(kevent
);
141 ret
= LTTCOMM_KERN_ENABLE_FAIL
;
151 * Enable all kernel tracepoint events of a channel of the kernel session.
153 int event_kernel_enable_all_tracepoints(struct ltt_kernel_session
*ksession
,
154 struct ltt_kernel_channel
*kchan
, int kernel_tracer_fd
)
157 struct ltt_kernel_event
*kevent
;
158 struct lttng_event
*event_list
;
160 /* For each event in the kernel session */
161 cds_list_for_each_entry(kevent
, &kchan
->events_list
.head
, list
) {
162 ret
= kernel_enable_event(kevent
);
164 /* Enable failed but still continue */
169 size
= kernel_list_events(kernel_tracer_fd
, &event_list
);
171 ret
= LTTCOMM_KERN_LIST_FAIL
;
175 for (i
= 0; i
< size
; i
++) {
176 kevent
= trace_kernel_get_event_by_name(event_list
[i
].name
, kchan
);
177 if (kevent
== NULL
) {
178 /* Default event type for enable all */
179 event_list
[i
].type
= LTTNG_EVENT_TRACEPOINT
;
180 /* Enable each single tracepoint event */
181 ret
= kernel_create_event(&event_list
[i
], kchan
);
183 /* Ignore error here and continue */
195 * Enable all kernel tracepoint events of a channel of the kernel session.
197 int event_kernel_enable_all_syscalls(struct ltt_kernel_session
*ksession
,
198 struct ltt_kernel_channel
*kchan
, int kernel_tracer_fd
)
201 struct lttng_event event
;
203 init_syscalls_kernel_event(&event
);
205 DBG("Enabling all syscall tracing");
207 ret
= kernel_create_event(&event
, kchan
);
217 * Enable all kernel events of a channel of the kernel session.
219 int event_kernel_enable_all(struct ltt_kernel_session
*ksession
,
220 struct ltt_kernel_channel
*kchan
, int kernel_tracer_fd
)
224 ret
= event_kernel_enable_all_tracepoints(ksession
, kchan
, kernel_tracer_fd
);
225 if (ret
!= LTTCOMM_OK
) {
228 ret
= event_kernel_enable_all_syscalls(ksession
, kchan
, kernel_tracer_fd
);