[lttng-dev] [PATCH lttng-tools] sessiond: add --extra-kmod-probes option
David Goulet
dgoulet at efficios.com
Fri Sep 19 12:13:57 EDT 2014
Merged!
Small fixes of the syntax in the commit.
David
On 12 Sep (21:37:18), Philippe Proulx wrote:
> This patch adds the --extra-kmod-probes option to
> lttng-sessiond. The LTTNG_EXTRA_KMOD_PROBES environment
> variable may also be used.
>
> The option specifies a list of extra probe kernel modules
> to be loaded (and unloaded) by lttng-sessiond. The list
> is appended to either the default list or to the
> user-supplied --kmod-probes list.
>
> This option is especially useful for kernel developers who
> need the default LTTng kernel probes plus additional probes
> in order to instrument their custom kernel or module. This
> becomes easy with --extra-kmod-probes:
>
> lttng-sessiond --extra-kmod-probes=custom_subsys,other
>
> would load all known and available LTTng kernel probes plus
> lttng_probe_custom_subsys and lttng_probe_other.
>
> Signed-off-by: Philippe Proulx <eeppeliteloop at gmail.com>
> ---
> doc/man/lttng-sessiond.8 | 8 ++
> src/bin/lttng-sessiond/main.c | 10 ++
> src/bin/lttng-sessiond/modprobe.c | 202 +++++++++++++++++++++++++++++---------
> src/bin/lttng-sessiond/modprobe.h | 1 +
> src/common/defaults.h | 3 +
> src/common/utils.c | 12 ++-
> src/common/utils.h | 1 +
> 7 files changed, 192 insertions(+), 45 deletions(-)
>
> diff --git a/doc/man/lttng-sessiond.8 b/doc/man/lttng-sessiond.8
> index 212b743..9cd148e 100644
> --- a/doc/man/lttng-sessiond.8
> +++ b/doc/man/lttng-sessiond.8
> @@ -86,6 +86,12 @@ 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 " --extra-kmod-probes=probe1, probe2, ..."
> +Specify extra kernel modules containing LTTng probes to be loaded by the session
> +daemon. The list follows the format of the \fB--kmod-probes\fP option.
> +This list is appended to the list provided by \fB--kmod-probes\fP or, if
> +\fB--kmod-probes\fP is missing, to the default list of probes.
> +.TP
> .BR "-c, --client-sock=PATH"
> Specify path for the client unix socket
> .TP
> @@ -175,6 +181,8 @@ the timeout of the operating system (this is the default).
> 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.
> +.IP "LTTNG_EXTRA_KMOD_PROBES"
> +Specify extra kernel modules probes that should be loaded by the session daemon.
> .SH "SEE ALSO"
>
> .PP
> diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c
> index c7fc178..2a97c37 100644
> --- a/src/bin/lttng-sessiond/main.c
> +++ b/src/bin/lttng-sessiond/main.c
> @@ -157,6 +157,7 @@ static const struct option long_options[] = {
> { "config", 1, 0, 'f' },
> { "load", 1, 0, 'l' },
> { "kmod-probes", 1, 0, 'P' },
> + { "extra-kmod-probes", 1, 0, 'e' },
> { NULL, 0, 0, 0 }
> };
>
> @@ -4214,6 +4215,7 @@ static void usage(void)
> 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");
> + fprintf(stderr, " --extra-kmod-probes Specify extra kernel module probes to load\n");
> }
>
> /*
> @@ -4400,6 +4402,14 @@ static int set_option(int opt, const char *arg, const char *optname)
> ret = -ENOMEM;
> }
> break;
> + case 'e':
> + free(kmod_extra_probes_list);
> + kmod_extra_probes_list = strdup(arg);
> + if (!kmod_extra_probes_list) {
> + perror("strdup");
> + ret = -ENOMEM;
> + }
> + break;
> case 'f':
> /* This is handled in set_options() thus silent break. */
> break;
> diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c
> index adad7bf..2a0b66a 100644
> --- a/src/bin/lttng-sessiond/modprobe.c
> +++ b/src/bin/lttng-sessiond/modprobe.c
> @@ -95,6 +95,7 @@ struct kern_modules_param kern_modules_probes_default[] = {
> /* dynamic probe modules list */
> static struct kern_modules_param *probes;
> static int nr_probes;
> +static int probes_capacity;
>
> void modprobe_remove_lttng(const struct kern_modules_param *modules,
> int entries, int required)
> @@ -122,8 +123,6 @@ void modprobe_remove_lttng(const struct kern_modules_param *modules,
> DBG("Modprobe removal successful %s",
> modules[i].name);
> }
> - if (probes)
> - free(probes[i].name);
> }
> }
>
> @@ -145,14 +144,18 @@ void modprobe_remove_lttng_control(void)
> */
> void modprobe_remove_lttng_data(void)
> {
> + int i;
> +
> if (probes) {
> modprobe_remove_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
> +
> + for (i = 0; i < nr_probes; ++i) {
> + free(probes[i].name);
> + }
> +
> free(probes);
> probes = NULL;
> - } else
> - modprobe_remove_lttng(kern_modules_probes_default,
> - ARRAY_SIZE(kern_modules_probes_default),
> - LTTNG_MOD_OPTIONAL);
> + }
> }
>
> /*
> @@ -280,72 +283,183 @@ int modprobe_lttng_control(void)
> return ret;
> }
>
> -/*
> - * Load data kernel module(s).
> +/**
> + * Grow global list of probes (double capacity or set it to 1 if
> + * currently 0 and copy existing data).
> */
> -int modprobe_lttng_data(void)
> +static int grow_probes(void)
> {
> - int i, ret;
> - int entries = ARRAY_SIZE(kern_modules_probes_default);
> - char *list, *next;
> + int i;
>
> - /*
> - * 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);
> + /* Initialize capacity to 1 if 0. */
> + if (probes_capacity == 0) {
> + probes = zmalloc(sizeof(*probes));
> +
> + if (!probes) {
> + PERROR("malloc probe list");
> + return -ENOMEM;
> + }
> +
> + probes_capacity = 1;
> +
> + return 0;
> }
>
> - /*
> - * 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) {
> + /* Double size. */
> + probes_capacity *= 2;
> +
> + struct kern_modules_param *tmp_probes =
> + zmalloc(sizeof(*tmp_probes) * probes_capacity);
> +
> + if (!tmp_probes) {
> PERROR("malloc probe list");
> return -ENOMEM;
> }
>
> - for (i = 0; i < entries; i++) {
> - size_t name_len;
> + for (i = 0; i < nr_probes; ++i) {
> + /* Move name pointer. */
> + tmp_probes[i].name = probes[i].name;
> + }
> +
> + /* Replace probes with larger copy. */
> + free(probes);
> + probes = tmp_probes;
>
> - next = strtok(list, ",");
> + return 0;
> +}
> +
> +/*
> + * Appends a comma-separated list of probes to the global list
> + * of probes.
> + */
> +static int append_list_to_probes(const char* list)
> +{
> + char *next;
> + int ret;
> + int at = nr_probes;
> +
> + char* tmp_list = strdup(list);
> +
> + if (!tmp_list) {
> + PERROR("strdup temp list");
> + return -ENOMEM;
> + }
> +
> + for (;;) {
> + next = strtok(tmp_list, ",");
> if (!next) {
> - goto out;
> + break;
> }
> - list = NULL;
> + tmp_list = NULL;
>
> /* filter leading spaces */
> while (*next == ' ') {
> next++;
> }
>
> + if (probes_capacity <= nr_probes) {
> + ret = grow_probes();
> +
> + if (ret) {
> + return ret;
> + }
> + }
> +
> /* Length 13 is "lttng-probe-" + \0 */
> - name_len = strlen(next) + 13;
> + size_t name_len = strlen(next) + 13;
> +
> + struct kern_modules_param *cur = &probes[at];
>
> - probes[i].name = zmalloc(name_len);
> - if (!probes[i].name) {
> + cur->name = zmalloc(name_len);
> + if (!cur->name) {
> PERROR("malloc probe list");
> return -ENOMEM;
> }
>
> - ret = snprintf(probes[i].name, name_len, "lttng-probe-%s", next);
> + ret = snprintf(cur->name, name_len, "lttng-probe-%s", next);
> +
> if (ret < 0) {
> PERROR("snprintf modprobe name");
> - goto out;
> + return -ENOMEM;
> + }
> +
> + at++;
> + nr_probes++;
> + }
> +
> + free(tmp_list);
> +
> + return 0;
> +}
> +
> +/*
> + * Load data kernel module(s).
> + */
> +int modprobe_lttng_data(void)
> +{
> + int ret, i;
> + char *list;
> +
> + /*
> + * Base probes: either from command line option, environment
> + * variable or default list.
> + */
> + if (kmod_probes_list) {
> + list = kmod_probes_list;
> + } else {
> + list = utils_get_kmod_probes_list();
> + }
> +
> + if (list) {
> + /* User-specified probes. */
> + ret = append_list_to_probes(list);
> +
> + if (ret) {
> + return ret;
> + }
> + } else {
> + /* Default probes. */
> + int def_len = ARRAY_SIZE(kern_modules_probes_default);
> + probes = zmalloc(sizeof(*probes) * def_len);
> +
> + if (!probes) {
> + PERROR("malloc probe list");
> + return -ENOMEM;
> + }
> +
> + nr_probes = probes_capacity = def_len;
> +
> + for (i = 0; i < def_len; ++i) {
> + char* name = strdup(kern_modules_probes_default[i].name);
> +
> + if (!name) {
> + PERROR("strdup probe item");
> + return -ENOMEM;
> + }
> +
> + probes[i].name = name;
> }
> }
>
> -out:
> - nr_probes = i;
> + /*
> + * Extra modules? Append them to current probes list.
> + */
> + if (kmod_extra_probes_list) {
> + list = kmod_extra_probes_list;
> + } else {
> + list = utils_get_extra_kmod_probes_list();
> + }
> +
> + if (list) {
> + ret = append_list_to_probes(list);
> +
> + if (ret) {
> + return ret;
> + }
> + }
> +
> + /*
> + * Load probes modules now.
> + */
> 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 42e1912..cc44160 100644
> --- a/src/bin/lttng-sessiond/modprobe.h
> +++ b/src/bin/lttng-sessiond/modprobe.h
> @@ -25,5 +25,6 @@ int modprobe_lttng_control(void);
> int modprobe_lttng_data(void);
>
> char *kmod_probes_list;
> +char *kmod_extra_probes_list;
>
> #endif /* _MODPROBE_H */
> diff --git a/src/common/defaults.h b/src/common/defaults.h
> index 88f7fe8..25d7b32 100644
> --- a/src/common/defaults.h
> +++ b/src/common/defaults.h
> @@ -94,6 +94,9 @@
> /* Default probes list */
> #define DEFAULT_LTTNG_KMOD_PROBES "LTTNG_KMOD_PROBES"
>
> +/* Default extra probes list */
> +#define DEFAULT_LTTNG_EXTRA_KMOD_PROBES "LTTNG_EXTRA_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 ff6d1c2..1d07cb3 100644
> --- a/src/common/utils.c
> +++ b/src/common/utils.c
> @@ -927,7 +927,7 @@ end:
>
> /*
> * Obtain the value of LTTNG_KMOD_PROBES environment variable, if exists.
> - * Otherwise returns an empty string.
> + * Otherwise returns NULL.
> */
> LTTNG_HIDDEN
> char *utils_get_kmod_probes_list(void)
> @@ -936,6 +936,16 @@ char *utils_get_kmod_probes_list(void)
> }
>
> /*
> + * Obtain the value of LTTNG_EXTRA_KMOD_PROBES environment variable, if
> + * exists. Otherwise returns NULL.
> + */
> +LTTNG_HIDDEN
> +char *utils_get_extra_kmod_probes_list(void)
> +{
> + return getenv(DEFAULT_LTTNG_EXTRA_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 bdc0e14..537fe0f 100644
> --- a/src/common/utils.h
> +++ b/src/common/utils.h
> @@ -48,6 +48,7 @@ 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);
> +char *utils_get_extra_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,
> --
> 2.1.0
>
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 603 bytes
Desc: Digital signature
URL: <http://lists.lttng.org/pipermail/lttng-dev/attachments/20140919/6cda6fed/attachment.sig>
More information about the lttng-dev
mailing list