From b73401da87657682c2b51665a6fd1950f5c362f1 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 7 Jul 2011 10:29:19 -0400 Subject: [PATCH] Add detection of debugfs and kernel module loading The session daemon now detects the path of the debugfs mount point or create and mount it at a default location (/mnt/debugfs). Then, the kernel module are loaded automatically, if present, and the kernel tracer fd is opened at the previous detected debugfs path. The kernel module list is hardcoded for now. NOTE: There is no module unload at the session daemon cleanup. This is to avoid removing tracing capabilities when a trace is ongoing and written to disk. Signed-off-by: David Goulet --- ltt-sessiond/ltt-sessiond.h | 25 +++++-- ltt-sessiond/main.c | 128 ++++++++++++++++++++++++++++++++++-- 2 files changed, 144 insertions(+), 9 deletions(-) diff --git a/ltt-sessiond/ltt-sessiond.h b/ltt-sessiond/ltt-sessiond.h index af48cd92a..e87830211 100644 --- a/ltt-sessiond/ltt-sessiond.h +++ b/ltt-sessiond/ltt-sessiond.h @@ -24,10 +24,27 @@ #define DEFAULT_GLOBAL_APPS_PIPE DEFAULT_UST_SOCK_DIR "/global" #define DEFAULT_TRACE_OUTPUT DEFAULT_HOME_DIR "/lttng" -/* - * Kernel tracer defines - */ -#define DEFAULT_KERNEL_TRACER_PATH "/mnt/debugfs/lttng" +/* LTTng kernel tracer modules list */ +const char *kernel_modules_list[] = { + "lib-ring-buffer", + "ltt-relay", + "ltt-ring-buffer-client-discard", + "ltt-ring-buffer-client-overwrite", + "ltt-ring-buffer-metadata-client", + "ltt-ring-buffer-client-mmap-discard", + "ltt-ring-buffer-client-mmap-overwrite", + "ltt-ring-buffer-metadata-mmap-client", + "lttng-ftrace", + "lttng-kprobes", + "lttng-probe-block", + "lttng-probe-irq", + "lttng-probe-kvm", + "lttng-probe-lttng", + "lttng-probe-sched", + "lttng-probe-syscalls", + "lttng-types", + NULL, +}; extern const char default_home_dir[], default_tracing_group[], diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 0ab3ad9a7..205548bed 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -641,6 +642,58 @@ error: return ret; } +/* + * modprobe_kernel_modules + */ +static int modprobe_kernel_modules(void) +{ + int ret = 0, i = 0; + char modprobe[256]; + + while (kernel_modules_list[i] != NULL) { + ret = snprintf(modprobe, sizeof(modprobe), "/sbin/modprobe %s", + kernel_modules_list[i]); + if (ret < 0) { + perror("snprintf modprobe"); + goto error; + } + ret = system(modprobe); + if (ret < 0) { + ERR("Unable to load module %s", kernel_modules_list[i]); + } + DBG("Modprobe successfully %s", kernel_modules_list[i]); + i++; + } + +error: + return ret; +} + +/* + * mount_debugfs + */ +static int mount_debugfs(char *path) +{ + int ret; + char *type = "debugfs"; + + ret = mkdir_recursive(path, S_IRWXU | S_IRWXG); + if (ret < 0) { + goto error; + } + + ret = mount(type, path, type, 0, NULL); + if (ret < 0) { + perror("mount debugfs"); + goto error; + } + + DBG("Mounted debugfs successfully at %s", path); + +error: + return ret; +} + /* * init_kernel_tracer * @@ -648,14 +701,80 @@ error: */ static void init_kernel_tracer(void) { - /* Set the global kernel tracer fd */ - kernel_tracer_fd = open(DEFAULT_KERNEL_TRACER_PATH, O_RDWR); + int ret; + char *proc_mounts = "/proc/mounts"; + char line[256]; + char *debugfs_path = NULL, *lttng_path; + FILE *fp; + + /* Detect debugfs */ + fp = fopen(proc_mounts, "r"); + if (fp == NULL) { + ERR("Unable to probe %s", proc_mounts); + goto error; + } + + while (fgets(line, sizeof(line), fp) != NULL) { + if (strstr(line, "debugfs") != NULL) { + /* Remove first string */ + strtok(line, " "); + /* Dup string here so we can reuse line later on */ + debugfs_path = strdup(strtok(NULL, " ")); + DBG("Got debugfs path : %s", debugfs_path); + break; + } + } + + fclose(fp); + + /* Mount debugfs if needded */ + if (debugfs_path == NULL) { + ret = asprintf(&debugfs_path, "/mnt/debugfs"); + if (ret < 0) { + perror("asprintf debugfs path"); + goto error; + } + ret = mount_debugfs(debugfs_path); + if (ret < 0) { + goto error; + } + } + + /* Modprobe lttng kernel modules */ + ret = modprobe_kernel_modules(); + if (ret < 0) { + goto error; + } + + /* Setup lttng kernel path */ + ret = asprintf(<tng_path, "%s/lttng", debugfs_path); + if (ret < 0) { + perror("asprintf lttng path"); + goto error; + } + + /* Open debugfs lttng */ + kernel_tracer_fd = open(lttng_path, O_RDWR); if (kernel_tracer_fd < 0) { - WARN("No kernel tracer available"); - kernel_tracer_fd = 0; + DBG("Failed to open %s", lttng_path); + goto error; } + free(lttng_path); + free(debugfs_path); DBG("Kernel tracer fd %d", kernel_tracer_fd); + return; + +error: + if (lttng_path) { + free(lttng_path); + } + if (debugfs_path) { + free(debugfs_path); + } + WARN("No kernel tracer available"); + kernel_tracer_fd = 0; + return; } /* @@ -1995,7 +2114,6 @@ int main(int argc, char **argv) /* Check if daemon is UID = 0 */ is_root = !getuid(); - /* Set all sockets path */ if (is_root) { ret = create_lttng_rundir(); if (ret < 0) { -- 2.34.1