futex.c futex.h \
shm.c shm.h \
session.c session.h \
+ modprobe.c modprobe.h kern-modules.h \
lttng-ust-ctl.h lttng-ust-abi.h
if HAVE_LIBLTTNG_UST_CTL
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KERN_MODULES_H
+#define _KERN_MODULES_H
+
+/*
+ * Compatible lttng-modules version.
+ */
+#define KERN_MODULES_VERSION 0
+#define KERN_MODULES_PATCHLEVEL 9
+#define KERN_MODULES_SUBLEVEL 1
+
+struct kern_modules_param {
+ const char *name;
+ int required;
+};
+
+#endif /* _KERN_MODULES_H */
#include <common/kernel-ctl/kernel-ctl.h>
#include "kernel.h"
+#include "kern-modules.h"
/*
* Add context on a kernel channel.
error:
return -1;
}
+
+/*
+ * Get kernel version and validate it.
+ */
+int kernel_validate_version(int tracer_fd)
+{
+ int ret;
+ struct lttng_kernel_tracer_version version;
+
+ ret = kernctl_tracer_version(tracer_fd, &version);
+ if (ret < 0) {
+ ERR("Failed at getting the lttng-modules version");
+ goto error;
+ }
+
+ /* Validate version */
+ if (version.version > KERN_MODULES_VERSION) {
+ goto error_version;
+ } else {
+ if (version.patchlevel > KERN_MODULES_PATCHLEVEL) {
+ goto error_version;
+ }
+ else {
+ if (version.sublevel > KERN_MODULES_SUBLEVEL) {
+ goto error_version;
+ }
+ }
+ }
+
+ DBG2("Kernel tracer version validated (%d.%d.%d)", version.version,
+ version.patchlevel, version.sublevel);
+
+ return 0;
+
+error_version:
+ ERR("Kernel version is not compatible %d.%d.%d (supporting <= %d.%d.%d)",
+ version.version, version.patchlevel, version.sublevel,
+ KERN_MODULES_VERSION, KERN_MODULES_PATCHLEVEL,
+ KERN_MODULES_SUBLEVEL);
+ ret = -1;
+
+error:
+ return ret;
+}
ssize_t kernel_list_events(int tracer_fd, struct lttng_event **event_list);
void kernel_wait_quiescent(int fd);
int kernel_calibrate(int fd, struct lttng_kernel_calibrate *calibrate);
+int kernel_validate_version(int tracer_fd);
#endif /* _LTT_KERNEL_CTL_H */
#include "session.h"
#include "ust-app.h"
-struct module_param {
- const char *name;
- int required;
-};
-
-/* LTTng kernel tracer modules list */
-const struct module_param kernel_modules_list[] = {
- { "lttng-ftrace", 0 },
- { "lttng-kprobes", 0 },
- { "lttng-kretprobes", 0 },
- { "lib-ring-buffer", 1 },
- { "ltt-relay", 1 },
- { "ltt-ring-buffer-client-discard", 1 },
- { "ltt-ring-buffer-client-overwrite", 1 },
- { "ltt-ring-buffer-metadata-client", 1 },
- { "ltt-ring-buffer-client-mmap-discard", 1 },
- { "ltt-ring-buffer-client-mmap-overwrite", 1 },
- { "ltt-ring-buffer-metadata-mmap-client", 1 },
- { "lttng-probe-lttng", 1 },
- { "lttng-types", 0 },
- { "lttng-probe-block", 0 },
- { "lttng-probe-irq", 0 },
- { "lttng-probe-kvm", 0 },
- { "lttng-probe-sched", 0 },
-};
+const char *module_proc_lttng = "/proc/lttng";
extern const char default_home_dir[],
default_tracing_group[],
#include "event.h"
#include "futex.h"
#include "kernel.h"
+#include "modprobe.h"
#include "shm.h"
#include "ust-ctl.h"
#include "utils.h"
return 0;
}
-/*
- * Remove modules in reverse load order.
- */
-static int modprobe_remove_kernel_modules(void)
-{
- int ret = 0, i;
- char modprobe[256];
-
- for (i = ARRAY_SIZE(kernel_modules_list) - 1; i >= 0; i--) {
- ret = snprintf(modprobe, sizeof(modprobe),
- "/sbin/modprobe -r -q %s",
- kernel_modules_list[i].name);
- if (ret < 0) {
- perror("snprintf modprobe -r");
- goto error;
- }
- modprobe[sizeof(modprobe) - 1] = '\0';
- ret = system(modprobe);
- if (ret == -1) {
- ERR("Unable to launch modprobe -r for module %s",
- kernel_modules_list[i].name);
- } else if (kernel_modules_list[i].required
- && WEXITSTATUS(ret) != 0) {
- ERR("Unable to remove module %s",
- kernel_modules_list[i].name);
- } else {
- DBG("Modprobe removal successful %s",
- kernel_modules_list[i].name);
- }
- }
-
-error:
- return ret;
-}
-
/*
* Return group ID of the tracing group or -1 if not found.
*/
DBG2("Closing kernel fd");
close(kernel_tracer_fd);
DBG("Unloading kernel modules");
- modprobe_remove_kernel_modules();
+ modprobe_remove_lttng_all();
}
close(thread_quit_pipe[0]);
}
/*
- * modprobe_kernel_modules
+ * Check version of the lttng-modules.
*/
-static int modprobe_kernel_modules(void)
+static int validate_lttng_modules_version(void)
{
- int ret = 0, i;
- char modprobe[256];
-
- for (i = 0; i < ARRAY_SIZE(kernel_modules_list); i++) {
- ret = snprintf(modprobe, sizeof(modprobe),
- "/sbin/modprobe %s%s",
- kernel_modules_list[i].required ? "" : "-q ",
- kernel_modules_list[i].name);
- if (ret < 0) {
- perror("snprintf modprobe");
- goto error;
- }
- modprobe[sizeof(modprobe) - 1] = '\0';
- ret = system(modprobe);
- if (ret == -1) {
- ERR("Unable to launch modprobe for module %s",
- kernel_modules_list[i].name);
- } else if (kernel_modules_list[i].required
- && WEXITSTATUS(ret) != 0) {
- ERR("Unable to load module %s",
- kernel_modules_list[i].name);
- } else {
- DBG("Modprobe successfully %s",
- kernel_modules_list[i].name);
- }
- }
-
-error:
- return ret;
+ return kernel_validate_version(kernel_tracer_fd);
}
/*
- * mount_debugfs
+ * Setup necessary data for kernel tracer action.
*/
-static int mount_debugfs(char *path)
+static int init_kernel_tracer(void)
{
int ret;
- char *type = "debugfs";
-
- ret = run_as_mkdir_recursive(path, S_IRWXU | S_IRWXG, geteuid(), getegid());
- if (ret < 0) {
- PERROR("Cannot create debugfs path");
- goto error;
- }
- ret = mount(type, path, type, 0, NULL);
+ /* Modprobe lttng kernel modules */
+ ret = modprobe_lttng_control();
if (ret < 0) {
- PERROR("Cannot mount debugfs");
goto error;
}
- DBG("Mounted debugfs successfully at %s", path);
-
-error:
- return ret;
-}
-
-/*
- * Setup necessary data for kernel tracer action.
- */
-static void init_kernel_tracer(void)
-{
- int ret;
- char *proc_mounts = "/proc/mounts";
- char line[256];
- char *debugfs_path = NULL, *lttng_path = NULL;
- 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) {
- perror("Cannot mount debugfs");
- goto error;
- }
+ /* Open debugfs lttng */
+ kernel_tracer_fd = open(module_proc_lttng, O_RDWR);
+ if (kernel_tracer_fd < 0) {
+ DBG("Failed to open %s", module_proc_lttng);
+ ret = -1;
+ goto error_open;
}
- /* Modprobe lttng kernel modules */
- ret = modprobe_kernel_modules();
+ /* Validate kernel version */
+ ret = validate_lttng_modules_version();
if (ret < 0) {
- goto error;
+ goto error_version;
}
- /* Setup lttng kernel path */
- ret = asprintf(<tng_path, "%s/lttng", debugfs_path);
+ ret = modprobe_lttng_data();
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) {
- DBG("Failed to open %s", lttng_path);
- goto error;
+ goto error_modules;
}
- free(lttng_path);
- free(debugfs_path);
DBG("Kernel tracer fd %d", kernel_tracer_fd);
- return;
+ return 0;
+
+error_version:
+ modprobe_remove_lttng_control();
+ close(kernel_tracer_fd);
+ kernel_tracer_fd = 0;
+ return LTTCOMM_KERN_VERSION;
+
+error_modules:
+ close(kernel_tracer_fd);
+
+error_open:
+ modprobe_remove_lttng_control();
error:
- if (lttng_path) {
- free(lttng_path);
- }
- if (debugfs_path) {
- free(debugfs_path);
- }
WARN("No kernel tracer available");
kernel_tracer_fd = 0;
- return;
+ return LTTCOMM_KERN_NA;
}
/*
/* Kernel tracer check */
if (kernel_tracer_fd == 0) {
/* Basically, load kernel tracer modules */
- init_kernel_tracer();
- if (kernel_tracer_fd == 0) {
- ret = LTTCOMM_KERN_NA;
+ ret = init_kernel_tracer();
+ if (ret != 0) {
goto error;
}
}
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#include <common/common.h>
+
+#include "modprobe.h"
+#include "kern-modules.h"
+
+/* MUST be loaded first */
+const struct kern_modules_param kern_modules_control[] = {
+ { "ltt-relay", 1 },
+};
+
+/* LTTng kernel tracer modules list */
+const struct kern_modules_param kern_modules_list[] = {
+ { "lttng-ftrace", 0 },
+ { "lttng-kprobes", 0 },
+ { "lttng-kretprobes", 0 },
+ { "lib-ring-buffer", 1 },
+ { "ltt-ring-buffer-client-discard", 1 },
+ { "ltt-ring-buffer-client-overwrite", 1 },
+ { "ltt-ring-buffer-metadata-client", 1 },
+ { "ltt-ring-buffer-client-mmap-discard", 1 },
+ { "ltt-ring-buffer-client-mmap-overwrite", 1 },
+ { "ltt-ring-buffer-metadata-mmap-client", 1 },
+ { "lttng-probe-lttng", 1 },
+ { "lttng-types", 0 },
+ { "lttng-probe-block", 0 },
+ { "lttng-probe-irq", 0 },
+ { "lttng-probe-kvm", 0 },
+ { "lttng-probe-sched", 0 },
+};
+
+/*
+ * Remove control kernel module(s) in reverse load order.
+ */
+void modprobe_remove_lttng_control(void)
+{
+ int ret = 0, i;
+ char modprobe[256];
+
+ for (i = ARRAY_SIZE(kern_modules_control) - 1; i >= 0; i--) {
+ ret = snprintf(modprobe, sizeof(modprobe),
+ "/sbin/modprobe -r -q %s",
+ kern_modules_control[i].name);
+ if (ret < 0) {
+ PERROR("snprintf modprobe -r");
+ goto error;
+ }
+ modprobe[sizeof(modprobe) - 1] = '\0';
+ ret = system(modprobe);
+ if (ret == -1) {
+ ERR("Unable to launch modprobe -r for module %s",
+ kern_modules_control[i].name);
+ } else if (kern_modules_control[i].required
+ && WEXITSTATUS(ret) != 0) {
+ ERR("Unable to remove module %s",
+ kern_modules_control[i].name);
+ } else {
+ DBG("Modprobe removal successful %s",
+ kern_modules_control[i].name);
+ }
+ }
+
+error:
+ return;
+}
+
+/*
+ * Remove data kernel modules in reverse load order.
+ */
+void modprobe_remove_lttng_data(void)
+{
+ int ret = 0, i;
+ char modprobe[256];
+
+ for (i = ARRAY_SIZE(kern_modules_list) - 1; i >= 0; i--) {
+ ret = snprintf(modprobe, sizeof(modprobe),
+ "/sbin/modprobe -r -q %s",
+ kern_modules_list[i].name);
+ if (ret < 0) {
+ perror("snprintf modprobe -r");
+ goto error;
+ }
+ modprobe[sizeof(modprobe) - 1] = '\0';
+ ret = system(modprobe);
+ if (ret == -1) {
+ ERR("Unable to launch modprobe -r for module %s",
+ kern_modules_list[i].name);
+ } else if (kern_modules_list[i].required
+ && WEXITSTATUS(ret) != 0) {
+ ERR("Unable to remove module %s",
+ kern_modules_list[i].name);
+ } else {
+ DBG("Modprobe removal successful %s",
+ kern_modules_list[i].name);
+ }
+ }
+
+error:
+ return;
+}
+
+/*
+ * Remove all kernel modules in reverse order.
+ */
+void modprobe_remove_lttng_all(void)
+{
+ modprobe_remove_lttng_data();
+ modprobe_remove_lttng_control();
+}
+
+/*
+ * Load control kernel module(s).
+ */
+int modprobe_lttng_control(void)
+{
+ int ret = 0, i;
+ char modprobe[256];
+
+ for (i = 0; i < ARRAY_SIZE(kern_modules_control); i++) {
+ ret = snprintf(modprobe, sizeof(modprobe),
+ "/sbin/modprobe %s%s",
+ kern_modules_control[i].required ? "" : "-q ",
+ kern_modules_control[i].name);
+ if (ret < 0) {
+ PERROR("snprintf modprobe");
+ goto error;
+ }
+ modprobe[sizeof(modprobe) - 1] = '\0';
+ ret = system(modprobe);
+ if (ret == -1) {
+ ERR("Unable to launch modprobe for module %s",
+ kern_modules_control[i].name);
+ } else if (kern_modules_control[i].required
+ && WEXITSTATUS(ret) != 0) {
+ ERR("Unable to load module %s",
+ kern_modules_control[i].name);
+ } else {
+ DBG("Modprobe successfully %s",
+ kern_modules_control[i].name);
+ }
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * Load data kernel module(s).
+ */
+int modprobe_lttng_data(void)
+{
+ int ret = 0, i;
+ char modprobe[256];
+
+ for (i = 0; i < ARRAY_SIZE(kern_modules_list); i++) {
+ ret = snprintf(modprobe, sizeof(modprobe),
+ "/sbin/modprobe %s%s",
+ kern_modules_list[i].required ? "" : "-q ",
+ kern_modules_list[i].name);
+ if (ret < 0) {
+ perror("snprintf modprobe");
+ goto error;
+ }
+ modprobe[sizeof(modprobe) - 1] = '\0';
+ ret = system(modprobe);
+ if (ret == -1) {
+ ERR("Unable to launch modprobe for module %s",
+ kern_modules_list[i].name);
+ } else if (kern_modules_list[i].required
+ && WEXITSTATUS(ret) != 0) {
+ ERR("Unable to load module %s",
+ kern_modules_list[i].name);
+ } else {
+ DBG("Modprobe successfully %s",
+ kern_modules_list[i].name);
+ }
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * Load all lttng kernel modules.
+ */
+int modprobe_lttng_all(void)
+{
+ int ret;
+
+ ret = modprobe_lttng_control();
+ if (ret < 0) {
+ goto error;
+ }
+
+ ret = modprobe_lttng_data();
+ if (ret < 0) {
+ goto error;
+ }
+
+error:
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MODPROBE_H
+#define _MODPROBE_H
+
+void modprobe_remove_lttng_all(void);
+void modprobe_remove_lttng_control(void);
+void modprobe_remove_lttng_data(void);
+int modprobe_lttng_all(void);
+int modprobe_lttng_control(void);
+int modprobe_lttng_data(void);
+
+#endif /* _MODPROBE_H */