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 | ||
56fff090 | 18 | #include <string.h> |
54d01ffb DG |
19 | #include <unistd.h> |
20 | ||
21 | #include <lttng/lttng.h> | |
22 | #include <lttng-sessiond-comm.h> | |
23 | #include <lttngerr.h> | |
24 | ||
25 | #include "channel.h" | |
f6a9efaa | 26 | #include "hashtable.h" |
54d01ffb | 27 | #include "kernel-ctl.h" |
44d3bd01 | 28 | #include "ust-ctl.h" |
54d01ffb DG |
29 | #include "utils.h" |
30 | ||
31 | /* | |
32 | * Return allocated channel attributes. | |
33 | */ | |
f6cd6b0f | 34 | struct lttng_channel *channel_new_default_attr(int dom) |
54d01ffb DG |
35 | { |
36 | struct lttng_channel *chan; | |
37 | ||
38 | chan = zmalloc(sizeof(struct lttng_channel)); | |
39 | if (chan == NULL) { | |
ba7f0ae5 | 40 | perror("zmalloc channel init"); |
54d01ffb DG |
41 | goto error_alloc; |
42 | } | |
43 | ||
44d3bd01 DG |
44 | if (snprintf(chan->name, sizeof(chan->name), "%s", |
45 | DEFAULT_CHANNEL_NAME) < 0) { | |
46 | perror("snprintf default channel name"); | |
54d01ffb DG |
47 | goto error; |
48 | } | |
49 | ||
50 | chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; | |
51 | chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; | |
52 | chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; | |
53 | ||
54 | switch (dom) { | |
55 | case LTTNG_DOMAIN_KERNEL: | |
56 | chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; | |
57 | chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; | |
58 | chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; | |
59 | break; | |
2bdd86d4 | 60 | case LTTNG_DOMAIN_UST: |
44d3bd01 DG |
61 | case LTTNG_DOMAIN_UST_PID: |
62 | chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; | |
63 | chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; | |
64 | chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; | |
65 | break; | |
54d01ffb DG |
66 | default: |
67 | goto error; /* Not implemented */ | |
68 | } | |
69 | ||
70 | return chan; | |
71 | ||
72 | error: | |
73 | free(chan); | |
74 | error_alloc: | |
75 | return NULL; | |
76 | } | |
77 | ||
56fff090 DG |
78 | /* |
79 | * Copy two ltt ust channel. Dst and src must be already allocated. | |
80 | */ | |
81 | int channel_ust_copy(struct ltt_ust_channel *dst, | |
82 | struct ltt_ust_channel *src) | |
83 | { | |
f6a9efaa | 84 | //struct ltt_ust_event *uevent, *new_uevent; |
56fff090 DG |
85 | |
86 | memcpy(dst, src, sizeof(struct ltt_ust_channel)); | |
f6a9efaa | 87 | dst->events = hashtable_new_str(0); |
56fff090 | 88 | |
f6a9efaa | 89 | /* |
56fff090 | 90 | cds_list_for_each_entry(uevent, &src->events.head, list) { |
ba7f0ae5 | 91 | new_uevent = zmalloc(sizeof(struct ltt_ust_event)); |
56fff090 | 92 | if (new_uevent == NULL) { |
ba7f0ae5 | 93 | perror("zmalloc ltt_ust_event"); |
56fff090 DG |
94 | goto error; |
95 | } | |
96 | ||
97 | memcpy(new_uevent, uevent, sizeof(struct ltt_ust_event)); | |
98 | cds_list_add(&new_uevent->list, &dst->events.head); | |
99 | dst->events.count++; | |
100 | } | |
f6a9efaa | 101 | */ |
56fff090 DG |
102 | |
103 | return 0; | |
104 | ||
f6a9efaa DG |
105 | //error: |
106 | // return -1; | |
56fff090 DG |
107 | } |
108 | ||
54d01ffb DG |
109 | /* |
110 | * Disable kernel channel of the kernel session. | |
111 | */ | |
112 | int channel_kernel_disable(struct ltt_kernel_session *ksession, | |
113 | char *channel_name) | |
114 | { | |
115 | int ret; | |
116 | struct ltt_kernel_channel *kchan; | |
117 | ||
118 | kchan = trace_kernel_get_channel_by_name(channel_name, ksession); | |
119 | if (kchan == NULL) { | |
120 | ret = LTTCOMM_KERN_CHAN_NOT_FOUND; | |
121 | goto error; | |
122 | } else if (kchan->enabled == 1) { | |
123 | ret = kernel_disable_channel(kchan); | |
124 | if (ret < 0) { | |
125 | if (ret != EEXIST) { | |
126 | ret = LTTCOMM_KERN_CHAN_DISABLE_FAIL; | |
127 | } | |
128 | goto error; | |
129 | } | |
130 | } | |
131 | ||
132 | ret = LTTCOMM_OK; | |
133 | ||
134 | error: | |
135 | return ret; | |
136 | } | |
137 | ||
138 | /* | |
139 | * Enable kernel channel of the kernel session. | |
140 | */ | |
141 | int channel_kernel_enable(struct ltt_kernel_session *ksession, | |
142 | struct ltt_kernel_channel *kchan) | |
143 | { | |
144 | int ret; | |
145 | ||
146 | if (kchan->enabled == 0) { | |
147 | ret = kernel_enable_channel(kchan); | |
148 | if (ret < 0) { | |
149 | ret = LTTCOMM_KERN_CHAN_ENABLE_FAIL; | |
150 | goto error; | |
151 | } | |
152 | } | |
153 | ||
154 | ret = LTTCOMM_OK; | |
155 | ||
156 | error: | |
157 | return ret; | |
158 | } | |
159 | ||
160 | /* | |
161 | * Create kernel channel of the kernel session and notify kernel thread. | |
162 | */ | |
163 | int channel_kernel_create(struct ltt_kernel_session *ksession, | |
44d3bd01 | 164 | struct lttng_channel *chan, int kernel_pipe) |
54d01ffb DG |
165 | { |
166 | int ret; | |
167 | struct lttng_channel *attr = chan; | |
168 | ||
169 | /* Creating channel attributes if needed */ | |
170 | if (attr == NULL) { | |
2bdd86d4 | 171 | /* FIXME: this appears to be a memory leak */ |
f6cd6b0f | 172 | attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL); |
54d01ffb DG |
173 | if (attr == NULL) { |
174 | ret = LTTCOMM_FATAL; | |
175 | goto error; | |
176 | } | |
177 | } | |
178 | ||
179 | /* Channel not found, creating it */ | |
180 | ret = kernel_create_channel(ksession, attr, ksession->trace_path); | |
181 | if (ret < 0) { | |
182 | ret = LTTCOMM_KERN_CHAN_FAIL; | |
183 | goto error; | |
184 | } | |
185 | ||
186 | /* Notify kernel thread that there is a new channel */ | |
187 | ret = notify_thread_pipe(kernel_pipe); | |
188 | if (ret < 0) { | |
189 | ret = LTTCOMM_FATAL; | |
190 | goto error; | |
191 | } | |
192 | ||
193 | ret = LTTCOMM_OK; | |
194 | ||
195 | error: | |
196 | return ret; | |
197 | } | |
44d3bd01 DG |
198 | |
199 | /* | |
200 | * Create UST channel and enable it on the tracer. | |
201 | */ | |
48842b30 DG |
202 | int channel_ust_create(struct ltt_ust_session *usess, |
203 | struct lttng_channel *attr) | |
44d3bd01 DG |
204 | { |
205 | int ret; | |
48842b30 DG |
206 | struct ltt_ust_channel *uchan; |
207 | //struct lttng_ust_channel_attr uattr; | |
208 | //struct object_data *obj; | |
209 | ||
210 | uchan = trace_ust_find_channel_by_name(usess->domain_global.channels, | |
211 | attr->name); | |
212 | if (uchan == NULL) { | |
213 | uchan = trace_ust_create_channel(attr, usess->pathname); | |
214 | if (uchan == NULL) { | |
215 | ret = LTTCOMM_UST_CHAN_FAIL; | |
44d3bd01 DG |
216 | goto error; |
217 | } | |
48842b30 DG |
218 | rcu_read_lock(); |
219 | hashtable_add_unique(usess->domain_global.channels, &uchan->node); | |
220 | rcu_read_unlock(); | |
221 | } else { | |
222 | ret = LTTCOMM_UST_CHAN_EXIST; | |
2bdd86d4 MD |
223 | goto error; |
224 | } | |
f6a9efaa | 225 | |
48842b30 DG |
226 | /* TODO: NOTIFY ust application to update */ |
227 | /* | |
228 | ret = ustctl_create_channel(sock, usession->handle, &uattr, &obj); | |
44d3bd01 DG |
229 | if (ret < 0) { |
230 | ret = LTTCOMM_UST_CHAN_FAIL; | |
231 | goto error; | |
232 | } | |
48842b30 | 233 | */ |
f6a9efaa | 234 | |
48842b30 DG |
235 | /* |
236 | uchan->attr.overwrite = uattr.overwrite; | |
237 | uchan->attr.subbuf_size = uattr.subbuf_size; | |
238 | uchan->attr.num_subbuf = uattr.num_subbuf; | |
239 | uchan->attr.switch_timer_interval = uattr.switch_timer_interval; | |
240 | uchan->attr.read_timer_interval = uattr.read_timer_interval; | |
241 | uchan->attr.output = uattr.output; | |
242 | uchan->handle = obj->handle; | |
243 | uchan->attr.shm_fd = obj->shm_fd; | |
244 | uchan->attr.wait_fd = obj->wait_fd; | |
245 | uchan->attr.memory_map_size = obj->memory_map_size; | |
246 | uchan->obj = obj; | |
247 | */ | |
2bdd86d4 MD |
248 | |
249 | /* Add channel to session */ | |
48842b30 DG |
250 | //rcu_read_lock(); |
251 | //cds_list_add(&uchan->list, &usession->channels.head); | |
252 | //usession->channels.count++; | |
253 | //rcu_read_unlock(); | |
2bdd86d4 | 254 | |
48842b30 | 255 | //DBG2("Channel %s UST create successfully for sock:%d", uchan->name, sock); |
44d3bd01 DG |
256 | |
257 | ret = LTTCOMM_OK; | |
258 | ||
259 | error: | |
260 | return ret; | |
261 | } | |
262 | ||
263 | /* | |
264 | * Enable UST channel on the tracer. | |
265 | */ | |
266 | int channel_ust_enable(struct ltt_ust_session *usession, | |
267 | struct ltt_ust_channel *uchan, int sock) | |
268 | { | |
2bdd86d4 | 269 | int ret = LTTCOMM_OK; |
48842b30 | 270 | #ifdef DISABLE |
2bdd86d4 MD |
271 | struct object_data obj; |
272 | ||
2bdd86d4 MD |
273 | obj.shm_fd = uchan->attr.shm_fd; |
274 | obj.wait_fd = uchan->attr.wait_fd; | |
275 | obj.memory_map_size = uchan->attr.memory_map_size; | |
276 | ret = ustctl_enable(sock, &obj); | |
44d3bd01 DG |
277 | if (ret < 0) { |
278 | ret = LTTCOMM_UST_CHAN_FAIL; | |
2bdd86d4 | 279 | goto end; |
44d3bd01 | 280 | } |
44d3bd01 | 281 | ret = LTTCOMM_OK; |
2bdd86d4 | 282 | end: |
48842b30 | 283 | #endif |
44d3bd01 DG |
284 | return ret; |
285 | } | |
286 | ||
287 | /* | |
288 | * Disable UST channel on the tracer. | |
289 | */ | |
290 | int channel_ust_disable(struct ltt_ust_session *usession, | |
291 | struct ltt_ust_channel *uchan, int sock) | |
292 | { | |
2bdd86d4 | 293 | int ret = LTTCOMM_OK; |
48842b30 | 294 | #ifdef DISABLE |
2bdd86d4 MD |
295 | struct object_data obj; |
296 | ||
2bdd86d4 MD |
297 | obj.shm_fd = uchan->attr.shm_fd; |
298 | obj.wait_fd = uchan->attr.wait_fd; | |
299 | obj.memory_map_size = uchan->attr.memory_map_size; | |
300 | ret = ustctl_disable(sock, &obj); | |
44d3bd01 DG |
301 | if (ret < 0) { |
302 | ret = LTTCOMM_UST_CHAN_FAIL; | |
2bdd86d4 | 303 | goto end; |
44d3bd01 | 304 | } |
44d3bd01 | 305 | ret = LTTCOMM_OK; |
2bdd86d4 | 306 | end: |
48842b30 | 307 | #endif |
44d3bd01 DG |
308 | return ret; |
309 | } |