extern int lttng_kernel_create_session(void);
extern int lttng_kernel_start_tracing(void);
extern int lttng_kernel_stop_tracing(void);
-extern int lttng_kernel_create_channel(int overwrite,
- uint64_t subbuf_size, uint64_t num_subbuf,
- unsigned int switch_timer_interval,
- unsigned int read_timer_interval);
+extern int lttng_kernel_create_channel(void);
#endif /* _LIBLTTNGCTL_H */
*
* Create a channel in the kernel tracer.
*/
-int lttng_kernel_create_channel(int overwrite,
- u64 subbuf_size, u64 num_subbuf,
- unsigned int switch_timer_interval,
- unsigned int read_timer_interval)
+int lttng_kernel_create_channel(void)
{
- /* Write setting to the session message */
- lsm.u.create_channel.overwrite = overwrite;
- lsm.u.create_channel.subbuf_size = subbuf_size;
- lsm.u.create_channel.num_subbuf = num_subbuf;
- lsm.u.create_channel.switch_timer_interval = switch_timer_interval;
- lsm.u.create_channel.read_timer_interval = read_timer_interval;
-
return ask_sessiond(KERNEL_CREATE_CHANNEL, NULL);
}
[ LTTCOMM_ERR_INDEX(LTTCOMM_NO_TRACEABLE) ] = "App is not traceable",
[ LTTCOMM_ERR_INDEX(LTTCOMM_SELECT_SESS) ] = "A session MUST be selected",
[ LTTCOMM_ERR_INDEX(LTTCOMM_EXIST_SESS) ] = "Session name already exist",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_NA) ] = "Kernel tracer not available",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_SESS_FAIL) ] = "Kernel create session failed",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_FAIL) ] = "Kernel create channel failed",
[ LTTCOMM_ERR_INDEX(KCONSUMERD_COMMAND_SOCK_READY) ] = "Kconsumerd command socket ready",
[ LTTCOMM_ERR_INDEX(KCONSUMERD_SUCCESS_RECV_FD) ] = "Kconsumerd success on receiving fds",
[ LTTCOMM_ERR_INDEX(KCONSUMERD_ERROR_RECV_FD) ] = "Kconsumerd error on receiving fds",
* lttcomm error code.
*/
enum lttcomm_return_code {
- LTTCOMM_OK = 1000, /* Ok */
- LTTCOMM_ERR, /* Unknown Error */
- LTTCOMM_UND, /* Undefine command */
- LTTCOMM_ALLOC_FAIL, /* Trace allocation fail */
- LTTCOMM_NO_SESSION, /* No session found */
- LTTCOMM_CREATE_FAIL, /* Create trace fail */
- LTTCOMM_SESSION_FAIL, /* Create session fail */
- LTTCOMM_START_FAIL, /* Start tracing fail */
- LTTCOMM_STOP_FAIL, /* Stop tracing fail */
- LTTCOMM_LIST_FAIL, /* Listing apps fail */
- LTTCOMM_NO_APPS, /* No traceable application */
- LTTCOMM_NO_SESS, /* No sessions available */
- LTTCOMM_NO_TRACE, /* No trace exist */
- LTTCOMM_FATAL, /* Session daemon had a fatal error */
- LTTCOMM_NO_TRACEABLE, /* Error for non traceable app */
- LTTCOMM_SELECT_SESS, /* Must select a session */
- LTTCOMM_EXIST_SESS, /* Session name already exist */
- LTTCOMM_NO_EVENT, /* No event found */
- LTTCOMM_NR, /* Last element */
+ LTTCOMM_OK = 1000, /* Ok */
+ LTTCOMM_ERR, /* Unknown Error */
+ LTTCOMM_UND, /* Undefine command */
+ LTTCOMM_ALLOC_FAIL, /* Trace allocation fail */
+ LTTCOMM_NO_SESSION, /* No session found */
+ LTTCOMM_CREATE_FAIL, /* Create trace fail */
+ LTTCOMM_SESSION_FAIL, /* Create session fail */
+ LTTCOMM_START_FAIL, /* Start tracing fail */
+ LTTCOMM_STOP_FAIL, /* Stop tracing fail */
+ LTTCOMM_LIST_FAIL, /* Listing apps fail */
+ LTTCOMM_NO_APPS, /* No traceable application */
+ LTTCOMM_NO_SESS, /* No sessions available */
+ LTTCOMM_NO_TRACE, /* No trace exist */
+ LTTCOMM_FATAL, /* Session daemon had a fatal error */
+ LTTCOMM_NO_TRACEABLE, /* Error for non traceable app */
+ LTTCOMM_SELECT_SESS, /* Must select a session */
+ LTTCOMM_EXIST_SESS, /* Session name already exist */
+ LTTCOMM_NO_EVENT, /* No event found */
+ LTTCOMM_KERN_NA, /* Kernel tracer unavalable */
+ LTTCOMM_KERN_SESS_FAIL, /* Kernel create session failed */
+ LTTCOMM_KERN_CHAN_FAIL, /* Kernel create channel failed */
KCONSUMERD_COMMAND_SOCK_READY, /* when kconsumerd command socket ready */
- KCONSUMERD_SUCCESS_RECV_FD, /* success on receiving fds */
- KCONSUMERD_ERROR_RECV_FD, /* error on receiving fds */
- KCONSUMERD_POLL_ERROR, /* Error in polling thread in kconsumerd */
- KCONSUMERD_POLL_NVAL, /* Poll on closed fd */
- KCONSUMERD_POLL_HUP, /* All fds have hungup */
- KCONSUMERD_EXIT_SUCCESS, /* kconsumerd exiting normally */
- KCONSUMERD_EXIT_FAILURE, /* kconsumerd exiting on error */
- KCONSUMERD_OUTFD_ERROR, /* error opening the tracefile */
+ KCONSUMERD_SUCCESS_RECV_FD, /* success on receiving fds */
+ KCONSUMERD_ERROR_RECV_FD, /* error on receiving fds */
+ KCONSUMERD_POLL_ERROR, /* Error in polling thread in kconsumerd */
+ KCONSUMERD_POLL_NVAL, /* Poll on closed fd */
+ KCONSUMERD_POLL_HUP, /* All fds have hungup */
+ KCONSUMERD_EXIT_SUCCESS, /* kconsumerd exiting normally */
+ KCONSUMERD_EXIT_FAILURE, /* kconsumerd exiting on error */
+ KCONSUMERD_OUTFD_ERROR, /* error opening the tracefile */
+ /* MUST be last element */
+ LTTCOMM_NR, /* Last element */
};
/* commands for kconsumerd */
struct {
char event_name[NAME_MAX];
} event;
- /* Create channel kernel */
- struct {
- int overwrite;
- u64 subbuf_size;
- u64 num_subbuf;
- unsigned int switch_timer_interval;
- unsigned int read_timer_interval;
- } create_channel;
} u;
};
-AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/liblttsessiondcomm
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/liblttsessiondcomm -I$(top_srcdir)/libkernelctl
AM_CFLAGS = -fno-strict-aliasing
bin_PROGRAMS = ltt-sessiond
-ltt_sessiond_SOURCES = session.c trace.c traceable-app.c main.c
+ltt_sessiond_SOURCES = session.c trace.c traceable-app.c kernel-ctl.c main.c
ltt_sessiond_LDADD = \
- $(top_builddir)/liblttsessiondcomm/liblttsessiondcomm.la
+ $(top_builddir)/liblttsessiondcomm/liblttsessiondcomm.la \
+ $(top_builddir)/libkernelctl/libkernelctl.la
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ltt-sessiond.h"
+#include "libkernelctl.h"
+#include "kernel-ctl.h"
+#include "trace.h"
+
+/*
+ * kernel_create_session
+ *
+ * Create a new kernel session using the command context session.
+ */
+int kernel_create_session(struct command_ctx *cmd_ctx, int tracer_fd)
+{
+ int ret;
+ struct ltt_kernel_session *lks;
+
+ /* Allocate a new kernel session */
+ lks = malloc(sizeof(struct ltt_kernel_session));
+ if (lks == NULL) {
+ perror("kernel session malloc");
+ ret = -errno;
+ goto error;
+ }
+
+ ret = kernctl_create_session(tracer_fd);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Assigning session fd and to the command context */
+ lks->fd = ret;
+ cmd_ctx->session->kernel_session = lks;
+ cmd_ctx->session->kern_session_count++;
+
+ return 0;
+
+error:
+ return ret;
+}
+
+/*
+ * kernel_create_channel
+ *
+ * Create a kernel channel within the kernel session.
+ */
+int kernel_create_channel(struct command_ctx *cmd_ctx)
+{
+ int ret;
+ struct ltt_kernel_channel *lkc;
+ struct lttng_channel *chan;
+
+ lkc = malloc(sizeof(struct ltt_kernel_channel));
+ chan = malloc(sizeof(struct lttng_channel));
+
+ if (lkc == NULL || chan == NULL) {
+ perror("kernel channel malloc");
+ ret = -errno;
+ goto error;
+ }
+
+ chan->overwrite = DEFAULT_KERNEL_OVERWRITE;
+ chan->subbuf_size = DEFAULT_KERNEL_SUBBUF_SIZE;
+ chan->num_subbuf = DEFAULT_KERNEL_SUBBUF_NUM;
+ chan->switch_timer_interval = DEFAULT_KERNEL_SWITCH_TIMER;
+ chan->read_timer_interval = DEFAULT_KERNEL_READ_TIMER;
+
+ ret = kernctl_create_channel(cmd_ctx->session->kernel_session->fd, chan);
+ if (ret < 0) {
+ goto error;
+ }
+
+ lkc->fd = ret;
+ lkc->channel = chan;
+ CDS_INIT_LIST_HEAD(&lkc->events_list.head);
+
+ cmd_ctx->session->kernel_session->channel = lkc;
+
+ return 0;
+
+error:
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 _LTT_KERNEL_CTL_H
+#define _LTT_KERNEL_CTL_H
+
+int kernel_create_session(struct command_ctx *cmd_ctx, int tracer_fd);
+int kernel_create_channel(struct command_ctx *cmd_ctx);
+
+#endif /* _LTT_KERNEL_CTL_H */
#define DEFAULT_UST_SOCK_DIR "/tmp/ust-app-socks"
#define DEFAULT_GLOBAL_APPS_PIPE "/tmp/ust-app-socks/global"
+/*
+ * Kernel tracer defines
+ */
+#define DEFAULT_KERNEL_TRACER_PATH "/mnt/debugfs/lttng"
+#define DEFAULT_KERNEL_OVERWRITE 0
+#define DEFAULT_KERNEL_SUBBUF_SIZE 512 /* bytes */
+#define DEFAULT_KERNEL_SUBBUF_NUM 2 /* Must always be a power of 2 */
+#define DEFAULT_KERNEL_SWITCH_TIMER 0 /* usec */
+#define DEFAULT_KERNEL_READ_TIMER 10000 /* usec */
+
extern const char default_home_dir[],
default_tracing_group[],
default_ust_sock_dir[],
#include "liblttsessiondcomm.h"
#include "ltt-sessiond.h"
#include "lttngerr.h"
+#include "kernel-ctl.h"
#include "session.h"
#include "trace.h"
#include "traceable-app.h"
static int client_sock;
static int apps_sock;
static int kconsumerd_err_sock;
+static int kernel_tracer_fd;
/*
* thread_manage_kconsumerd
break;
}
+ /* Check command for kernel tracing */
+ switch (cmd_ctx->lsm->cmd_type) {
+ case KERNEL_CREATE_SESSION:
+ case KERNEL_CREATE_CHANNEL:
+ if (kernel_tracer_fd == 0) {
+ ret = LTTCOMM_KERN_NA;
+ goto error;
+ }
+ break;
+ }
+
/* Connect to ust apps if available pid */
if (cmd_ctx->lsm->pid > 0) {
/* Connect to app using ustctl API */
/* Process by command type */
switch (cmd_ctx->lsm->cmd_type) {
+ case KERNEL_CREATE_SESSION:
+ {
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 0) {
+ goto setup_error;
+ }
+
+ DBG("Creating kernel session");
+
+ ret = kernel_create_session(cmd_ctx, kernel_tracer_fd);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_SESS_FAIL;
+ goto error;
+ }
+
+ ret = LTTCOMM_OK;
+ break;
+ }
+ case KERNEL_CREATE_CHANNEL:
+ {
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 0) {
+ goto setup_error;
+ }
+
+ DBG("Creating kernel session");
+
+ ret = kernel_create_channel(cmd_ctx);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CHAN_FAIL;
+ goto error;
+ }
+
+ ret = LTTCOMM_OK;
+ break;
+ }
case KERNEL_ENABLE_EVENT:
{
/* Setup lttng message with no payload */
return ret;
}
+/*
+ * init_kernel_tracer
+ *
+ * Setup necessary data for kernel tracer action.
+ */
+static void init_kernel_tracer(void)
+{
+ /* Set the global kernel tracer fd */
+ kernel_tracer_fd = open(DEFAULT_KERNEL_TRACER_PATH, O_RDWR);
+ if (kernel_tracer_fd < 0) {
+ WARN("No kernel tracer available");
+ kernel_tracer_fd = 0;
+ }
+}
+
/*
* set_kconsumerd_sockets
*
if (ret < 0) {
goto error;
}
+
+ /* Setup kernel tracer */
+ init_kernel_tracer();
} else {
if (strlen(apps_unix_sock_path) == 0) {
snprintf(apps_unix_sock_path, PATH_MAX,
/* Init list */
CDS_INIT_LIST_HEAD(&new_session->ust_traces);
- CDS_INIT_LIST_HEAD(&new_session->kernel_traces);
/* Set trace list counter */
new_session->ust_trace_count = 0;
- new_session->kern_trace_count = 0;
/* Add new session to the global session list */
add_session_list(new_session);
#define _LTT_SESSION_H
#include <lttng/lttng.h>
+#include <urcu/list.h>
#include <uuid/uuid.h>
/* Global session list */
* to identify a tracing session for both LTTng and UST.
*/
struct ltt_session {
- char *name;
struct cds_list_head list;
+ char *name;
uuid_t uuid;
struct cds_list_head ust_traces;
- struct cds_list_head kernel_traces;
+ struct ltt_kernel_session *kernel_session;
unsigned int ust_trace_count;
- unsigned int kern_trace_count;
+ unsigned int kern_session_count;
pid_t ust_consumer;
pid_t kernel_consumer;
};
*/
int get_trace_count_per_session(struct ltt_session *session)
{
- return session->ust_trace_count + session->kern_trace_count;
+ return session->ust_trace_count + session->kern_session_count;
}
/*
{
int i = 0;
struct ltt_ust_trace *ust_iter;
- struct ltt_kernel_trace *kern_iter;
struct lttng_trace trace;
DBG("Getting userspace traces for session %s", session->name);
DBG("Getting kernel traces for session %s", session->name);
/* Getting kernel traces */
- cds_list_for_each_entry(kern_iter, &session->kernel_traces, list) {
+ if (session->kern_session_count > 0) {
trace.type = KERNEL;
- strncpy(trace.name, kern_iter->name, sizeof(trace.name));
- trace.name[sizeof(trace.name) - 1] = '\0';
+ strncpy(trace.name, "kernel", 6);
memcpy(&traces[i], &trace, sizeof(trace));
- memset(&trace, 0, sizeof(trace));
- i++;
}
}
#include "ltt-sessiond.h"
#include "session.h"
+#include "lttng-kernel.h"
-/* LTTng trace representation */
-struct ltt_kernel_trace {
- struct cds_list_head list;
+/* Kernel event list */
+struct ltt_kernel_event_list {
+ struct cds_list_head head;
+};
+
+/* Kernel event */
+struct ltt_kernel_event {
char name[NAME_MAX];
- struct cds_list_head marker_list;
+ int fd;
+ struct cds_list_head list;
+};
+
+/* Kernel channel */
+struct ltt_kernel_channel {
+ int fd;
+ struct lttng_channel *channel;
+ struct ltt_kernel_event_list events_list;
+};
+
+/* Kernel session */
+struct ltt_kernel_session {
+ int fd;
+ struct ltt_kernel_channel *channel;
};
/* UST trace representation */
*/
static int process_kernel_create_trace(void)
{
+ int ret;
+
+ /* Setup kernel session */
+ ret = lttng_kernel_create_session();
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Create an empty channel (with no event) */
+ ret = lttng_kernel_create_channel();
+ if (ret < 0) {
+ goto error;
+ }
+
return 0;
+
+error:
+ return ret;
}
/*
extern int opt_disable_event;
extern int opt_destroy_session;
extern int opt_create_session;
-extern int opt_create_channel;
+extern int opt_kern_create_channel;
extern int opt_list_apps;
extern int opt_no_sessiond;
extern int opt_list_session;
int opt_stop_trace = 0;
int opt_enable_event;
int opt_disable_event;
-int opt_create_channel;
+int opt_kern_create_channel;
pid_t opt_trace_pid = 0;
enum {
{"group", 0, POPT_ARG_STRING, &opt_tracing_group, 0, 0, 0},
{"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
{"kernel", 'k', POPT_ARG_VAL, &opt_trace_kernel, 1, 0, 0},
+ {"kern-create-channel",0, POPT_ARG_VAL, &opt_kern_create_channel, 1, 0, 0},
{"list-apps", 'L', POPT_ARG_VAL, &opt_list_apps, 1, 0, 0},
{"list-sessions", 'l', POPT_ARG_VAL, &opt_list_session, 1, 0, 0},
{"list-traces", 't', POPT_ARG_VAL, &opt_list_traces, 1, 0, 0},
fprintf(ofp, " --stop [NAME] Stop tracing. Use NAME to identify user-space trace\n");
fprintf(ofp, "\n");
fprintf(ofp, "Kernel tracing options:\n");
- fprintf(ofp, " --create-channel Create kernel channel\n");
+ fprintf(ofp, " --kern-create-channel Create a kernel channel\n");
fprintf(ofp, "\n");
fprintf(ofp, "User-space tracing options:\n");
fprintf(ofp, "\n");