e9f4f180e0728e52ccf76f7902ca4a65d5c8db48
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");
446 int lttctl_set_channel_enable(const char *name
, const char *channel
,
453 if (!name
|| !channel
) {
454 fprintf(stderr
, "%s: args invalid\n", __func__
);
459 ret
= lttctl_check_trace(name
, 1);
463 if (strcmp(channel
, "all")) {
464 ret
= __lttctl_set_channel_enable(name
, channel
, enable
);
468 /* Don't allow set enable state for metadata channel */
469 n_channel
= lttctl_get_channellist(name
, &channellist
, 0);
471 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
477 for (; n_channel
> 0; n_channel
--) {
478 ret
= __lttctl_set_channel_enable(name
,
479 channellist
[n_channel
- 1], enable
);
483 lttctl_free_channellist(channellist
, n_channel
);
489 lttctl_free_channellist(channellist
, n_channel
);
495 static int __lttctl_set_channel_overwrite(const char *name
, const char *channel
,
499 char ctlfname
[PATH_MAX
];
501 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/overwrite",
502 debugfsmntdir
, name
, channel
);
504 ret
= lttctl_sendop(ctlfname
, overwrite
? "1" : "0");
506 fprintf(stderr
, "Set channel's overwrite mode failed\n");
510 int lttctl_set_channel_overwrite(const char *name
, const char *channel
,
517 if (!name
|| !channel
) {
518 fprintf(stderr
, "%s: args invalid\n", __func__
);
523 ret
= lttctl_check_trace(name
, 1);
527 if (strcmp(channel
, "all")) {
528 ret
= __lttctl_set_channel_overwrite(name
, channel
, overwrite
);
532 /* Don't allow set overwrite for metadata channel */
533 n_channel
= lttctl_get_channellist(name
, &channellist
, 0);
535 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
541 for (; n_channel
> 0; n_channel
--) {
542 ret
= __lttctl_set_channel_overwrite(name
,
543 channellist
[n_channel
- 1], overwrite
);
547 lttctl_free_channellist(channellist
, n_channel
);
553 lttctl_free_channellist(channellist
, n_channel
);
559 static int __lttctl_set_channel_subbuf_num(const char *name
,
560 const char *channel
, unsigned subbuf_num
)
563 char ctlfname
[PATH_MAX
];
566 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/subbuf_num",
567 debugfsmntdir
, name
, channel
);
569 sprintf(opstr
, "%u", subbuf_num
);
571 ret
= lttctl_sendop(ctlfname
, opstr
);
573 fprintf(stderr
, "Set channel's subbuf number failed\n");
577 int lttctl_set_channel_subbuf_num(const char *name
, const char *channel
,
584 if (!name
|| !channel
) {
585 fprintf(stderr
, "%s: args invalid\n", __func__
);
590 ret
= lttctl_check_trace(name
, 1);
594 if (strcmp(channel
, "all")) {
595 ret
= __lttctl_set_channel_subbuf_num(name
, channel
,
600 /* allow set subbuf_num for metadata channel */
601 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
603 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
609 for (; n_channel
> 0; n_channel
--) {
610 ret
= __lttctl_set_channel_subbuf_num(name
,
611 channellist
[n_channel
- 1], subbuf_num
);
615 lttctl_free_channellist(channellist
, n_channel
);
621 lttctl_free_channellist(channellist
, n_channel
);
627 static int __lttctl_set_channel_subbuf_size(const char *name
,
628 const char *channel
, unsigned subbuf_size
)
631 char ctlfname
[PATH_MAX
];
634 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/subbuf_size",
635 debugfsmntdir
, name
, channel
);
637 sprintf(opstr
, "%u", subbuf_size
);
639 ret
= lttctl_sendop(ctlfname
, opstr
);
641 fprintf(stderr
, "Set channel's subbuf size failed\n");
644 int lttctl_set_channel_subbuf_size(const char *name
, const char *channel
,
645 unsigned subbuf_size
)
651 if (!name
|| !channel
) {
652 fprintf(stderr
, "%s: args invalid\n", __func__
);
657 ret
= lttctl_check_trace(name
, 1);
661 if (strcmp(channel
, "all")) {
662 ret
= __lttctl_set_channel_subbuf_size(name
, channel
,
667 /* allow set subbuf_size for metadata channel */
668 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
670 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
676 for (; n_channel
> 0; n_channel
--) {
677 ret
= __lttctl_set_channel_subbuf_size(name
,
678 channellist
[n_channel
- 1], subbuf_size
);
682 lttctl_free_channellist(channellist
, n_channel
);
688 lttctl_free_channellist(channellist
, n_channel
);
694 static int __lttctl_set_channel_switch_timer(const char *name
,
695 const char *channel
, unsigned switch_timer
)
698 char ctlfname
[PATH_MAX
];
701 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/switch_timer",
702 debugfsmntdir
, name
, channel
);
704 sprintf(opstr
, "%u", switch_timer
);
706 ret
= lttctl_sendop(ctlfname
, opstr
);
708 fprintf(stderr
, "Set channel's switch timer failed\n");
711 int lttctl_set_channel_switch_timer(const char *name
, const char *channel
,
712 unsigned switch_timer
)
718 if (!name
|| !channel
) {
719 fprintf(stderr
, "%s: args invalid\n", __func__
);
724 ret
= lttctl_check_trace(name
, 1);
728 if (strcmp(channel
, "all")) {
729 ret
= __lttctl_set_channel_subbuf_size(name
, channel
,
734 /* allow set subbuf_size for metadata channel */
735 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
737 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
743 for (; n_channel
> 0; n_channel
--) {
744 ret
= __lttctl_set_channel_switch_timer(name
,
745 channellist
[n_channel
- 1], switch_timer
);
749 lttctl_free_channellist(channellist
, n_channel
);
755 lttctl_free_channellist(channellist
, n_channel
);
761 int getdebugfsmntdir(char *mntdir
)
763 char mnt_dir
[PATH_MAX
];
764 char mnt_type
[PATH_MAX
];
765 int trymount_done
= 0;
767 FILE *fp
= fopen("/proc/mounts", "r");
773 if (fscanf(fp
, "%*s %s %s %*s %*s %*s", mnt_dir
, mnt_type
) <= 0)
776 if (!strcmp(mnt_type
, "debugfs")) {
777 strcpy(mntdir
, mnt_dir
);
782 if (!trymount_done
) {
783 mount("debugfs", "/sys/kernel/debug/", "debugfs", 0, NULL
);
This page took 0.062955 seconds and 4 git commands to generate.