diff mbox series

[v2] trace-cmd: Load trace-cmd plugins from build folder, if exists

Message ID 20190423095658.3907-1-tstoyanov@vmware.com (mailing list archive)
State Superseded
Headers show
Series [v2] trace-cmd: Load trace-cmd plugins from build folder, if exists | expand

Commit Message

Tzvetomir Stoyanov April 23, 2019, 9:56 a.m. UTC
[
 v2 changes:
  - Removed the logic looking for plugins in the build path.
  - Added logic which gets the full path of the running trace-cmd
    binary and loads plugins from "plugins" directory around it, if exist.
]

When a development version of trace-cmd is built and run on the machine,
by default it loads all plugins from predefined drierctories :
  (install_preffix)/lib/traceevent/plugins
  ~/.traceevent/plugins
  the path specified in TRACEEVENT_PLUGIN_DIR environment variable.
Thus, the development plugins will not be loaded. To simplify the development
process, a new logic is added:
  At plugins load time, check the location of trace-cmd application and look
  for "plugins" directory around it. If found, load plugins from it. Those
  pluigins will be loaded last, so in case of duplication the "development"
  plugins win.

Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
---
 lib/trace-cmd/trace-util.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

Comments

Slavomir Kaslev April 23, 2019, 1:10 p.m. UTC | #1
On Tue, 2019-04-23 at 12:56 +0300, Tzvetomir Stoyanov wrote:
> [
>  v2 changes:
>   - Removed the logic looking for plugins in the build path.
>   - Added logic which gets the full path of the running trace-cmd
>     binary and loads plugins from "plugins" directory around it, if
> exist.
> ]
> 
> When a development version of trace-cmd is built and run on the
> machine,
> by default it loads all plugins from predefined drierctories :
>   (install_preffix)/lib/traceevent/plugins
>   ~/.traceevent/plugins
>   the path specified in TRACEEVENT_PLUGIN_DIR environment variable.
> Thus, the development plugins will not be loaded. To simplify the
> development
> process, a new logic is added:
>   At plugins load time, check the location of trace-cmd application
> and look
>   for "plugins" directory around it. If found, load plugins from it.
> Those
>   pluigins will be loaded last, so in case of duplication the
> "development"
>   plugins win.
> 
> Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
> ---
>  lib/trace-cmd/trace-util.c | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/lib/trace-cmd/trace-util.c b/lib/trace-cmd/trace-util.c
> index 8d21fb2..98402a0 100644
> --- a/lib/trace-cmd/trace-util.c
> +++ b/lib/trace-cmd/trace-util.c
> @@ -1364,6 +1364,34 @@ static int add_plugin_file(struct tep_handle
> *pevent, const char *path,
>  	return -ENOMEM;
>  }
>  
> +static char *trace_util_get_source_plugins_dir(void)
> +{
> +	char *plugins = "/plugins";
> +	char path[PATH_MAX+1];
> +	int slash = 0;
> +	int ret;
> +
> +	ret = readlink("/proc/self/exe", path, PATH_MAX);
> +	if (ret > PATH_MAX || ret < 0)
> +		return NULL;
> +
> +	while (ret) {
> +		if ('/' == path[ret--])
> +			slash++;
> +		if (slash == 2) {
> +			path[ret+1] = 0;
> +			if (strlen(path) + strlen(plugins) > PATH_MAX)
> +				break;
> +			strcat(path, plugins);
> +			return strdup(path);
> +		}
> +	}

Looks good. I think that this while() loop can be simplified using the
standard library to something like:

	char resolved[PATH_MAX+1];

	dirname(path);
	strcat(path, "/../plugins");
	if (!realpath(path, resolved))
		return NULL;

The realpath() above is also not strictly necessary.

Cheers,

-- Slavi
Steven Rostedt April 23, 2019, 1:32 p.m. UTC | #2
On Tue, 23 Apr 2019 13:10:35 +0000
Slavomir Kaslev <kaslevs@vmware.com> wrote:

 
> > +static char *trace_util_get_source_plugins_dir(void)
> > +{
> > +	char *plugins = "/plugins";
> > +	char path[PATH_MAX+1];
> > +	int slash = 0;
> > +	int ret;
> > +
> > +	ret = readlink("/proc/self/exe", path, PATH_MAX);
> > +	if (ret > PATH_MAX || ret < 0)
> > +		return NULL;
> > +
> > +	while (ret) {
> > +		if ('/' == path[ret--])
> > +			slash++;
> > +		if (slash == 2) {
> > +			path[ret+1] = 0;
> > +			if (strlen(path) + strlen(plugins) > PATH_MAX)
> > +				break;
> > +			strcat(path, plugins);
> > +			return strdup(path);
> > +		}
> > +	}  
> 
> Looks good. I think that this while() loop can be simplified using the
> standard library to something like:
> 
> 	char resolved[PATH_MAX+1];
> 
> 	dirname(path);
> 	strcat(path, "/../plugins");
> 	if (!realpath(path, resolved))
> 		return NULL;
> 
> The realpath() above is also not strictly necessary.

Or:

	char *p;

	dirname(path);
	p = strrchr(path, '/');
	if (!p)
		return NULL;
	/* It's only in the source if we are in the tracecmd directory */
	if (strcmp(p, "/tracecmd") != 0)
		return NULL;

	strcpy(p, "/plugins");


-- Steve
Tzvetomir Stoyanov April 23, 2019, 2:15 p.m. UTC | #3
On Tue, Apr 23, 2019 at 4:32 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Tue, 23 Apr 2019 13:10:35 +0000
> Slavomir Kaslev <kaslevs@vmware.com> wrote:
>
>
> > > +static char *trace_util_get_source_plugins_dir(void)
> > > +{
> > > +   char *plugins = "/plugins";
> > > +   char path[PATH_MAX+1];
> > > +   int slash = 0;
> > > +   int ret;
> > > +
> > > +   ret = readlink("/proc/self/exe", path, PATH_MAX);
> > > +   if (ret > PATH_MAX || ret < 0)
> > > +           return NULL;
> > > +
> > > +   while (ret) {
> > > +           if ('/' == path[ret--])
> > > +                   slash++;
> > > +           if (slash == 2) {
> > > +                   path[ret+1] = 0;
> > > +                   if (strlen(path) + strlen(plugins) > PATH_MAX)
> > > +                           break;
> > > +                   strcat(path, plugins);
> > > +                   return strdup(path);
> > > +           }
> > > +   }
> >
> > Looks good. I think that this while() loop can be simplified using the
> > standard library to something like:
> >
> >       char resolved[PATH_MAX+1];
> >
> >       dirname(path);
> >       strcat(path, "/../plugins");
> >       if (!realpath(path, resolved))
> >               return NULL;
> >
> > The realpath() above is also not strictly necessary.
>
> Or:
>
>         char *p;
>
>         dirname(path);
>         p = strrchr(path, '/');
>         if (!p)
>                 return NULL;
>         /* It's only in the source if we are in the tracecmd directory */
>         if (strcmp(p, "/tracecmd") != 0)
>                 return NULL;
>
>         strcpy(p, "/plugins");
>
>
> -- Steve
>

It makes sense to check for tracecmd directory, though it narrows the
use cases. I'll send the next version with this.
diff mbox series

Patch

diff --git a/lib/trace-cmd/trace-util.c b/lib/trace-cmd/trace-util.c
index 8d21fb2..98402a0 100644
--- a/lib/trace-cmd/trace-util.c
+++ b/lib/trace-cmd/trace-util.c
@@ -1364,6 +1364,34 @@  static int add_plugin_file(struct tep_handle *pevent, const char *path,
 	return -ENOMEM;
 }
 
+static char *trace_util_get_source_plugins_dir(void)
+{
+	char *plugins = "/plugins";
+	char path[PATH_MAX+1];
+	int slash = 0;
+	int ret;
+
+	ret = readlink("/proc/self/exe", path, PATH_MAX);
+	if (ret > PATH_MAX || ret < 0)
+		return NULL;
+
+	while (ret) {
+		if ('/' == path[ret--])
+			slash++;
+		if (slash == 2) {
+			path[ret+1] = 0;
+			if (strlen(path) + strlen(plugins) > PATH_MAX)
+				break;
+			strcat(path, plugins);
+			return strdup(path);
+		}
+	}
+
+	return NULL;
+
+}
+
+
 int trace_util_load_plugins(struct tep_handle *pevent, const char *suffix,
 			    int (*load_plugin)(struct tep_handle *pevent,
 					       const char *path,
@@ -1404,6 +1432,12 @@  int trace_util_load_plugins(struct tep_handle *pevent, const char *suffix,
 	trace_util_load_plugins_dir(pevent, suffix, path, load_plugin, data);
 
 	free(path);
+
+	path = trace_util_get_source_plugins_dir();
+	if (path) {
+		trace_util_load_plugins_dir(pevent, suffix, path, load_plugin, data);
+		free(path);
+	}
 	return 0;
 }