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