convert from svn repository: remove tags directory
[lttv.git] / trunk / ltt-control / liblttctl / liblttctl.c
index ca5ba08b153717ba6cee872505f5af91a08200b6..6ee37a479797d7f5f70d65446035c9c69588e354 100644 (file)
@@ -39,53 +39,60 @@ static char debugfsmntdir[PATH_MAX];
 
 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;
 }
 
@@ -111,10 +118,11 @@ static int lttctl_sendop(const char *fname, const char *op)
        }
 
        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);
@@ -130,7 +138,7 @@ static int lttctl_sendop(const char *fname, const char *op)
  *
  * 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)
@@ -166,10 +174,16 @@ 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;
@@ -227,6 +241,14 @@ error:
        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;
@@ -426,6 +448,8 @@ int lttctl_set_channel_enable(const char *name, const char *channel,
                int enable)
 {
        int ret;
+       char **channellist;
+       int n_channel;
 
        if (!name || !channel) {
                fprintf(stderr, "%s: args invalid\n", __func__);
@@ -442,9 +466,6 @@ int lttctl_set_channel_enable(const char *name, const char *channel,
                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) {
@@ -458,13 +479,15 @@ int lttctl_set_channel_enable(const char *name, const char *channel,
                        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;
@@ -489,6 +512,8 @@ int lttctl_set_channel_overwrite(const char *name, const char *channel,
                int overwrite)
 {
        int ret;
+       char **channellist;
+       int n_channel;
 
        if (!name || !channel) {
                fprintf(stderr, "%s: args invalid\n", __func__);
@@ -505,9 +530,6 @@ int lttctl_set_channel_overwrite(const char *name, const char *channel,
                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) {
@@ -521,13 +543,15 @@ int lttctl_set_channel_overwrite(const char *name, const char *channel,
                        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;
@@ -555,6 +579,8 @@ int lttctl_set_channel_subbuf_num(const char *name, const char *channel,
                unsigned subbuf_num)
 {
        int ret;
+       char **channellist;
+       int n_channel;
 
        if (!name || !channel) {
                fprintf(stderr, "%s: args invalid\n", __func__);
@@ -572,9 +598,6 @@ int lttctl_set_channel_subbuf_num(const char *name, const char *channel,
                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) {
@@ -588,13 +611,15 @@ int lttctl_set_channel_subbuf_num(const char *name, const char *channel,
                        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;
@@ -620,6 +645,8 @@ int lttctl_set_channel_subbuf_size(const char *name, const char *channel,
                unsigned subbuf_size)
 {
        int ret;
+       char **channellist;
+       int n_channel;
 
        if (!name || !channel) {
                fprintf(stderr, "%s: args invalid\n", __func__);
@@ -637,9 +664,6 @@ int lttctl_set_channel_subbuf_size(const char *name, const char *channel,
                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) {
@@ -653,14 +677,46 @@ int lttctl_set_channel_subbuf_size(const char *name, const char *channel,
                        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;
+}
This page took 0.026564 seconds and 4 git commands to generate.