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
);
166 if (errno
!= ENOENT
) {
167 fprintf(stderr
, "%s: %s\n", __func__
, strerror(errno
));
175 if (!expect
!= !exist
) {
178 fprintf(stderr
, "Trace %s already exist\n", name
);
183 fprintf(stderr
, "Trace %s not exist\n", name
);
193 * get channel list of a trace
194 * don't include metadata channel when metadata is 0
196 * return number of channel on success
197 * return negative number on fail
198 * Caller must free channellist.
200 static int lttctl_get_channellist(const char *tracename
,
201 char ***channellist
, int metadata
)
203 char tracedirname
[PATH_MAX
];
204 struct dirent
*dirent
;
206 char **list
= NULL
, **old_list
;
209 sprintf(tracedirname
, "%s/ltt/control/%s/channel", debugfsmntdir
,
212 dir
= opendir(tracedirname
);
219 dirent
= readdir(dir
);
222 if (!strcmp(dirent
->d_name
, ".")
223 || !strcmp(dirent
->d_name
, ".."))
225 if (!metadata
&& !strcmp(dirent
->d_name
, "metadata"))
228 list
= malloc(sizeof(char *) * ++nr_chan
);
229 memcpy(list
, old_list
, sizeof(*list
) * (nr_chan
- 1));
231 list
[nr_chan
- 1] = strdup(dirent
->d_name
);
244 static void lttctl_free_channellist(char **channellist
, int n_channel
)
247 for(; i
< n_channel
; ++i
)
248 free(channellist
[i
]);
252 int lttctl_setup_trace(const char *name
)
255 char ctlfname
[PATH_MAX
];
258 fprintf(stderr
, "%s: args invalid\n", __func__
);
263 ret
= lttctl_check_trace(name
, 0);
267 sprintf(ctlfname
, "%s/ltt/setup_trace", debugfsmntdir
);
269 ret
= lttctl_sendop(ctlfname
, name
);
271 fprintf(stderr
, "Setup trace failed\n");
282 int lttctl_destroy_trace(const char *name
)
285 char ctlfname
[PATH_MAX
];
288 fprintf(stderr
, "%s: args invalid\n", __func__
);
293 ret
= lttctl_check_trace(name
, 1);
297 sprintf(ctlfname
, "%s/ltt/destroy_trace", debugfsmntdir
);
299 ret
= lttctl_sendop(ctlfname
, name
);
301 fprintf(stderr
, "Destroy trace failed\n");
312 int lttctl_alloc_trace(const char *name
)
315 char ctlfname
[PATH_MAX
];
318 fprintf(stderr
, "%s: args invalid\n", __func__
);
323 ret
= lttctl_check_trace(name
, 1);
327 sprintf(ctlfname
, "%s/ltt/control/%s/alloc", debugfsmntdir
, name
);
329 ret
= lttctl_sendop(ctlfname
, "1");
331 fprintf(stderr
, "Allocate trace failed\n");
342 int lttctl_start(const char *name
)
345 char ctlfname
[PATH_MAX
];
348 fprintf(stderr
, "%s: args invalid\n", __func__
);
353 ret
= lttctl_check_trace(name
, 1);
357 sprintf(ctlfname
, "%s/ltt/control/%s/enabled", debugfsmntdir
, name
);
359 ret
= lttctl_sendop(ctlfname
, "1");
361 fprintf(stderr
, "Start trace failed\n");
372 int lttctl_pause(const char *name
)
375 char ctlfname
[PATH_MAX
];
378 fprintf(stderr
, "%s: args invalid\n", __func__
);
383 ret
= lttctl_check_trace(name
, 1);
387 sprintf(ctlfname
, "%s/ltt/control/%s/enabled", debugfsmntdir
, name
);
389 ret
= lttctl_sendop(ctlfname
, "0");
391 fprintf(stderr
, "Pause trace failed\n");
402 int lttctl_set_trans(const char *name
, const char *trans
)
405 char ctlfname
[PATH_MAX
];
408 fprintf(stderr
, "%s: args invalid\n", __func__
);
413 ret
= lttctl_check_trace(name
, 1);
417 sprintf(ctlfname
, "%s/ltt/control/%s/trans", debugfsmntdir
, name
);
419 ret
= lttctl_sendop(ctlfname
, trans
);
421 fprintf(stderr
, "Set transport failed\n");
432 static int __lttctl_set_channel_enable(const char *name
, const char *channel
,
436 char ctlfname
[PATH_MAX
];
438 sprintf(ctlfname
, "%s/ltt/control/%s/channel/%s/enable", debugfsmntdir
,
441 ret
= lttctl_sendop(ctlfname
, enable
? "1" : "0");
443 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");
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 int getdebugfsmntdir(char *mntdir
)
696 char mnt_dir
[PATH_MAX
];
697 char mnt_type
[PATH_MAX
];
698 int trymount_done
= 0;
700 FILE *fp
= fopen("/proc/mounts", "r");
706 if (fscanf(fp
, "%*s %s %s %*s %*s %*s", mnt_dir
, mnt_type
) <= 0)
709 if (!strcmp(mnt_type
, "debugfs")) {
710 strcpy(mntdir
, mnt_dir
);
715 if (!trymount_done
) {
716 mount("debugfs", "/sys/kernel/debug/", "debugfs", 0, NULL
);
This page took 0.125503 seconds and 4 git commands to generate.