static int initdebugfsmntdir(void)
{
- char mnt_dir[PATH_MAX];
- char mnt_type[PATH_MAX];
+ return getdebugfsmntdir(debugfsmntdir);
+}
- FILE *fp = fopen("/proc/mounts", "r");
- if (!fp) {
- fprintf(stderr, "%s: Can't open /proc/mounts\n", __func__);
- return 1;
+/*
+ * This function must called posterior to initdebugfsmntdir(),
+ * because it need to use debugfsmntdir[] which is inited in initdebugfsmntdir()
+ */
+static int initmodule(void)
+{
+ char controldirname[PATH_MAX];
+ DIR *dir;
+ int tryload_done = 0;
+
+ sprintf(controldirname, "%s/ltt/control/", debugfsmntdir);
+
+check_again:
+ /*
+ * Check ltt control's debugfs dir
+ *
+ * We don't check is ltt-trace-control module exist, because it maybe
+ * compiled into kernel.
+ */
+ dir = opendir(controldirname);
+ if (dir) {
+ closedir(dir);
+ return 0;
}
- while (1) {
- if (fscanf(fp, "%*s %s %s %*s %*s %*s", mnt_dir, mnt_type)
- <= 0) {
- fprintf(stderr, "%s: debugfs mountpoint not found\n",
- __func__);
- return 1;
- }
- if (!strcmp(mnt_type, "debugfs")) {
- strcpy(debugfsmntdir, mnt_dir);
- return 0;
- }
+ if (!tryload_done) {
+ system("modprobe ltt-trace-control");
+ tryload_done = 1;
+ goto check_again;
}
+
+ return -ENOENT;
}
int lttctl_init(void)
{
int ret;
- DIR *dir;
- char controldirname[PATH_MAX];
+
ret = initdebugfsmntdir();
if (ret) {
- fprintf(stderr, "Debugfs mount point not found\n");
- return 1;
+ fprintf(stderr, "Get debugfs mount point failed\n");
+ return ret;
}
- /* check ltt control's debugfs dir */
- sprintf(controldirname, "%s/ltt/control/", debugfsmntdir);
-
- dir = opendir(controldirname);
- if (!dir) {
- fprintf(stderr, "ltt-trace-control's debugfs dir not found\n");
- closedir(dir);
- return -errno;
+ ret = initmodule();
+ if (ret) {
+ fprintf(stderr, "Control module seems not work\n");
+ return ret;
}
- closedir(dir);
-
return 0;
}
}
if (write(fd, op, strlen(op)) == -1) {
+ int ret = errno;
fprintf(stderr, "%s: write %s to %s failed: %s\n", __func__, op,
fname, strerror(errno));
close(fd);
- return 1;
+ return ret;
}
close(fd);
*
* ret:
* 0: check pass
- * 1: check failed
+ * -(EEXIST | ENOENT): check failed
* -ERRNO: error happened (no check)
*/
static int lttctl_check_trace(const char *name, int expect)
if (!expect != !exist) {
if (exist)
+ {
fprintf(stderr, "Trace %s already exist\n", name);
+ return -EEXIST;
+ }
else
+ {
fprintf(stderr, "Trace %s not exist\n", name);
- return 1;
+ return -ENOENT;
+ }
+
}
return 0;
return nr_chan;
}
+static void lttctl_free_channellist(char **channellist, int n_channel)
+{
+ int i = 0;
+ for(; i < n_channel; ++i)
+ free(channellist[i]);
+ free(channellist);
+}
+
int lttctl_setup_trace(const char *name)
{
int ret;
int enable)
{
int ret;
+ char **channellist;
+ int n_channel;
if (!name || !channel) {
fprintf(stderr, "%s: args invalid\n", __func__);
if (ret)
goto op_err;
} else {
- char **channellist;
- int n_channel;
-
/* Don't allow set enable state for metadata channel */
n_channel = lttctl_get_channellist(name, &channellist, 0);
if (n_channel < 0) {
ret = __lttctl_set_channel_enable(name,
channellist[n_channel - 1], enable);
if (ret)
- goto op_err;
+ goto op_err_clean;
}
- free(channellist);
+ lttctl_free_channellist(channellist, n_channel);
}
return 0;
+op_err_clean:
+ lttctl_free_channellist(channellist, n_channel);
op_err:
arg_error:
return ret;
int overwrite)
{
int ret;
+ char **channellist;
+ int n_channel;
if (!name || !channel) {
fprintf(stderr, "%s: args invalid\n", __func__);
if (ret)
goto op_err;
} else {
- char **channellist;
- int n_channel;
-
/* Don't allow set overwrite for metadata channel */
n_channel = lttctl_get_channellist(name, &channellist, 0);
if (n_channel < 0) {
ret = __lttctl_set_channel_overwrite(name,
channellist[n_channel - 1], overwrite);
if (ret)
- goto op_err;
+ goto op_err_clean;
}
- free(channellist);
+ lttctl_free_channellist(channellist, n_channel);
}
return 0;
+op_err_clean:
+ lttctl_free_channellist(channellist, n_channel);
op_err:
arg_error:
return ret;
unsigned subbuf_num)
{
int ret;
+ char **channellist;
+ int n_channel;
if (!name || !channel) {
fprintf(stderr, "%s: args invalid\n", __func__);
if (ret)
goto op_err;
} else {
- char **channellist;
- int n_channel;
-
/* allow set subbuf_num for metadata channel */
n_channel = lttctl_get_channellist(name, &channellist, 1);
if (n_channel < 0) {
ret = __lttctl_set_channel_subbuf_num(name,
channellist[n_channel - 1], subbuf_num);
if (ret)
- goto op_err;
+ goto op_err_clean;
}
- free(channellist);
+ lttctl_free_channellist(channellist, n_channel);
}
return 0;
+op_err_clean:
+ lttctl_free_channellist(channellist, n_channel);
op_err:
arg_error:
return ret;
unsigned subbuf_size)
{
int ret;
+ char **channellist;
+ int n_channel;
if (!name || !channel) {
fprintf(stderr, "%s: args invalid\n", __func__);
if (ret)
goto op_err;
} else {
- char **channellist;
- int n_channel;
-
/* allow set subbuf_size for metadata channel */
n_channel = lttctl_get_channellist(name, &channellist, 1);
if (n_channel < 0) {
ret = __lttctl_set_channel_subbuf_size(name,
channellist[n_channel - 1], subbuf_size);
if (ret)
- goto op_err;
+ goto op_err_clean;
}
- free(channellist);
+ lttctl_free_channellist(channellist, n_channel);
}
return 0;
+op_err_clean:
+ lttctl_free_channellist(channellist, n_channel);
op_err:
arg_error:
return ret;
}
+
+int getdebugfsmntdir(char *mntdir)
+{
+ char mnt_dir[PATH_MAX];
+ char mnt_type[PATH_MAX];
+ int trymount_done = 0;
+
+ FILE *fp = fopen("/proc/mounts", "r");
+ if (!fp)
+ return -EINVAL;
+
+find_again:
+ while (1) {
+ if (fscanf(fp, "%*s %s %s %*s %*s %*s", mnt_dir, mnt_type) <= 0)
+ break;
+
+ if (!strcmp(mnt_type, "debugfs")) {
+ strcpy(mntdir, mnt_dir);
+ return 0;
+ }
+ }
+
+ if (!trymount_done) {
+ mount("debugfs", "/sys/kernel/debug/", "debugfs", 0, NULL);
+ trymount_done = 1;
+ goto find_again;
+ }
+
+ return -ENOENT;
+}