66e134e4641be8690f9fffbbb10086a96d229bdc
[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 event for a channel from the kernel session.
43 */
44 int event_kernel_disable(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 all kernel event for a channel from the kernel session.
73 */
74 int event_kernel_disable_all(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
89 ret = LTTCOMM_OK;
90
91 return ret;
92 }
93
94 /*
95 * Enable kernel event for a channel from the kernel session.
96 */
97 int event_kernel_enable(struct ltt_kernel_session *ksession,
98 struct ltt_kernel_channel *kchan, struct lttng_event *event)
99 {
100 int ret;
101 struct ltt_kernel_event *kevent;
102
103 kevent = trace_kernel_get_event_by_name(event->name, kchan);
104 if (kevent == NULL) {
105 ret = kernel_create_event(event, kchan);
106 if (ret < 0) {
107 ret = LTTCOMM_KERN_ENABLE_FAIL;
108 goto error;
109 }
110 } else if (kevent->enabled == 0) {
111 ret = kernel_enable_event(kevent);
112 if (ret < 0) {
113 ret = LTTCOMM_KERN_ENABLE_FAIL;
114 goto error;
115 }
116 }
117
118 ret = LTTCOMM_OK;
119
120 error:
121 return ret;
122 }
123
124 /*
125 * Enable all kernel event of a channel of the kernel session.
126 */
127 int event_kernel_enable_all(struct ltt_kernel_session *ksession,
128 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
129 {
130 int size, i, ret;
131 struct ltt_kernel_event *kevent;
132 struct lttng_event *event_list;
133
134 /* For each event in the kernel session */
135 cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
136 ret = kernel_enable_event(kevent);
137 if (ret < 0) {
138 /* Enable failed but still continue */
139 continue;
140 }
141 }
142
143 size = kernel_list_events(kernel_tracer_fd, &event_list);
144 if (size < 0) {
145 ret = LTTCOMM_KERN_LIST_FAIL;
146 goto error;
147 }
148
149 for (i = 0; i < size; i++) {
150 kevent = trace_kernel_get_event_by_name(event_list[i].name, kchan);
151 if (kevent == NULL) {
152 /* Default event type for enable all */
153 event_list[i].type = LTTNG_EVENT_TRACEPOINT;
154 /* Enable each single tracepoint event */
155 ret = kernel_create_event(&event_list[i], kchan);
156 if (ret < 0) {
157 /* Ignore error here and continue */
158 }
159 }
160 }
161
162 free(event_list);
163
164 ret = LTTCOMM_OK;
165
166 error:
167 return ret;
168 }
169
170 /*
171 * Enable all kernel syscalls tracing.
172 */
173 int event_kernel_enable_syscalls(struct ltt_kernel_session *ksession,
174 struct ltt_kernel_channel *kchan, int kernel_tracer_fd)
175 {
176 int ret;
177 struct lttng_event event;
178
179 init_syscalls_kernel_event(&event);
180
181 DBG("Enabling all syscall tracing");
182
183 ret = kernel_create_event(&event, kchan);
184 if (ret < 0) {
185 goto error;
186 }
187
188 ret = LTTCOMM_OK;
189
190 error:
191 return ret;
192 }
This page took 0.048111 seconds and 3 git commands to generate.