Configurable kernel module probes support
authorJan Glauber <jan.glauber@gmail.com>
Wed, 14 May 2014 14:26:32 +0000 (16:26 +0200)
committerDavid Goulet <dgoulet@efficios.com>
Wed, 14 May 2014 20:43:26 +0000 (16:43 -0400)
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@gmail.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
doc/man/lttng-sessiond.8
src/bin/lttng-sessiond/kern-modules.h
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/modprobe.c
src/bin/lttng-sessiond/modprobe.h
src/common/defaults.h
src/common/utils.c
src/common/utils.h

index e6e37a0f5067d8cef60d9dac80afc294f351ca80..8a7e042100802a3c912703d9d7e0a609567614e6 100644 (file)
@@ -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
@@ -153,6 +158,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
index ca09fc3afae2795423134002a6edc00a4e50d877..26f44578d2f786520f57d8cc6552b5010977d8da 100644 (file)
@@ -28,7 +28,7 @@
 #define KERN_MODULES_MINOR         0
 
 struct kern_modules_param {
-       const char *name;
+       char *name;
 };
 
 #endif /* _KERN_MODULES_H */
index eb772fe593273f968e422b5aabeae8b686cf3e97..5448259e5f58e47b6abf05e02a253a5399a00d8e 100644 (file)
@@ -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;
        case 'f':
                /* This is handled in set_options() thus silent break. */
                break;
index 2fbc7bd8734bde95e51831b401769b0bd3d41829..3cc67f0b92c43ffe480159a42b7cc850ce19ec37 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *               2014 - Jan Glauber <jan.glauber@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 2 only,
@@ -21,6 +22,7 @@
 #include <sys/wait.h>
 
 #include <common/common.h>
+#include <common/utils.h>
 
 #include "modprobe.h"
 #include "kern-modules.h"
@@ -49,7 +51,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 +92,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 +122,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 +133,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 +145,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 +164,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 +208,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 +218,67 @@ 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 i, ret;
+       int entries = ARRAY_SIZE(kern_modules_probes_default);
+       char *list, *next;
+
+       /*
+        * First take command line option, if not available take environment
+        * variable.
+        */
+       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 = zmalloc(sizeof(struct kern_modules_param *) * entries);
+       if (!probes) {
+               PERROR("malloc probe list");
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < entries; i++) {
+               size_t name_len;
+
+               next = strtok(list, ",");
+               if (!next) {
+                       goto out;
+               }
+               list = NULL;
+
+               /* filter leading spaces */
+               while (*next == ' ') {
+                       next++;
+               }
+
+               /* Length 13 is "lttng-probe-" + \0 */
+               name_len = strlen(next) + 13;
+
+               probes[i].name = zmalloc(name_len);
+               if (!probes[i].name) {
+                       PERROR("malloc probe list");
+                       return -ENOMEM;
+               }
+
+               ret = snprintf(probes[i].name, name_len, "lttng-probe-%s", next);
+               if (ret < 0) {
+                       PERROR("snprintf modprobe name");
+                       goto out;
+               }
+       }
+
+out:
+       nr_probes = i;
+       return modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
 }
index 0c6f5f158f925c825eebbaf550934eac60e7b126..42e191217ee8f6d054e7f6412788cdd0760b2fc2 100644 (file)
@@ -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 */
index de610644cea5cc807cbfa246e8ffacc583aa9a37..b49bf4b33cd6fb5b0fbeb7c13f1101391157d7f9 100644 (file)
@@ -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"
index 9821815ba06298dfbb7e76de02bbc385b9d49d0d..bf93386c46147eca75e33c59a13b9f8214f49ba4 100644 (file)
@@ -869,6 +869,16 @@ end:
        return home_dir;
 }
 
+/*
+ * 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.
  *
index b872b53192bb77d575763ec70bb2e4778324c68e..cc80a53690fc8f7a963f55b83d1c25cb36504a1d 100644 (file)
@@ -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,
This page took 0.034076 seconds and 5 git commands to generate.