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) {
121 fprintf(stderr
, "%s: write %s to %s failed: %s\n", __func__
, op
,
122 fname
, strerror(errno
));
133 * check is trace exist(check debugfsmntdir too)
135 * 0: expect that trace not exist
136 * !0: expect that trace exist
141 * -ERRNO: error happened (no check)
143 static int lttctl_check_trace(const char *name
, int expect
)
145 char tracedirname
[PATH_MAX
];
150 fprintf(stderr
, "%s: args invalid\n", __func__
);
154 if (!debugfsmntdir
[0]) {
155 fprintf(stderr
, "%s: debugfsmntdir not valid\n", __func__
);
159 sprintf(tracedirname
, "%s/ltt/control/%s", debugfsmntdir
, name
);
161 dir
= opendir(tracedirname
);
165 if (errno
!= ENOENT
) {
166 fprintf(stderr
, "%s: %s\n", __func__
, strerror(errno
));
174 if (!expect
!= !exist
) {
176 fprintf(stderr
, "Trace %s already exist\n", name
);
178 fprintf(stderr
, "Trace %s not exist\n", name
);
186 * get channel list of a trace
187 * don't include metadata channel when metadata is 0
189 * return number of channel on success
190 * return negative number on fail
191 * Caller must free channellist.
193 static int lttctl_get_channellist(const char *tracename
,
194 char ***channellist
, int metadata
)
196 char tracedirname
[PATH_MAX
];
197 struct dirent
*dirent
;
199 char **list
= NULL
, **old_list
;
202 sprintf(tracedirname
, "%s/ltt/control/%s/channel", debugfsmntdir
,
205 dir
= opendir(tracedirname
);
212 dirent
= readdir(dir
);
215 if (!strcmp(dirent
->d_name
, ".")
216 || !strcmp(dirent
->d_name
, ".."))
218 if (!metadata
&& !strcmp(dirent
->d_name
, "metadata"))
221 list
= malloc(sizeof(char *) * ++nr_chan
);
222 memcpy(list
, old_list
, sizeof(*list
) * (nr_chan
- 1));
224 list
[nr_chan
- 1] = strdup(dirent
->d_name
);
237 int lttctl_setup_trace(const char *name
)
240 char ctlfname
[PATH_MAX
];
243 fprintf(stderr
, "%s: args invalid\n", __func__
);
248 ret
= lttctl_check_trace(name
, 0);
252 sprintf(ctlfname
, "%s/ltt/setup_trace", debugfsmntdir
);
254 ret
= lttctl_sendop(ctlfname
, name
);
256 fprintf(stderr
, "Setup trace failed\n");
267 int lttctl_destroy_trace(const char *name
)
270 char ctlfname
[PATH_MAX
];
273 fprintf(stderr
, "%s: args invalid\n", __func__
);
278 ret
= lttctl_check_trace(name
, 1);
282 sprintf(ctlfname
, "%s/ltt/destroy_trace", debugfsmntdir
);
284 ret
= lttctl_sendop(ctlfname
, name
);
286 fprintf(stderr
, "Destroy trace failed\n");
297 int lttctl_alloc_trace(const char *name
)
300 char ctlfname
[PATH_MAX
];
303 fprintf(stderr
, "%s: args invalid\n", __func__
);
308 ret
= lttctl_check_trace(name
, 1);
312 sprintf(ctlfname
, "%s/ltt/control/%s/alloc", debugfsmntdir
, name
);
314 ret
= lttctl_sendop(ctlfname
, "1");
316 fprintf(stderr
, "Allocate trace failed\n");
327 int lttctl_start(const char *name
)
330 char ctlfname
[PATH_MAX
];
333 fprintf(stderr
, "%s: args invalid\n", __func__
);
338 ret
= lttctl_check_trace(name
, 1);
342 sprintf(ctlfname
, "%s/ltt/control/%s/enabled", debugfsmntdir
, name
);
344 ret
= lttctl_sendop(ctlfname
, "1");
346 fprintf(stderr
, "Start trace failed\n");
357 int lttctl_pause(const char *name
)
360 char ctlfname
[PATH_MAX
];
363 fprintf(stderr
, "%s: args invalid\n", __func__
);
368 ret
= lttctl_check_trace(name
, 1);
372 sprintf(ctlfname
, "%s/ltt/control/%s/enabled", debugfsmntdir
, name
);
374 ret
= lttctl_sendop(ctlfname
, "0");
376 fprintf(stderr
, "Pause trace failed\n");
387 int lttctl_set_trans(const char *name
, const char *trans
)
390 char ctlfname
[PATH_MAX
];
393 fprintf(stderr
, "%s: args invalid\n", __func__
);
398 ret
= lttctl_check_trace(name
, 1);
402 sprintf(ctlfname
, "%s/ltt/control/%s/trans", debugfsmntdir
, name
);
404 ret
= lttctl_sendop(ctlfname
, trans
);
406 fprintf(stderr
, "Set transport failed\n");
417 static int __lttctl_set_channel_enable(const char *name
, const char *channel
,
421 char ctlfname
[PATH_MAX
];
423 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/enable", debugfsmntdir
,
426 ret
= lttctl_sendop(ctlfname
, enable
? "1" : "0");
428 fprintf(stderr
, "Set channel's enable mode failed\n");
432 int lttctl_set_channel_enable(const char *name
, const char *channel
,
437 if (!name
|| !channel
) {
438 fprintf(stderr
, "%s: args invalid\n", __func__
);
443 ret
= lttctl_check_trace(name
, 1);
447 if (strcmp(channel
, "all")) {
448 ret
= __lttctl_set_channel_enable(name
, channel
, enable
);
455 /* Don't allow set enable state for metadata channel */
456 n_channel
= lttctl_get_channellist(name
, &channellist
, 0);
458 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
464 for (; n_channel
> 0; n_channel
--) {
465 ret
= __lttctl_set_channel_enable(name
,
466 channellist
[n_channel
- 1], enable
);
480 static int __lttctl_set_channel_overwrite(const char *name
, const char *channel
,
484 char ctlfname
[PATH_MAX
];
486 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/overwrite",
487 debugfsmntdir
, name
, channel
);
489 ret
= lttctl_sendop(ctlfname
, overwrite
? "1" : "0");
491 fprintf(stderr
, "Set channel's overwrite mode failed\n");
495 int lttctl_set_channel_overwrite(const char *name
, const char *channel
,
500 if (!name
|| !channel
) {
501 fprintf(stderr
, "%s: args invalid\n", __func__
);
506 ret
= lttctl_check_trace(name
, 1);
510 if (strcmp(channel
, "all")) {
511 ret
= __lttctl_set_channel_overwrite(name
, channel
, overwrite
);
518 /* Don't allow set overwrite for metadata channel */
519 n_channel
= lttctl_get_channellist(name
, &channellist
, 0);
521 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
527 for (; n_channel
> 0; n_channel
--) {
528 ret
= __lttctl_set_channel_overwrite(name
,
529 channellist
[n_channel
- 1], overwrite
);
543 static int __lttctl_set_channel_subbuf_num(const char *name
,
544 const char *channel
, unsigned subbuf_num
)
547 char ctlfname
[PATH_MAX
];
550 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/subbuf_num",
551 debugfsmntdir
, name
, channel
);
553 sprintf(opstr
, "%u", subbuf_num
);
555 ret
= lttctl_sendop(ctlfname
, opstr
);
557 fprintf(stderr
, "Set channel's subbuf number failed\n");
561 int lttctl_set_channel_subbuf_num(const char *name
, const char *channel
,
566 if (!name
|| !channel
) {
567 fprintf(stderr
, "%s: args invalid\n", __func__
);
572 ret
= lttctl_check_trace(name
, 1);
576 if (strcmp(channel
, "all")) {
577 ret
= __lttctl_set_channel_subbuf_num(name
, channel
,
585 /* allow set subbuf_num for metadata channel */
586 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
588 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
594 for (; n_channel
> 0; n_channel
--) {
595 ret
= __lttctl_set_channel_subbuf_num(name
,
596 channellist
[n_channel
- 1], subbuf_num
);
610 static int __lttctl_set_channel_subbuf_size(const char *name
,
611 const char *channel
, unsigned subbuf_size
)
614 char ctlfname
[PATH_MAX
];
617 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/subbuf_size",
618 debugfsmntdir
, name
, channel
);
620 sprintf(opstr
, "%u", subbuf_size
);
622 ret
= lttctl_sendop(ctlfname
, opstr
);
624 fprintf(stderr
, "Set channel's subbuf size failed\n");
626 int lttctl_set_channel_subbuf_size(const char *name
, const char *channel
,
627 unsigned subbuf_size
)
631 if (!name
|| !channel
) {
632 fprintf(stderr
, "%s: args invalid\n", __func__
);
637 ret
= lttctl_check_trace(name
, 1);
641 if (strcmp(channel
, "all")) {
642 ret
= __lttctl_set_channel_subbuf_size(name
, channel
,
650 /* allow set subbuf_size for metadata channel */
651 n_channel
= lttctl_get_channellist(name
, &channellist
, 1);
653 fprintf(stderr
, "%s: lttctl_get_channellist failed\n",
659 for (; n_channel
> 0; n_channel
--) {
660 ret
= __lttctl_set_channel_subbuf_size(name
,
661 channellist
[n_channel
- 1], subbuf_size
);
675 int getdebugfsmntdir(char *mntdir
)
677 char mnt_dir
[PATH_MAX
];
678 char mnt_type
[PATH_MAX
];
679 int trymount_done
= 0;
681 FILE *fp
= fopen("/proc/mounts", "r");
687 if (fscanf(fp
, "%*s %s %s %*s %*s %*s", mnt_dir
, mnt_type
) <= 0)
690 if (!strcmp(mnt_type
, "debugfs")) {
691 strcpy(mntdir
, mnt_dir
);
696 if (!trymount_done
) {
697 mount("debugfs", "/sys/kernel/debug/", "debugfs", 0, NULL
);
This page took 0.054038 seconds and 4 git commands to generate.