31d2c6b0 |
1 | /* libltt |
2 | * |
3 | * Linux Trace Toolkit Netlink Control Library |
4 | * |
64ba9405 |
5 | * Controls the ltt-control kernel module through debugfs. |
31d2c6b0 |
6 | * |
7 | * Copyright 2005 - |
8 | * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> |
9 | * |
10 | * |
11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. |
15 | * |
16 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
e59e4125 |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
31d2c6b0 |
19 | * GNU General Public License for more details. |
64ba9405 |
20 | * |
31d2c6b0 |
21 | */ |
22 | |
4e4d11b3 |
23 | #ifdef HAVE_CONFIG_H |
24 | #include <config.h> |
25 | #endif |
26 | |
e7e15834 |
27 | #include <liblttctl/lttctl.h> |
ace0e68d |
28 | #include <errno.h> |
29 | #include <stdio.h> |
5e5b1de1 |
30 | #include <string.h> |
64ba9405 |
31 | #include <dirent.h> |
32 | #include <limits.h> |
33 | #include <fcntl.h> |
34 | #include <stdlib.h> |
5e5b1de1 |
35 | |
64ba9405 |
36 | #define MAX_CHANNEL (256) |
31d2c6b0 |
37 | |
64ba9405 |
38 | static char debugfsmntdir[PATH_MAX]; |
c589e8b1 |
39 | |
64ba9405 |
40 | static int initdebugfsmntdir(void) |
31d2c6b0 |
41 | { |
ddc3e631 |
42 | return getdebugfsmntdir(debugfsmntdir); |
43 | } |
31d2c6b0 |
44 | |
ddc3e631 |
45 | /* |
46 | * This function must called posterior to initdebugfsmntdir(), |
47 | * because it need to use debugfsmntdir[] which is inited in initdebugfsmntdir() |
48 | */ |
49 | static int initmodule(void) |
50 | { |
51 | char controldirname[PATH_MAX]; |
52 | DIR *dir; |
53 | int tryload_done = 0; |
54 | |
55 | sprintf(controldirname, "%s/ltt/control/", debugfsmntdir); |
56 | |
57 | check_again: |
58 | /* |
59 | * Check ltt control's debugfs dir |
60 | * |
61 | * We don't check is ltt-trace-control module exist, because it maybe |
62 | * compiled into kernel. |
63 | */ |
64 | dir = opendir(controldirname); |
65 | if (dir) { |
66 | closedir(dir); |
67 | return 0; |
64ba9405 |
68 | } |
31d2c6b0 |
69 | |
ddc3e631 |
70 | if (!tryload_done) { |
71 | system("modprobe ltt-trace-control"); |
72 | tryload_done = 1; |
73 | goto check_again; |
31d2c6b0 |
74 | } |
ddc3e631 |
75 | |
76 | return -ENOENT; |
64ba9405 |
77 | } |
78 | |
79 | int lttctl_init(void) |
80 | { |
81 | int ret; |
ddc3e631 |
82 | |
64ba9405 |
83 | |
84 | ret = initdebugfsmntdir(); |
85 | if (ret) { |
ddc3e631 |
86 | fprintf(stderr, "Get debugfs mount point failed\n"); |
936d4065 |
87 | return ret; |
31d2c6b0 |
88 | } |
ace0e68d |
89 | |
ddc3e631 |
90 | ret = initmodule(); |
91 | if (ret) { |
92 | fprintf(stderr, "Control module seems not work\n"); |
936d4065 |
93 | return ret; |
64ba9405 |
94 | } |
31d2c6b0 |
95 | |
64ba9405 |
96 | return 0; |
97 | } |
31d2c6b0 |
98 | |
64ba9405 |
99 | int lttctl_destroy(void) |
ace0e68d |
100 | { |
64ba9405 |
101 | return 0; |
ace0e68d |
102 | } |
103 | |
64ba9405 |
104 | static int lttctl_sendop(const char *fname, const char *op) |
ace0e68d |
105 | { |
64ba9405 |
106 | int fd; |
107 | |
108 | if (!fname) { |
109 | fprintf(stderr, "%s: args invalid\n", __func__); |
110 | return 1; |
111 | } |
112 | |
113 | fd = open(fname, O_WRONLY); |
114 | if (fd == -1) { |
115 | fprintf(stderr, "%s: open %s failed: %s\n", __func__, fname, |
116 | strerror(errno)); |
117 | return errno; |
118 | } |
119 | |
120 | if (write(fd, op, strlen(op)) == -1) { |
936d4065 |
121 | int ret = errno; |
64ba9405 |
122 | fprintf(stderr, "%s: write %s to %s failed: %s\n", __func__, op, |
123 | fname, strerror(errno)); |
124 | close(fd); |
936d4065 |
125 | return ret; |
64ba9405 |
126 | } |
31d2c6b0 |
127 | |
64ba9405 |
128 | close(fd); |
129 | |
130 | return 0; |
131 | } |
31d2c6b0 |
132 | |
133 | /* |
64ba9405 |
134 | * check is trace exist(check debugfsmntdir too) |
135 | * expect: |
136 | * 0: expect that trace not exist |
137 | * !0: expect that trace exist |
138 | * |
139 | * ret: |
140 | * 0: check pass |
936d4065 |
141 | * -(EEXIST | ENOENT): check failed |
64ba9405 |
142 | * -ERRNO: error happened (no check) |
31d2c6b0 |
143 | */ |
64ba9405 |
144 | static int lttctl_check_trace(const char *name, int expect) |
31d2c6b0 |
145 | { |
64ba9405 |
146 | char tracedirname[PATH_MAX]; |
147 | DIR *dir; |
148 | int exist; |
31d2c6b0 |
149 | |
64ba9405 |
150 | if (!name) { |
151 | fprintf(stderr, "%s: args invalid\n", __func__); |
152 | return -EINVAL; |
31d2c6b0 |
153 | } |
64ba9405 |
154 | |
155 | if (!debugfsmntdir[0]) { |
156 | fprintf(stderr, "%s: debugfsmntdir not valid\n", __func__); |
157 | return -EINVAL; |
158 | } |
159 | |
160 | sprintf(tracedirname, "%s/ltt/control/%s", debugfsmntdir, name); |
161 | |
162 | dir = opendir(tracedirname); |
163 | if (dir) { |
164 | exist = 1; |
165 | } else { |
166 | if (errno != ENOENT) { |
167 | fprintf(stderr, "%s: %s\n", __func__, strerror(errno)); |
168 | return -EINVAL; |
169 | } |
170 | exist = 0; |
171 | } |
172 | |
173 | closedir(dir); |
174 | |
175 | if (!expect != !exist) { |
176 | if (exist) |
936d4065 |
177 | { |
64ba9405 |
178 | fprintf(stderr, "Trace %s already exist\n", name); |
936d4065 |
179 | return -EEXIST; |
180 | } |
64ba9405 |
181 | else |
936d4065 |
182 | { |
64ba9405 |
183 | fprintf(stderr, "Trace %s not exist\n", name); |
936d4065 |
184 | return -ENOENT; |
185 | } |
186 | |
64ba9405 |
187 | } |
188 | |
189 | return 0; |
31d2c6b0 |
190 | } |
191 | |
192 | /* |
64ba9405 |
193 | * get channel list of a trace |
194 | * don't include metadata channel when metadata is 0 |
195 | * |
196 | * return number of channel on success |
197 | * return negative number on fail |
198 | * Caller must free channellist. |
31d2c6b0 |
199 | */ |
64ba9405 |
200 | static int lttctl_get_channellist(const char *tracename, |
201 | char ***channellist, int metadata) |
31d2c6b0 |
202 | { |
64ba9405 |
203 | char tracedirname[PATH_MAX]; |
204 | struct dirent *dirent; |
205 | DIR *dir; |
206 | char **list = NULL, **old_list; |
207 | int nr_chan = 0; |
208 | |
209 | sprintf(tracedirname, "%s/ltt/control/%s/channel", debugfsmntdir, |
210 | tracename); |
211 | |
212 | dir = opendir(tracedirname); |
213 | if (!dir) { |
214 | nr_chan = -ENOENT; |
215 | goto error; |
216 | } |
217 | |
218 | for (;;) { |
219 | dirent = readdir(dir); |
220 | if (!dirent) |
221 | break; |
222 | if (!strcmp(dirent->d_name, ".") |
223 | || !strcmp(dirent->d_name, "..")) |
224 | continue; |
225 | if (!metadata && !strcmp(dirent->d_name, "metadata")) |
226 | continue; |
227 | old_list = list; |
228 | list = malloc(sizeof(char *) * ++nr_chan); |
229 | memcpy(list, old_list, sizeof(*list) * (nr_chan - 1)); |
230 | free(old_list); |
231 | list[nr_chan - 1] = strdup(dirent->d_name); |
232 | } |
233 | |
234 | closedir(dir); |
235 | |
236 | *channellist = list; |
237 | return nr_chan; |
238 | error: |
239 | free(list); |
240 | *channellist = NULL; |
241 | return nr_chan; |
242 | } |
243 | |
936d4065 |
244 | static void lttctl_free_channellist(char **channellist, int n_channel) |
245 | { |
246 | int i = 0; |
247 | for(; i < n_channel; ++i) |
248 | free(channellist[i]); |
249 | free(channellist); |
250 | } |
251 | |
64ba9405 |
252 | int lttctl_setup_trace(const char *name) |
253 | { |
254 | int ret; |
255 | char ctlfname[PATH_MAX]; |
256 | |
257 | if (!name) { |
258 | fprintf(stderr, "%s: args invalid\n", __func__); |
259 | ret = -EINVAL; |
260 | goto arg_error; |
261 | } |
262 | |
263 | ret = lttctl_check_trace(name, 0); |
264 | if (ret) |
265 | goto arg_error; |
266 | |
267 | sprintf(ctlfname, "%s/ltt/setup_trace", debugfsmntdir); |
268 | |
269 | ret = lttctl_sendop(ctlfname, name); |
270 | if (ret) { |
271 | fprintf(stderr, "Setup trace failed\n"); |
272 | goto op_err; |
31d2c6b0 |
273 | } |
64ba9405 |
274 | |
31d2c6b0 |
275 | return 0; |
64ba9405 |
276 | |
277 | op_err: |
278 | arg_error: |
279 | return ret; |
31d2c6b0 |
280 | } |
281 | |
64ba9405 |
282 | int lttctl_destroy_trace(const char *name) |
283 | { |
284 | int ret; |
285 | char ctlfname[PATH_MAX]; |
286 | |
287 | if (!name) { |
288 | fprintf(stderr, "%s: args invalid\n", __func__); |
289 | ret = -EINVAL; |
290 | goto arg_error; |
291 | } |
292 | |
293 | ret = lttctl_check_trace(name, 1); |
294 | if (ret) |
295 | goto arg_error; |
296 | |
297 | sprintf(ctlfname, "%s/ltt/destroy_trace", debugfsmntdir); |
298 | |
299 | ret = lttctl_sendop(ctlfname, name); |
300 | if (ret) { |
301 | fprintf(stderr, "Destroy trace failed\n"); |
302 | goto op_err; |
303 | } |
304 | |
305 | return 0; |
306 | |
307 | op_err: |
308 | arg_error: |
309 | return ret; |
310 | } |
31d2c6b0 |
311 | |
64ba9405 |
312 | int lttctl_alloc_trace(const char *name) |
31d2c6b0 |
313 | { |
64ba9405 |
314 | int ret; |
315 | char ctlfname[PATH_MAX]; |
316 | |
317 | if (!name) { |
318 | fprintf(stderr, "%s: args invalid\n", __func__); |
319 | ret = -EINVAL; |
320 | goto arg_error; |
321 | } |
322 | |
323 | ret = lttctl_check_trace(name, 1); |
324 | if (ret) |
325 | goto arg_error; |
326 | |
327 | sprintf(ctlfname, "%s/ltt/control/%s/alloc", debugfsmntdir, name); |
328 | |
329 | ret = lttctl_sendop(ctlfname, "1"); |
330 | if (ret) { |
331 | fprintf(stderr, "Allocate trace failed\n"); |
332 | goto op_err; |
333 | } |
334 | |
335 | return 0; |
336 | |
337 | op_err: |
338 | arg_error: |
339 | return ret; |
340 | } |
341 | |
342 | int lttctl_start(const char *name) |
343 | { |
344 | int ret; |
345 | char ctlfname[PATH_MAX]; |
346 | |
347 | if (!name) { |
348 | fprintf(stderr, "%s: args invalid\n", __func__); |
349 | ret = -EINVAL; |
350 | goto arg_error; |
351 | } |
352 | |
353 | ret = lttctl_check_trace(name, 1); |
354 | if (ret) |
355 | goto arg_error; |
356 | |
357 | sprintf(ctlfname, "%s/ltt/control/%s/enabled", debugfsmntdir, name); |
358 | |
359 | ret = lttctl_sendop(ctlfname, "1"); |
360 | if (ret) { |
361 | fprintf(stderr, "Start trace failed\n"); |
362 | goto op_err; |
ace0e68d |
363 | } |
364 | |
365 | return 0; |
366 | |
64ba9405 |
367 | op_err: |
368 | arg_error: |
369 | return ret; |
31d2c6b0 |
370 | } |
371 | |
64ba9405 |
372 | int lttctl_pause(const char *name) |
31d2c6b0 |
373 | { |
64ba9405 |
374 | int ret; |
375 | char ctlfname[PATH_MAX]; |
376 | |
377 | if (!name) { |
378 | fprintf(stderr, "%s: args invalid\n", __func__); |
379 | ret = -EINVAL; |
380 | goto arg_error; |
381 | } |
382 | |
383 | ret = lttctl_check_trace(name, 1); |
384 | if (ret) |
385 | goto arg_error; |
386 | |
387 | sprintf(ctlfname, "%s/ltt/control/%s/enabled", debugfsmntdir, name); |
388 | |
389 | ret = lttctl_sendop(ctlfname, "0"); |
390 | if (ret) { |
391 | fprintf(stderr, "Pause trace failed\n"); |
392 | goto op_err; |
ace0e68d |
393 | } |
394 | |
395 | return 0; |
396 | |
64ba9405 |
397 | op_err: |
398 | arg_error: |
399 | return ret; |
400 | } |
401 | |
402 | int lttctl_set_trans(const char *name, const char *trans) |
403 | { |
404 | int ret; |
405 | char ctlfname[PATH_MAX]; |
406 | |
407 | if (!name) { |
408 | fprintf(stderr, "%s: args invalid\n", __func__); |
409 | ret = -EINVAL; |
410 | goto arg_error; |
411 | } |
412 | |
413 | ret = lttctl_check_trace(name, 1); |
414 | if (ret) |
415 | goto arg_error; |
416 | |
417 | sprintf(ctlfname, "%s/ltt/control/%s/trans", debugfsmntdir, name); |
ace0e68d |
418 | |
64ba9405 |
419 | ret = lttctl_sendop(ctlfname, trans); |
420 | if (ret) { |
421 | fprintf(stderr, "Set transport failed\n"); |
422 | goto op_err; |
423 | } |
424 | |
425 | return 0; |
426 | |
427 | op_err: |
428 | arg_error: |
429 | return ret; |
31d2c6b0 |
430 | } |
431 | |
64ba9405 |
432 | static int __lttctl_set_channel_enable(const char *name, const char *channel, |
433 | int enable) |
31d2c6b0 |
434 | { |
64ba9405 |
435 | int ret; |
436 | char ctlfname[PATH_MAX]; |
ace0e68d |
437 | |
64ba9405 |
438 | sprintf(ctlfname, "%s/ltt/control/%s/channel/%s/enable", debugfsmntdir, |
439 | name, channel); |
31d2c6b0 |
440 | |
64ba9405 |
441 | ret = lttctl_sendop(ctlfname, enable ? "1" : "0"); |
442 | if (ret) |
443 | fprintf(stderr, "Set channel's enable mode failed\n"); |
31d2c6b0 |
444 | |
64ba9405 |
445 | return ret; |
446 | } |
447 | int lttctl_set_channel_enable(const char *name, const char *channel, |
448 | int enable) |
449 | { |
450 | int ret; |
936d4065 |
451 | char **channellist; |
452 | int n_channel; |
31d2c6b0 |
453 | |
64ba9405 |
454 | if (!name || !channel) { |
455 | fprintf(stderr, "%s: args invalid\n", __func__); |
456 | ret = -EINVAL; |
457 | goto arg_error; |
458 | } |
ace0e68d |
459 | |
64ba9405 |
460 | ret = lttctl_check_trace(name, 1); |
461 | if (ret) |
462 | goto arg_error; |
463 | |
464 | if (strcmp(channel, "all")) { |
465 | ret = __lttctl_set_channel_enable(name, channel, enable); |
466 | if (ret) |
467 | goto op_err; |
468 | } else { |
64ba9405 |
469 | /* Don't allow set enable state for metadata channel */ |
470 | n_channel = lttctl_get_channellist(name, &channellist, 0); |
471 | if (n_channel < 0) { |
472 | fprintf(stderr, "%s: lttctl_get_channellist failed\n", |
473 | __func__); |
474 | ret = -ENOENT; |
475 | goto op_err; |
476 | } |
ace0e68d |
477 | |
64ba9405 |
478 | for (; n_channel > 0; n_channel--) { |
479 | ret = __lttctl_set_channel_enable(name, |
480 | channellist[n_channel - 1], enable); |
481 | if (ret) |
936d4065 |
482 | goto op_err_clean; |
64ba9405 |
483 | } |
936d4065 |
484 | lttctl_free_channellist(channellist, n_channel); |
ace0e68d |
485 | } |
486 | |
487 | return 0; |
488 | |
936d4065 |
489 | op_err_clean: |
490 | lttctl_free_channellist(channellist, n_channel); |
64ba9405 |
491 | op_err: |
492 | arg_error: |
493 | return ret; |
494 | } |
495 | |
496 | static int __lttctl_set_channel_overwrite(const char *name, const char *channel, |
497 | int overwrite) |
498 | { |
499 | int ret; |
500 | char ctlfname[PATH_MAX]; |
501 | |
502 | sprintf(ctlfname, "%s/ltt/control/%s/channel/%s/overwrite", |
503 | debugfsmntdir, name, channel); |
504 | |
505 | ret = lttctl_sendop(ctlfname, overwrite ? "1" : "0"); |
506 | if (ret) |
507 | fprintf(stderr, "Set channel's overwrite mode failed\n"); |
508 | |
509 | return ret; |
510 | } |
511 | int lttctl_set_channel_overwrite(const char *name, const char *channel, |
512 | int overwrite) |
513 | { |
514 | int ret; |
936d4065 |
515 | char **channellist; |
516 | int n_channel; |
64ba9405 |
517 | |
518 | if (!name || !channel) { |
519 | fprintf(stderr, "%s: args invalid\n", __func__); |
520 | ret = -EINVAL; |
521 | goto arg_error; |
522 | } |
523 | |
524 | ret = lttctl_check_trace(name, 1); |
525 | if (ret) |
526 | goto arg_error; |
527 | |
528 | if (strcmp(channel, "all")) { |
529 | ret = __lttctl_set_channel_overwrite(name, channel, overwrite); |
530 | if (ret) |
531 | goto op_err; |
532 | } else { |
64ba9405 |
533 | /* Don't allow set overwrite for metadata channel */ |
534 | n_channel = lttctl_get_channellist(name, &channellist, 0); |
535 | if (n_channel < 0) { |
536 | fprintf(stderr, "%s: lttctl_get_channellist failed\n", |
537 | __func__); |
538 | ret = -ENOENT; |
539 | goto op_err; |
540 | } |
541 | |
542 | for (; n_channel > 0; n_channel--) { |
543 | ret = __lttctl_set_channel_overwrite(name, |
544 | channellist[n_channel - 1], overwrite); |
545 | if (ret) |
936d4065 |
546 | goto op_err_clean; |
64ba9405 |
547 | } |
936d4065 |
548 | lttctl_free_channellist(channellist, n_channel); |
64ba9405 |
549 | } |
550 | |
551 | return 0; |
ace0e68d |
552 | |
936d4065 |
553 | op_err_clean: |
554 | lttctl_free_channellist(channellist, n_channel); |
64ba9405 |
555 | op_err: |
556 | arg_error: |
557 | return ret; |
31d2c6b0 |
558 | } |
559 | |
64ba9405 |
560 | static int __lttctl_set_channel_subbuf_num(const char *name, |
561 | const char *channel, unsigned subbuf_num) |
562 | { |
563 | int ret; |
564 | char ctlfname[PATH_MAX]; |
565 | char opstr[32]; |
566 | |
567 | sprintf(ctlfname, "%s/ltt/control/%s/channel/%s/subbuf_num", |
568 | debugfsmntdir, name, channel); |
569 | |
570 | sprintf(opstr, "%u", subbuf_num); |
571 | |
572 | ret = lttctl_sendop(ctlfname, opstr); |
573 | if (ret) |
574 | fprintf(stderr, "Set channel's subbuf number failed\n"); |
575 | |
576 | return ret; |
577 | } |
578 | int lttctl_set_channel_subbuf_num(const char *name, const char *channel, |
579 | unsigned subbuf_num) |
31d2c6b0 |
580 | { |
64ba9405 |
581 | int ret; |
936d4065 |
582 | char **channellist; |
583 | int n_channel; |
64ba9405 |
584 | |
585 | if (!name || !channel) { |
586 | fprintf(stderr, "%s: args invalid\n", __func__); |
587 | ret = -EINVAL; |
588 | goto arg_error; |
589 | } |
590 | |
591 | ret = lttctl_check_trace(name, 1); |
592 | if (ret) |
593 | goto arg_error; |
594 | |
595 | if (strcmp(channel, "all")) { |
596 | ret = __lttctl_set_channel_subbuf_num(name, channel, |
597 | subbuf_num); |
598 | if (ret) |
599 | goto op_err; |
600 | } else { |
64ba9405 |
601 | /* allow set subbuf_num for metadata channel */ |
602 | n_channel = lttctl_get_channellist(name, &channellist, 1); |
603 | if (n_channel < 0) { |
604 | fprintf(stderr, "%s: lttctl_get_channellist failed\n", |
605 | __func__); |
606 | ret = -ENOENT; |
607 | goto op_err; |
608 | } |
609 | |
610 | for (; n_channel > 0; n_channel--) { |
611 | ret = __lttctl_set_channel_subbuf_num(name, |
612 | channellist[n_channel - 1], subbuf_num); |
613 | if (ret) |
936d4065 |
614 | goto op_err_clean; |
64ba9405 |
615 | } |
936d4065 |
616 | lttctl_free_channellist(channellist, n_channel); |
ace0e68d |
617 | } |
618 | |
619 | return 0; |
620 | |
936d4065 |
621 | op_err_clean: |
622 | lttctl_free_channellist(channellist, n_channel); |
64ba9405 |
623 | op_err: |
624 | arg_error: |
625 | return ret; |
626 | } |
627 | |
628 | static int __lttctl_set_channel_subbuf_size(const char *name, |
629 | const char *channel, unsigned subbuf_size) |
630 | { |
631 | int ret; |
632 | char ctlfname[PATH_MAX]; |
633 | char opstr[32]; |
634 | |
635 | sprintf(ctlfname, "%s/ltt/control/%s/channel/%s/subbuf_size", |
636 | debugfsmntdir, name, channel); |
637 | |
638 | sprintf(opstr, "%u", subbuf_size); |
639 | |
640 | ret = lttctl_sendop(ctlfname, opstr); |
641 | if (ret) |
642 | fprintf(stderr, "Set channel's subbuf size failed\n"); |
31d2c6b0 |
643 | } |
64ba9405 |
644 | int lttctl_set_channel_subbuf_size(const char *name, const char *channel, |
645 | unsigned subbuf_size) |
646 | { |
647 | int ret; |
936d4065 |
648 | char **channellist; |
649 | int n_channel; |
fde1a29a |
650 | |
64ba9405 |
651 | if (!name || !channel) { |
652 | fprintf(stderr, "%s: args invalid\n", __func__); |
653 | ret = -EINVAL; |
654 | goto arg_error; |
655 | } |
656 | |
657 | ret = lttctl_check_trace(name, 1); |
658 | if (ret) |
659 | goto arg_error; |
660 | |
661 | if (strcmp(channel, "all")) { |
662 | ret = __lttctl_set_channel_subbuf_size(name, channel, |
663 | subbuf_size); |
664 | if (ret) |
665 | goto op_err; |
666 | } else { |
64ba9405 |
667 | /* allow set subbuf_size for metadata channel */ |
668 | n_channel = lttctl_get_channellist(name, &channellist, 1); |
669 | if (n_channel < 0) { |
670 | fprintf(stderr, "%s: lttctl_get_channellist failed\n", |
671 | __func__); |
672 | ret = -ENOENT; |
673 | goto op_err; |
674 | } |
675 | |
676 | for (; n_channel > 0; n_channel--) { |
677 | ret = __lttctl_set_channel_subbuf_size(name, |
678 | channellist[n_channel - 1], subbuf_size); |
679 | if (ret) |
936d4065 |
680 | goto op_err_clean; |
64ba9405 |
681 | } |
936d4065 |
682 | lttctl_free_channellist(channellist, n_channel); |
64ba9405 |
683 | } |
684 | |
685 | return 0; |
686 | |
936d4065 |
687 | op_err_clean: |
688 | lttctl_free_channellist(channellist, n_channel); |
64ba9405 |
689 | op_err: |
690 | arg_error: |
691 | return ret; |
692 | } |
ddc3e631 |
693 | |
694 | int getdebugfsmntdir(char *mntdir) |
695 | { |
696 | char mnt_dir[PATH_MAX]; |
697 | char mnt_type[PATH_MAX]; |
698 | int trymount_done = 0; |
699 | |
700 | FILE *fp = fopen("/proc/mounts", "r"); |
701 | if (!fp) |
702 | return -EINVAL; |
703 | |
704 | find_again: |
705 | while (1) { |
706 | if (fscanf(fp, "%*s %s %s %*s %*s %*s", mnt_dir, mnt_type) <= 0) |
707 | break; |
708 | |
709 | if (!strcmp(mnt_type, "debugfs")) { |
710 | strcpy(mntdir, mnt_dir); |
711 | return 0; |
712 | } |
713 | } |
714 | |
715 | if (!trymount_done) { |
716 | mount("debugfs", "/sys/kernel/debug/", "debugfs", 0, NULL); |
717 | trymount_done = 1; |
718 | goto find_again; |
719 | } |
720 | |
721 | return -ENOENT; |
722 | } |