[lttng-dev] [PATCH lttng-tools v3 4/4] Configurable kernel module probes support
Jan Glauber
jan.glauber at gmail.com
Wed May 14 10:26:32 EDT 2014
Create a kernel module probes list and use it to load the specified
probes. The probes are selectable by the --kmod-probes command line option
to lttng-sessiond or the LTTNG_KMOD_PROBES environment variable.
If neither is set all probes are loaded so the current behaviour is not
changed.
Signed-off-by: Jan Glauber <jan.glauber at gmail.com>
---
doc/man/lttng-sessiond.8 | 7 +++
src/bin/lttng-sessiond/kern-modules.h | 2 +-
src/bin/lttng-sessiond/main.c | 5 ++
src/bin/lttng-sessiond/modprobe.c | 87 +++++++++++++++++++++++++++------
src/bin/lttng-sessiond/modprobe.h | 2 +
src/common/defaults.h | 3 ++
src/common/utils.c | 10 ++++
src/common/utils.h | 1 +
8 files changed, 102 insertions(+), 15 deletions(-)
diff --git a/doc/man/lttng-sessiond.8 b/doc/man/lttng-sessiond.8
index 633cf81..133c69f 100644
--- a/doc/man/lttng-sessiond.8
+++ b/doc/man/lttng-sessiond.8
@@ -81,6 +81,11 @@ No kernel tracer support
.BR " --jul-tcp-port"
JUL application registration TCP port (default: 5345)
.TP
+.BR " --kmod-probes=probe1, probe2, ..."
+Specify the kernel modules containing LTTng probes to load by the session daemon.
+Only the component name of the probe needs to be specified, e.g. to load the
+lttng-probe-irq and lttng-probe-sched use: --kmod-probes="irq, sched".
+.TP
.BR "-c, --client-sock=PATH"
Specify path for the client unix socket
.TP
@@ -150,6 +155,8 @@ parameter: the timeout value, in milliseconds. A value of 0 or -1 uses
the timeout of the operating system (this is the default).
.IP "LTTNG_SESSION_CONFIG_XSD_PATH"
Specify the path that contains the XML session configuration schema (xsd).
+.IP "LTTNG_KMOD_PROBES"
+Specify the kernel modules probes that should be loaded by the session daemon.
.SH "SEE ALSO"
.PP
diff --git a/src/bin/lttng-sessiond/kern-modules.h b/src/bin/lttng-sessiond/kern-modules.h
index ca09fc3..26f4457 100644
--- a/src/bin/lttng-sessiond/kern-modules.h
+++ b/src/bin/lttng-sessiond/kern-modules.h
@@ -28,7 +28,7 @@
#define KERN_MODULES_MINOR 0
struct kern_modules_param {
- const char *name;
+ char *name;
};
#endif /* _KERN_MODULES_H */
diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c
index 3a8a1b2..e6a2022 100644
--- a/src/bin/lttng-sessiond/main.c
+++ b/src/bin/lttng-sessiond/main.c
@@ -155,6 +155,7 @@ static const struct option long_options[] = {
{ "jul-tcp-port", 1, 0, 'J' },
{ "config", 1, 0, 'f' },
{ "load", 1, 0, 'l' },
+ { "kmod-probes", 1, 0, 'P' },
{ NULL, 0, 0, 0 }
};
@@ -4132,6 +4133,7 @@ static void usage(void)
fprintf(stderr, " --jul-tcp-port JUL application registration TCP port\n");
fprintf(stderr, " -f --config Load daemon configuration file\n");
fprintf(stderr, " -l --load PATH Load session configuration\n");
+ fprintf(stderr, " --kmod-probes Specify kernel module probes to load\n");
}
/*
@@ -4258,6 +4260,9 @@ static int set_option(int opt, const char *arg, const char *optname)
ret = -ENOMEM;
}
break;
+ case 'P': /* probe modules list */
+ kmod_probes_list = strdup(arg);
+ break;
default:
/* Unknown option or other error.
* Error is printed by getopt, just return */
diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c
index 2fbc7bd..6aa87de 100644
--- a/src/bin/lttng-sessiond/modprobe.c
+++ b/src/bin/lttng-sessiond/modprobe.c
@@ -21,6 +21,7 @@
#include <sys/wait.h>
#include <common/common.h>
+#include <common/utils.h>
#include "modprobe.h"
#include "kern-modules.h"
@@ -49,7 +50,7 @@ struct kern_modules_param kern_modules_control_opt[] = {
};
/* LTTng kernel tracer probe modules list */
-const struct kern_modules_param kern_modules_probes[] = {
+struct kern_modules_param kern_modules_probes_default[] = {
{ "lttng-probe-asoc" },
{ "lttng-probe-block" },
{ "lttng-probe-btrfs" },
@@ -90,6 +91,10 @@ const struct kern_modules_param kern_modules_probes[] = {
{ "lttng-probe-writeback" },
};
+/* dynamic probe modules list */
+static struct kern_modules_param *probes;
+static int nr_probes;
+
void modprobe_remove_lttng(const struct kern_modules_param *modules,
int entries, int required)
{
@@ -116,6 +121,8 @@ void modprobe_remove_lttng(const struct kern_modules_param *modules,
DBG("Modprobe removal successful %s",
modules[i].name);
}
+ if (probes)
+ free(probes[i].name);
}
}
@@ -125,11 +132,11 @@ void modprobe_remove_lttng(const struct kern_modules_param *modules,
void modprobe_remove_lttng_control(void)
{
modprobe_remove_lttng(kern_modules_control_opt,
- ARRAY_SIZE(kern_modules_control_opt),
- LTTNG_MOD_OPTIONAL);
+ ARRAY_SIZE(kern_modules_control_opt),
+ LTTNG_MOD_OPTIONAL);
modprobe_remove_lttng(kern_modules_control_core,
- ARRAY_SIZE(kern_modules_control_core),
- LTTNG_MOD_REQUIRED);
+ ARRAY_SIZE(kern_modules_control_core),
+ LTTNG_MOD_REQUIRED);
}
/*
@@ -137,9 +144,14 @@ void modprobe_remove_lttng_control(void)
*/
void modprobe_remove_lttng_data(void)
{
- return modprobe_remove_lttng(kern_modules_probes,
- ARRAY_SIZE(kern_modules_probes),
- LTTNG_MOD_OPTIONAL);
+ if (probes) {
+ modprobe_remove_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
+ free(probes);
+ probes = NULL;
+ } else
+ modprobe_remove_lttng(kern_modules_probes_default,
+ ARRAY_SIZE(kern_modules_probes_default),
+ LTTNG_MOD_OPTIONAL);
}
/*
@@ -151,7 +163,7 @@ void modprobe_remove_lttng_all(void)
modprobe_remove_lttng_control();
}
-static int modprobe_lttng(const struct kern_modules_param *modules,
+static int modprobe_lttng(struct kern_modules_param *modules,
int entries, int required)
{
int ret = 0, i;
@@ -195,8 +207,8 @@ int modprobe_lttng_control(void)
if (ret != 0)
return ret;
ret = modprobe_lttng(kern_modules_control_opt,
- ARRAY_SIZE(kern_modules_control_opt),
- LTTNG_MOD_OPTIONAL);
+ ARRAY_SIZE(kern_modules_control_opt),
+ LTTNG_MOD_OPTIONAL);
return ret;
}
@@ -205,7 +217,54 @@ int modprobe_lttng_control(void)
*/
int modprobe_lttng_data(void)
{
- return modprobe_lttng(kern_modules_probes,
- ARRAY_SIZE(kern_modules_probes),
- LTTNG_MOD_OPTIONAL);
+ int entries = ARRAY_SIZE(kern_modules_probes_default);
+ char *list, *next;
+ int i;
+
+ /*
+ * First take command line option,
+ * if not available take environment variable.
+ * No idea how the config file option could be provided.
+ */
+ if (kmod_probes_list)
+ list= kmod_probes_list;
+ else
+ list = utils_get_kmod_probes_list();
+
+ /* the default is to load ALL probes */
+ if (!list)
+ return modprobe_lttng(kern_modules_probes_default, entries,
+ LTTNG_MOD_OPTIONAL);
+
+ /*
+ * A probe list is available, so use it.
+ * The number of probes is limited by the number of probes in the
+ * default list.
+ */
+ probes = malloc(sizeof(struct kern_modules_param *) * entries);
+ if (!probes) {
+ PERROR("malloc probe list");
+ return -ENOMEM;
+ }
+ for (i = 0; i < entries; i++) {
+ next = strtok(list, ",");
+ if (!next)
+ goto out;
+ list = NULL;
+
+ /* filter leading spaces */
+ while (*next == ' ')
+ next++;
+
+ /* length 13 is "lttng-probe-" + \0 */
+ probes[i].name = malloc(strlen(next) + 13);
+ if (!probes[i].name) {
+ PERROR("malloc probe list");
+ return -ENOMEM;
+ }
+ sprintf(probes[i].name, "lttng-probe-%s", next);
+ }
+out:
+ nr_probes = i;
+ return modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
}
diff --git a/src/bin/lttng-sessiond/modprobe.h b/src/bin/lttng-sessiond/modprobe.h
index 0c6f5f1..42e1912 100644
--- a/src/bin/lttng-sessiond/modprobe.h
+++ b/src/bin/lttng-sessiond/modprobe.h
@@ -24,4 +24,6 @@ void modprobe_remove_lttng_data(void);
int modprobe_lttng_control(void);
int modprobe_lttng_data(void);
+char *kmod_probes_list;
+
#endif /* _MODPROBE_H */
diff --git a/src/common/defaults.h b/src/common/defaults.h
index de61064..b49bf4b 100644
--- a/src/common/defaults.h
+++ b/src/common/defaults.h
@@ -90,6 +90,9 @@
#define DEFAULT_LTTNG_SESSIOND_PIDFILE "lttng-sessiond.pid"
#define DEFAULT_LTTNG_SESSIOND_JULPORT_FILE "jul.port"
+/* Default probes list */
+#define DEFAULT_LTTNG_KMOD_PROBES "LTTNG_KMOD_PROBES"
+
/* Default unix socket path */
#define DEFAULT_GLOBAL_CLIENT_UNIX_SOCK DEFAULT_LTTNG_RUNDIR "/client-lttng-sessiond"
#define DEFAULT_HOME_CLIENT_UNIX_SOCK DEFAULT_LTTNG_HOME_RUNDIR "/client-lttng-sessiond"
diff --git a/src/common/utils.c b/src/common/utils.c
index 815965b..78f858c 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -870,6 +870,16 @@ end:
}
/*
+ * Obtain the value of LTTNG_KMOD_PROBES environment variable, if exists.
+ * Otherwise returns an empty string.
+ */
+LTTNG_HIDDEN
+char *utils_get_kmod_probes_list(void)
+{
+ return getenv(DEFAULT_LTTNG_KMOD_PROBES);
+}
+
+/*
* With the given format, fill dst with the time of len maximum siz.
*
* Return amount of bytes set in the buffer or else 0 on error.
diff --git a/src/common/utils.h b/src/common/utils.h
index b872b53..cc80a53 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -47,6 +47,7 @@ int utils_parse_size_suffix(char const * const str, uint64_t * const size);
int utils_get_count_order_u32(uint32_t x);
char *utils_get_home_dir(void);
char *utils_get_user_home_dir(uid_t uid);
+char *utils_get_kmod_probes_list(void);
size_t utils_get_current_time_str(const char *format, char *dst, size_t len);
gid_t utils_get_group_id(const char *name);
char *utils_generate_optstring(const struct option *long_options,
--
1.7.9.5
More information about the lttng-dev
mailing list