3 * Linux Trace Toolkit Netlink Control Library
5 * Controls the ltt-control kernel module through debugfs.
8 * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
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.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
27 #include <liblttctl/lttctl.h>
36 #define MAX_CHANNEL (256)
38 static char debugfsmntdir
[PATH_MAX
];
40 static int initdebugfsmntdir(void)
42 return getdebugfsmntdir(debugfsmntdir
);
46 * This function must called posterior to initdebugfsmntdir(),
47 * because it need to use debugfsmntdir[] which is inited in initdebugfsmntdir()
49 static int initmodule(void)
51 char controldirname
[PATH_MAX
];
55 sprintf(controldirname
, "%s/ltt/control/", debugfsmntdir
);
59 * Check ltt control's debugfs dir
61 * We don't check is ltt-trace-control module exist, because it maybe
62 * compiled into kernel.
64 dir
= opendir(controldirname
);
71 system("modprobe ltt-trace-control");
84 ret
= initdebugfsmntdir();
86 fprintf(stderr
, "Get debugfs mount point failed\n");
92 fprintf(stderr
, "Control module seems not work\n");
99 int lttctl_destroy(void)
104 static int lttctl_sendop(const char *fname
, const char *op
)
109 fprintf(stderr
, "%s: args invalid\n", __func__
);
113 fd
= open(fname
, O_WRONLY
);
115 fprintf(stderr
, "%s: open %s failed: %s\n", __func__
, fname
,
120 if (write(fd
, op
, strlen(op
)) == -1) {
122 fprintf(stderr
, "%s: write %s to %s failed: %s\n", __func__
, op
,
123 fname
, strerror(errno
));
134 * check is trace exist(check debugfsmntdir too)
136 * 0: expect that trace not exist
137 * !0: expect that trace exist
141 * -(EEXIST | ENOENT): check failed
142 * -ERRNO: error happened (no check)
144 static int lttctl_check_trace(const char *name
, int expect
)
146 char tracedirname
[PATH_MAX
];
151 fprintf(stderr
, "%s: args invalid\n", __func__
);
155 if (!debugfsmntdir
[0]) {
156 fprintf(stderr
, "%s: debugfsmntdir not valid\n", __func__
);
160 sprintf(tracedirname
, "%s/ltt/control/%s", debugfsmntdir
, name
);
162 dir
= opendir(tracedirname
);
167 if (errno
!= ENOENT
) {
168 fprintf(stderr
, "%s: %s\n", __func__
, strerror(errno
));
174 if (!expect
!= !exist
) {
177 fprintf(stderr
, "Trace %s already exist\n", name
);
182 fprintf(stderr
, "Trace %s not exist\n", name
);
192 * get channel list of a trace
193 * don't include metadata channel when metadata is 0
195 * return number of channel on success
196 * return negative number on fail
197 * Caller must free channellist.
199 static int lttctl_get_channellist(const char *tracename
,
200 char ***channellist
, int metadata
)
202 char tracedirname
[PATH_MAX
];
203 struct dirent
*dirent
;
205 char **list
= NULL
, **old_list
;
208 sprintf(tracedirname
, "%s/ltt/control/%s/channel", debugfsmntdir
,
211 dir
= opendir(tracedirname
);
218 dirent
= readdir(dir
);
221 if (!strcmp(dirent
->d_name
, ".")
222 || !strcmp(dirent
->d_name
, ".."))
224 if (!metadata
&& !strcmp(dirent
->d_name
, "metadata"))
227 list
= malloc(sizeof(char *) * ++nr_chan
);
228 memcpy(list
, old_list
, sizeof(*list
) * (nr_chan
- 1));
230 list
[nr_chan
- 1] = strdup(dirent
->d_name
);
243 static void lttctl_free_channellist(char **channellist
, int n_channel
)
246 for(; i
< n_channel
; ++i
)
247 free(channellist
[i
]);
251 int lttctl_setup_trace(const char *name
)
254 char ctlfname
[PATH_MAX
];
257 fprintf(stderr
, "%s: args invalid\n", __func__
);
262 ret
= lttctl_check_trace(name
, 0);
266 sprintf(ctlfname
, "%s/ltt/setup_trace", debugfsmntdir
);
268 ret
= lttctl_sendop(ctlfname
, name
);
270 fprintf(stderr
, "Setup trace failed\n");
281 int lttctl_destroy_trace(const char *name
)
284 char ctlfname
[PATH_MAX
];
287 fprintf(stderr
, "%s: args invalid\n", __func__
);
292 ret
= lttctl_check_trace(name
, 1);
296 sprintf(ctlfname
, "%s/ltt/destroy_trace", debugfsmntdir
);
298 ret
= lttctl_sendop(ctlfname
, name
);
300 fprintf(stderr
, "Destroy trace failed\n");
311 int lttctl_alloc_trace(const char *name
)
314 char ctlfname
[PATH_MAX
];
317 fprintf(stderr
, "%s: args invalid\n", __func__
);
322 ret
= lttctl_check_trace(name
, 1);
326 sprintf(ctlfname
, "%s/ltt/control/%s/alloc", debugfsmntdir
, name
);
328 ret
= lttctl_sendop(ctlfname
, "1");
330 fprintf(stderr
, "Allocate trace failed\n");
341 int lttctl_start(const char *name
)
344 char ctlfname
[PATH_MAX
];
347 fprintf(stderr
, "%s: args invalid\n", __func__
);
352 ret
= lttctl_check_trace(name
, 1);
356 sprintf(ctlfname
, "%s/ltt/control/%s/enabled", debugfsmntdir
, name
);
358 ret
= lttctl_sendop(ctlfname
, "1");
360 fprintf(stderr
, "Start trace failed\n");
371 int lttctl_pause(const char *name
)
374 char ctlfname
[PATH_MAX
];
377 fprintf(stderr
, "%s: args invalid\n", __func__
);
382 ret
= lttctl_check_trace(name
, 1);
386 sprintf(ctlfname
, "%s/ltt/control/%s/enabled", debugfsmntdir
, name
);
388 ret
= lttctl_sendop(ctlfname
, "0");
390 fprintf(stderr
, "Pause trace failed\n");
401 int lttctl_set_trans(const char *name
, const char *trans
)
404 char ctlfname
[PATH_MAX
];
407 fprintf(stderr
, "%s: args invalid\n", __func__
);
412 ret
= lttctl_check_trace(name
, 1);
416 sprintf(ctlfname
, "%s/ltt/control/%s/trans", debugfsmntdir
, name
);
418 ret
= lttctl_sendop(ctlfname
, trans
);
420 fprintf(stderr
, "Set transport failed\n");
431 static int __lttctl_set_channel_enable(const char *name
, const char *channel
,
435 char ctlfname
[PATH_MAX
];
437 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/enable", debugfsmntdir
,
440 ret
= lttctl_sendop(ctlfname
, enable
? "1" : "0");
442 fprintf(stderr
, "Set channel's enable mode failed\n");
447 int lttctl_set_channel_enable(const char *name
, const char *channel
,
454 if (!name
|| !channel
) {
455 fprintf(stderr
, "%s: args invalid\n", __func__
);
460 ret
= lttctl_check_trace(name
, 1);
464 if (strcmp(channel
, "all")) {
465 ret
= __lttctl_set_channel_enable(name
, channel
, enable
);
469 /* Don't allow set enable state for metadata channel */
470 n_channel
= lttctl_get_channellist(name
, &channellist
, 0);
472 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
478 for (; n_channel
> 0; n_channel
--) {
479 ret
= __lttctl_set_channel_enable(name
,
480 channellist
[n_channel
- 1], enable
);
484 lttctl_free_channellist(channellist
, n_channel
);
490 lttctl_free_channellist(channellist
, n_channel
);
496 static int __lttctl_set_channel_overwrite(const char *name
, const char *channel
,
500 char ctlfname
[PATH_MAX
];
502 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/overwrite",
503 debugfsmntdir
, name
, channel
);
505 ret
= lttctl_sendop(ctlfname
, overwrite
? "1" : "0");
507 fprintf(stderr
, "Set channel's overwrite mode failed\n");
511 int lttctl_set_channel_overwrite(const char *name
, const char *channel
,
518 if (!name
|| !channel
) {
519 fprintf(stderr
, "%s: args invalid\n", __func__
);
524 ret
= lttctl_check_trace(name
, 1);
528 if (strcmp(channel
, "all")) {
529 ret
= __lttctl_set_channel_overwrite(name
, channel
, overwrite
);
533 /* Don't allow set overwrite for metadata channel */
534 n_channel
= lttctl_get_channellist(name
, &channellist
, 0);
536 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
542 for (; n_channel
> 0; n_channel
--) {
543 ret
= __lttctl_set_channel_overwrite(name
,
544 channellist
[n_channel
- 1], overwrite
);
548 lttctl_free_channellist(channellist
, n_channel
);
554 lttctl_free_channellist(channellist
, n_channel
);
560 static int __lttctl_set_channel_subbuf_num(const char *name
,
561 const char *channel
, unsigned subbuf_num
)
564 char ctlfname
[PATH_MAX
];
567 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/subbuf_num",
568 debugfsmntdir
, name
, channel
);
570 sprintf(opstr
, "%u", subbuf_num
);
572 ret
= lttctl_sendop(ctlfname
, opstr
);
574 fprintf(stderr
, "Set channel's subbuf number failed\n");
578 int lttctl_set_channel_subbuf_num(const char *name
, const char *channel
,
585 if (!name
|| !channel
) {
586 fprintf(stderr
, "%s: args invalid\n", __func__
);
591 ret
= lttctl_check_trace(name
, 1);
595 if (strcmp(channel
, "all")) {
596 ret
= __lttctl_set_channel_subbuf_num(name
, channel
,
601 /* allow set subbuf_num for metadata channel */
602 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
604 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
610 for (; n_channel
> 0; n_channel
--) {
611 ret
= __lttctl_set_channel_subbuf_num(name
,
612 channellist
[n_channel
- 1], subbuf_num
);
616 lttctl_free_channellist(channellist
, n_channel
);
622 lttctl_free_channellist(channellist
, n_channel
);
628 static int __lttctl_set_channel_subbuf_size(const char *name
,
629 const char *channel
, unsigned subbuf_size
)
632 char ctlfname
[PATH_MAX
];
635 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/subbuf_size",
636 debugfsmntdir
, name
, channel
);
638 sprintf(opstr
, "%u", subbuf_size
);
640 ret
= lttctl_sendop(ctlfname
, opstr
);
642 fprintf(stderr
, "Set channel's subbuf size failed\n");
646 int lttctl_set_channel_subbuf_size(const char *name
, const char *channel
,
647 unsigned subbuf_size
)
653 if (!name
|| !channel
) {
654 fprintf(stderr
, "%s: args invalid\n", __func__
);
659 ret
= lttctl_check_trace(name
, 1);
663 if (strcmp(channel
, "all")) {
664 ret
= __lttctl_set_channel_subbuf_size(name
, channel
,
669 /* allow set subbuf_size for metadata channel */
670 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
672 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
678 for (; n_channel
> 0; n_channel
--) {
679 ret
= __lttctl_set_channel_subbuf_size(name
,
680 channellist
[n_channel
- 1], subbuf_size
);
684 lttctl_free_channellist(channellist
, n_channel
);
690 lttctl_free_channellist(channellist
, n_channel
);
696 static int __lttctl_set_channel_switch_timer(const char *name
,
697 const char *channel
, unsigned switch_timer
)
700 char ctlfname
[PATH_MAX
];
703 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/switch_timer",
704 debugfsmntdir
, name
, channel
);
706 sprintf(opstr
, "%u", switch_timer
);
708 ret
= lttctl_sendop(ctlfname
, opstr
);
710 fprintf(stderr
, "Set channel's switch timer failed\n");
714 int lttctl_set_channel_switch_timer(const char *name
, const char *channel
,
715 unsigned switch_timer
)
721 if (!name
|| !channel
) {
722 fprintf(stderr
, "%s: args invalid\n", __func__
);
727 ret
= lttctl_check_trace(name
, 1);
731 if (strcmp(channel
, "all")) {
732 ret
= __lttctl_set_channel_subbuf_size(name
, channel
,
737 /* allow set subbuf_size for metadata channel */
738 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
740 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
746 for (; n_channel
> 0; n_channel
--) {
747 ret
= __lttctl_set_channel_switch_timer(name
,
748 channellist
[n_channel
- 1], switch_timer
);
752 lttctl_free_channellist(channellist
, n_channel
);
758 lttctl_free_channellist(channellist
, n_channel
);
764 int getdebugfsmntdir(char *mntdir
)
766 char mnt_dir
[PATH_MAX
];
767 char mnt_type
[PATH_MAX
];
768 int trymount_done
= 0;
770 FILE *fp
= fopen("/proc/mounts", "r");
776 if (fscanf(fp
, "%*s %s %s %*s %*s %*s", mnt_dir
, mnt_type
) <= 0)
779 if (!strcmp(mnt_type
, "debugfs")) {
780 strcpy(mntdir
, mnt_dir
);
785 if (!trymount_done
) {
786 mount("debugfs", "/sys/kernel/debug/", "debugfs", 0, NULL
);
This page took 0.045532 seconds and 4 git commands to generate.