From: Mathieu Desnoyers Date: Fri, 26 Aug 2011 17:52:32 +0000 (-0400) Subject: Merge branch 'master' of ssh://git.lttng.org/home/git/lttng-tools X-Git-Tag: v2.0-pre13~19^2 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=f8f0c3d1337c4eda5fb76a323ffe6c21c926a21e;hp=007953922e4d3f9f96b896cddb1c4dceddccc26e Merge branch 'master' of ssh://git.lttng.org/home/git/lttng-tools --- diff --git a/AUTHORS b/AUTHORS index bc526ef38..29de56f75 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,13 +4,13 @@ Authors: ----------- Julien Desfossez - -) Kernel Consumer and Control + -) Kernel Consumer and Control. -Mathieu Desnoyers - -) Helped designed the lttng-tools infrastructure and doing a lot of code - reviews. Code has been taken from the kernel consumer of ltt-control. +Mathieu Desnoyers + -) Helped designed the lttng-tools infrastructure and doing a lot of code + reviews. Some code has been taken from the kernel consumer of ltt-control. David Goulet - -) Session Deamon, Lib LTTng Control, Communication Library and lttng - command line tool + -) Session Deamon, Lib LTTng Control, Communication library and lttng + command line tool. diff --git a/ChangeLog b/ChangeLog index 7af930286..0468b7bc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-08-25 lttng-tools 2.0-pre12 + * Multiple fixes + * Fix kconsumerd handling custom channel output + * Add lttng_register_consumer to register a custom consumer + * Add multiples tests of the session daemon + * Default kernel channel size/number changed + * Support for UST application registration + * Import LTTng UST 2.0 ABI + * Send data to kconsumerd before tracing start + * Export API of lib kernel consumer (liblttngkconsumerd) + 2011-08-12 lttng-tools 2.0-pre11 * New lttng API using the lttng_handle * Multiple fixes of kernel consumer diff --git a/configure.ac b/configure.ac index 066c4e20e..f30b8329d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([lttng-tools], [2.0-pre11], [david.goulet@polymtl.ca], ,[http://lttng.org]) +AC_INIT([lttng-tools], [2.0-pre12], [david.goulet@polymtl.ca], ,[http://lttng.org]) AC_CONFIG_AUX_DIR([config]) AC_CANONICAL_TARGET AC_CANONICAL_HOST @@ -12,6 +12,9 @@ AC_CHECK_HEADERS([ \ getopt.h sys/ipc.h sys/shm.h popt.h grp.h \ ]) +# URCU library version needed or newer +liburcu_version="0.6.0" + # Check for pthread AC_CHECK_LIB([pthread], [pthread_create], [], [AC_MSG_ERROR([Cannot find libpthread. Use [LDFLAGS]=-Ldir to specify its location.])] @@ -22,9 +25,17 @@ AC_CHECK_LIB([popt], [poptGetContext], [], [AC_MSG_ERROR([Cannot find libpopt. Use [LDFLAGS]=-Ldir to specify its location.])] ) -# Check liburcu +# Check liburcu list.h, wfqueue.h, futex.h AC_CHECK_DECL([cds_list_add], [], - [AC_MSG_ERROR([liburcu 0.5.4 or newer is needed])], [[#include ]] + [AC_MSG_ERROR([liburcu $liburcu_version or newer is needed])], [[#include ]] +) + +AC_CHECK_DECL([cds_wfq_init], [], + [AC_MSG_ERROR([liburcu $liburcu_version or newer is needed])], [[#include ]] +) + +AC_CHECK_DECL([futex_async], [], + [AC_MSG_ERROR([liburcu $liburcu_version or newer is needed])], [[#include ]] ) AC_PROG_CC diff --git a/include/Makefile.am b/include/Makefile.am index 44d6672f0..171eefc9d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,4 +1,4 @@ lttnginclude_HEADERS = lttng/lttng.h lttng/lttng-kconsumerd.h noinst_HEADERS = lttngerr.h lttng-kernel.h ltt-kconsumerd.h lttng-share.h \ - lttng-sessiond-comm.h + lttng-sessiond-comm.h lttng-ust.h lttng-kernel-ctl.h diff --git a/include/lttng-kernel-ctl.h b/include/lttng-kernel-ctl.h new file mode 100644 index 000000000..b51273fac --- /dev/null +++ b/include/lttng-kernel-ctl.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2011 - Julien Desfossez + * Mathieu Desnoyers + * + * 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 _LTT_LIBKERNELCTL_H +#define _LTT_LIBKERNELCTL_H + +#include +#include + +int kernctl_create_session(int fd); +int kernctl_open_metadata(int fd, struct lttng_channel_attr *chops); +int kernctl_create_channel(int fd, struct lttng_channel_attr *chops); +int kernctl_create_stream(int fd); +int kernctl_create_event(int fd, struct lttng_kernel_event *ev); +int kernctl_add_context(int fd, struct lttng_kernel_context *ctx); + +int kernctl_enable(int fd); +int kernctl_disable(int fd); +int kernctl_start_session(int fd); +int kernctl_stop_session(int fd); + +int kernctl_tracepoint_list(int fd); +int kernctl_tracer_version(int fd, struct lttng_kernel_tracer_version *v); +int kernctl_wait_quiescent(int fd); +int kernctl_calibrate(int fd, struct lttng_kernel_calibrate *calibrate); + + +/* Buffer operations */ + +/* For mmap mode, readable without "get" operation */ +int kernctl_get_mmap_len(int fd, unsigned long *len); +int kernctl_get_max_subbuf_size(int fd, unsigned long *len); + +/* + * For mmap mode, operate on the current packet (between get/put or + * get_next/put_next). + */ +int kernctl_get_mmap_read_offset(int fd, unsigned long *len); +int kernctl_get_subbuf_size(int fd, unsigned long *len); +int kernctl_get_padded_subbuf_size(int fd, unsigned long *len); + +int kernctl_get_next_subbuf(int fd); +int kernctl_put_next_subbuf(int fd); + +/* snapshot */ +int kernctl_snapshot(int fd); +int kernctl_snapshot_get_consumed(int fd, unsigned long *pos); +int kernctl_snapshot_get_produced(int fd, unsigned long *pos); +int kernctl_get_subbuf(int fd, unsigned long *pos); +int kernctl_put_subbuf(int fd); + +int kernctl_buffer_flush(int fd); + +#endif /* _LTT_LIBKERNELCTL_H */ diff --git a/include/lttng-sessiond-comm.h b/include/lttng-sessiond-comm.h index 019f92ec5..4deec5fc8 100644 --- a/include/lttng-sessiond-comm.h +++ b/include/lttng-sessiond-comm.h @@ -28,6 +28,7 @@ #include #include +#include #define LTTNG_RUNDIR "/var/run/lttng" @@ -40,8 +41,8 @@ /* Queue size of listen(2) */ #define MAX_LISTEN 10 -/* Get the error code index from 0 since - * LTTCOMM_OK start at 1000 +/* + * Get the error code index from 0 since LTTCOMM_OK start at 1000 */ #define LTTCOMM_ERR_INDEX(code) (code - LTTCOMM_OK) @@ -202,6 +203,33 @@ struct lttcomm_kconsumerd_msg { enum lttng_event_output output; /* use splice or mmap to consume this fd */ }; +/* + * Data structure for the commands sent from sessiond to UST. + */ +struct lttcomm_ust_msg { + uint32_t handle; + uint32_t cmd; + union { + struct lttng_ust_tracer_version version; + struct lttng_ust_channel channel; + struct lttng_ust_event event; + struct lttng_ust_context context; + } u; +}; + +/* + * Data structure for the response from UST to the session daemon. + * cmd_type is sent back in the reply for validation. + */ +struct lttcomm_ust_reply { + uint32_t handle; + uint32_t cmd; + uint32_t ret_code; /* enum lttcomm_return_code */ + uint32_t ret_val; /* return value */ + union { + } u; +}; + extern int lttcomm_create_unix_sock(const char *pathname); extern int lttcomm_connect_unix_sock(const char *pathname); extern int lttcomm_accept_unix_sock(int sock); diff --git a/include/lttng-share.h b/include/lttng-share.h index b3495e196..38598bcea 100644 --- a/include/lttng-share.h +++ b/include/lttng-share.h @@ -19,43 +19,27 @@ #ifndef _LTTNG_SHARE_H #define _LTTNG_SHARE_H -#include -#include - -typedef uint32_t u32; -typedef uint64_t u64; - -typedef __s64 s64; - /* Default channel attributes */ -#define DEFAULT_CHANNEL_NAME "channel0" -#define DEFAULT_CHANNEL_OVERWRITE 0 /* usec */ +#define DEFAULT_CHANNEL_NAME "channel0" +#define DEFAULT_CHANNEL_OVERWRITE 0 /* usec */ /* DEFAULT_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ -#define DEFAULT_CHANNEL_SUBBUF_SIZE 4096 /* bytes */ +#define DEFAULT_CHANNEL_SUBBUF_SIZE 4096 /* bytes */ /* DEFAULT_CHANNEL_SUBBUF_NUM must always be a power of 2 */ -#define DEFAULT_CHANNEL_SUBBUF_NUM 8 -#define DEFAULT_CHANNEL_SWITCH_TIMER 0 /* usec */ +#define DEFAULT_CHANNEL_SUBBUF_NUM 8 +#define DEFAULT_CHANNEL_SWITCH_TIMER 0 /* usec */ #define DEFAULT_CHANNEL_READ_TIMER 200 /* usec */ -#define DEFAULT_CHANNEL_OUTPUT LTTNG_EVENT_MMAP +#define DEFAULT_CHANNEL_OUTPUT LTTNG_EVENT_MMAP -#define DEFAULT_METADATA_SUBBUF_SIZE 4096 -#define DEFAULT_METADATA_SUBBUF_NUM 2 +#define DEFAULT_METADATA_SUBBUF_SIZE 4096 +#define DEFAULT_METADATA_SUBBUF_NUM 2 /* Kernel has different defaults */ /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ -#define DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE 262144 /* bytes */ +#define DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE 262144 /* bytes */ /* DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM must always be a power of 2 */ -#define DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM 4 +#define DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM 4 /* See lttng-kernel.h enum lttng_kernel_output for channel output */ -#define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE - -/* - * lttng user-space instrumentation type - */ -enum lttng_ust_instrumentation { - LTTNG_UST_TRACEPOINT, - LTTNG_UST_MARKER, -}; +#define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE #endif /* _LTTNG_SHARE_H */ diff --git a/include/lttng-ust.h b/include/lttng-ust.h new file mode 100644 index 000000000..abfd613b9 --- /dev/null +++ b/include/lttng-ust.h @@ -0,0 +1,108 @@ +#ifndef _LTTNG_UST_H +#define _LTTNG_UST_H + +/* + * Taken from the lttng-ust-abi.h in the UST 2.0 git tree + * + * Copyright 2010-2011 - Mathieu Desnoyers + * Copyright 2011 - David Goulet + * + * LTTng-UST ABI header + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include + +#define LTTNG_UST_SYM_NAME_LEN 128 + +#define LTTNG_UST_COMM_VERSION_MAJOR 0 +#define LTTNG_UST_COMM_VERSION_MINOR 1 + +/* See lttng-ust.h enum lttng_ust_output */ +#define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_UST_MMAP + +enum lttng_ust_instrumentation { + LTTNG_UST_TRACEPOINT = 0, + LTTNG_UST_PROBE = 1, + LTTNG_UST_FUNCTION = 2, +}; + +enum lttng_ust_output { + LTTNG_UST_MMAP = 0, +}; + +struct lttng_ust_tracer_version { + uint32_t version; + uint32_t patchlevel; + uint32_t sublevel; +}; + +struct lttng_ust_channel { + int overwrite; /* 1: overwrite, 0: discard */ + uint64_t subbuf_size; /* in bytes */ + uint64_t num_subbuf; + unsigned int switch_timer_interval; /* usecs */ + unsigned int read_timer_interval; /* usecs */ + enum lttng_ust_output output; /* output mode */ +}; + +struct lttng_ust_event { + char name[LTTNG_UST_SYM_NAME_LEN]; /* event name */ + enum lttng_ust_instrumentation instrumentation; + /* Per instrumentation type configuration */ + union { + } u; +}; + +enum lttng_ust_context_type { + LTTNG_UST_CONTEXT_VTID = 0, +}; + +struct lttng_ust_context { + enum lttng_ust_context_type ctx; + union { + } u; +}; + +#define _UST_CMD(minor) (minor) +#define _UST_CMDR(minor, type) (minor) +#define _UST_CMDW(minor, type) (minor) + +/* Handled by object descriptor */ +#define LTTNG_UST_RELEASE _UST_CMD(0x1) + +/* Handled by object cmd */ + +/* LTTng-UST commands */ +#define LTTNG_UST_SESSION _UST_CMD(0x40) +#define LTTNG_UST_TRACER_VERSION \ + _UST_CMDR(0x41, struct lttng_ust_tracer_version) +#define LTTNG_UST_TRACEPOINT_LIST _UST_CMD(0x42) +#define LTTNG_UST_WAIT_QUIESCENT _UST_CMD(0x43) +#define LTTNG_UST_REGISTER_DONE _UST_CMD(0x44) + +/* Session FD ioctl */ +#define LTTNG_UST_METADATA \ + _UST_CMDW(0x50, struct lttng_ust_channel) +#define LTTNG_UST_CHANNEL \ + _UST_CMDW(0x51, struct lttng_ust_channel) +#define LTTNG_UST_SESSION_START _UST_CMD(0x52) +#define LTTNG_UST_SESSION_STOP _UST_CMD(0x53) + +/* Channel FD ioctl */ +#define LTTNG_UST_STREAM _UST_CMD(0x60) +#define LTTNG_UST_EVENT \ + _UST_CMDW(0x61, struct lttng_ust_event) + +/* Event and Channel FD ioctl */ +#define LTTNG_UST_CONTEXT \ + _UST_CMDW(0x70, struct lttng_ust_context) + +/* Event, Channel and Session ioctl */ +#define LTTNG_UST_ENABLE _UST_CMD(0x80) +#define LTTNG_UST_DISABLE _UST_CMD(0x81) + +#define LTTNG_UST_ROOT_HANDLE 0 + +#endif /* _LTTNG_UST_H */ diff --git a/include/lttng/lttng-kconsumerd.h b/include/lttng/lttng-kconsumerd.h index e09bdc3bd..2aa337fa6 100644 --- a/include/lttng/lttng-kconsumerd.h +++ b/include/lttng/lttng-kconsumerd.h @@ -21,6 +21,7 @@ #include #include +#include /* * When the receiving thread dies, we need to have a way to make the polling diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 0811d594d..3e5b05562 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -23,10 +23,9 @@ #ifndef _LTTNG_H #define _LTTNG_H -#include -#include -#include #include +#include +#include /* Default unix group name for tracing. */ #define LTTNG_DEFAULT_TRACING_GROUP "tracing" diff --git a/libkernelctl/Makefile.am b/libkernelctl/Makefile.am index 97a2c9711..cabdeedd9 100644 --- a/libkernelctl/Makefile.am +++ b/libkernelctl/Makefile.am @@ -2,4 +2,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LTLIBRARIES = libkernelctl.la -libkernelctl_la_SOURCES = kernelctl.c kernelctl.h kernel-ioctl.h +libkernelctl_la_SOURCES = kernelctl.c kernel-ioctl.h diff --git a/libkernelctl/kernelctl.c b/libkernelctl/kernelctl.c index afb0e012b..7936b2742 100644 --- a/libkernelctl/kernelctl.c +++ b/libkernelctl/kernelctl.c @@ -19,8 +19,9 @@ #include +#include + #include "kernel-ioctl.h" -#include "kernelctl.h" int kernctl_create_session(int fd) { diff --git a/libkernelctl/kernelctl.h b/libkernelctl/kernelctl.h deleted file mode 100644 index 783f1258d..000000000 --- a/libkernelctl/kernelctl.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011 - Julien Desfossez - * Mathieu Desnoyers - * - * 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 _LTT_LIBKERNELCTL_H -#define _LTT_LIBKERNELCTL_H - -#include - -#include "lttng-kernel.h" - -int kernctl_create_session(int fd); -int kernctl_open_metadata(int fd, struct lttng_channel_attr *chops); -int kernctl_create_channel(int fd, struct lttng_channel_attr *chops); -int kernctl_create_stream(int fd); -int kernctl_create_event(int fd, struct lttng_kernel_event *ev); -int kernctl_add_context(int fd, struct lttng_kernel_context *ctx); - -int kernctl_enable(int fd); -int kernctl_disable(int fd); -int kernctl_start_session(int fd); -int kernctl_stop_session(int fd); - -int kernctl_tracepoint_list(int fd); -int kernctl_tracer_version(int fd, struct lttng_kernel_tracer_version *v); -int kernctl_wait_quiescent(int fd); -int kernctl_calibrate(int fd, struct lttng_kernel_calibrate *calibrate); - - -/* Buffer operations */ - -/* For mmap mode, readable without "get" operation */ -int kernctl_get_mmap_len(int fd, unsigned long *len); -int kernctl_get_max_subbuf_size(int fd, unsigned long *len); - -/* - * For mmap mode, operate on the current packet (between get/put or - * get_next/put_next). - */ -int kernctl_get_mmap_read_offset(int fd, unsigned long *len); -int kernctl_get_subbuf_size(int fd, unsigned long *len); -int kernctl_get_padded_subbuf_size(int fd, unsigned long *len); - -int kernctl_get_next_subbuf(int fd); -int kernctl_put_next_subbuf(int fd); - -/* snapshot */ -int kernctl_snapshot(int fd); -int kernctl_snapshot_get_consumed(int fd, unsigned long *pos); -int kernctl_snapshot_get_produced(int fd, unsigned long *pos); -int kernctl_get_subbuf(int fd, unsigned long *pos); -int kernctl_put_subbuf(int fd); - -int kernctl_buffer_flush(int fd); - -#endif /* _LTT_LIBKERNELCTL_H */ diff --git a/liblttng-sessiond-comm/lttng-sessiond-comm.c b/liblttng-sessiond-comm/lttng-sessiond-comm.c index 9a540f0a6..b293ac0b0 100644 --- a/liblttng-sessiond-comm/lttng-sessiond-comm.c +++ b/liblttng-sessiond-comm/lttng-sessiond-comm.c @@ -17,6 +17,7 @@ */ #define _GNU_SOURCE +#include #include #include #include @@ -26,7 +27,6 @@ #include #include #include -#include #include diff --git a/liblttngctl/lttngctl.c b/liblttngctl/lttngctl.c index c2b1242d8..4b803dc5b 100644 --- a/liblttngctl/lttngctl.c +++ b/liblttngctl/lttngctl.c @@ -21,18 +21,17 @@ */ #define _GNU_SOURCE -#include #include +#include #include #include #include #include -#include - #include -#include "lttngerr.h" -#include "lttng-share.h" +#include +#include +#include /* Socket to session daemon for communication */ static int sessiond_socket; @@ -348,6 +347,16 @@ static int ask_sessiond(struct lttcomm_session_msg *lsm, void **buf) goto end; } + /* + * Extra protection not to dereference a NULL pointer. If buf is NULL at + * this point, an error is returned and data is freed. + */ + if (buf == NULL) { + ret = -1; + free(data); + goto end; + } + *buf = data; ret = size; diff --git a/liblttngkconsumerd/Makefile.am b/liblttngkconsumerd/Makefile.am index edd005930..e8c5741b3 100644 --- a/liblttngkconsumerd/Makefile.am +++ b/liblttngkconsumerd/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libkernelctl +AM_CPPFLAGS = -I$(top_srcdir)/include lib_LTLIBRARIES = liblttngkconsumerd.la diff --git a/liblttngkconsumerd/lttngkconsumerd.c b/liblttngkconsumerd/lttngkconsumerd.c index 5c9f613b1..2e53f9a2d 100644 --- a/liblttngkconsumerd/lttngkconsumerd.c +++ b/liblttngkconsumerd/lttngkconsumerd.c @@ -18,6 +18,7 @@ */ #define _GNU_SOURCE +#include #include #include #include @@ -27,14 +28,11 @@ #include #include #include -#include -#include +#include +#include #include - -#include "kernelctl.h" -#include "lttngerr.h" -#include "lttng-sessiond-comm.h" +#include static struct lttng_kconsumerd_global_data { /* @@ -777,6 +775,7 @@ struct lttng_kconsumerd_local_data *lttng_kconsumerd_create( goto error; } + ctx->kconsumerd_error_socket = -1; /* assign the callbacks */ ctx->on_buffer_ready = buffer_ready; ctx->on_recv_fd = recv_fd; @@ -871,6 +870,7 @@ void *lttng_kconsumerd_thread_receive_fds(void *data) DBG("Sending ready command to ltt-sessiond"); ret = lttng_kconsumerd_send_error(ctx, KCONSUMERD_COMMAND_SOCK_READY); + /* return < 0 on error, but == 0 is not fatal */ if (ret < 0) { ERR("Error sending ready command to ltt-sessiond"); goto end; @@ -999,6 +999,7 @@ void lttng_kconsumerd_should_exit(struct lttng_kconsumerd_local_data *ctx) /* * Send return code to the session daemon. + * If the socket is not defined, we return 0, it is not a fatal error */ int lttng_kconsumerd_send_error( struct lttng_kconsumerd_local_data *ctx, int cmd) diff --git a/ltt-kconsumerd/Makefile.am b/ltt-kconsumerd/Makefile.am index 9ba16549b..068c55544 100644 --- a/ltt-kconsumerd/Makefile.am +++ b/ltt-kconsumerd/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libkernelctl +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = ltt-kconsumerd diff --git a/ltt-kconsumerd/ltt-kconsumerd.c b/ltt-kconsumerd/ltt-kconsumerd.c index 7eab42e52..d562c1729 100644 --- a/ltt-kconsumerd/ltt-kconsumerd.c +++ b/ltt-kconsumerd/ltt-kconsumerd.c @@ -38,12 +38,11 @@ #include #include +#include +#include +#include #include - -#include "lttngerr.h" -#include "kernelctl.h" -#include "ltt-kconsumerd.h" -#include "lttng-sessiond-comm.h" +#include /* the two threads (receive fd and poll) */ static pthread_t threads[2]; diff --git a/ltt-sessiond/Makefile.am b/ltt-sessiond/Makefile.am index daa4265c1..6cffbd738 100644 --- a/ltt-sessiond/Makefile.am +++ b/ltt-sessiond/Makefile.am @@ -1,15 +1,21 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_srcdir)/libkernelctl -I$(top_srcdir)/libustctl \ - -DINSTALL_BIN_PATH=\"$(bindir)\" + -DINSTALL_BIN_PATH=\""$(bindir)"\" AM_CFLAGS = -fno-strict-aliasing bin_PROGRAMS = ltt-sessiond -ltt_sessiond_SOURCES = utils.c trace.c session.c traceable-app.c ust-ctl.c \ - kernel-ctl.c context.c main.c \ - utils.h trace.h session.h traceable-app.h ust-ctl.h \ - context.h kernel-ctl.h ltt-sessiond.h +ltt_sessiond_SOURCES = utils.c utils.h \ + trace-kernel.c trace-kernel.h \ + trace-ust.c trace-ust.h \ + session.c session.h \ + traceable-app.c traceable-app.h \ + ust-ctl.c ust-ctl.h \ + kernel-ctl.c kernel-ctl.h \ + context.c context.h \ + futex.c futex.h \ + ust-comm.c ust-comm.h \ + ltt-sessiond.h main.c # link on liblttngctl for check if sessiond is already alive. ltt_sessiond_LDADD = \ diff --git a/ltt-sessiond/context.c b/ltt-sessiond/context.c index dc7712270..aebee0607 100644 --- a/ltt-sessiond/context.c +++ b/ltt-sessiond/context.c @@ -1,19 +1,18 @@ /* * Copyright (C) 2011 - David Goulet * - * 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 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. + * 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. + * 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 @@ -21,10 +20,13 @@ #include #include #include + +#include #include #include "lttngerr.h" #include "context.h" +#include "kernel-ctl.h" /* * Add kernel context to an event of a specific channel. @@ -37,7 +39,7 @@ static int add_kctx_to_event(struct lttng_kernel_context *kctx, DBG("Add kernel context to event %s", event_name); - kevent = get_kernel_event_by_name(event_name, kchan); + kevent = trace_kernel_get_event_by_name(event_name, kchan); if (kevent != NULL) { ret = kernel_add_event_context(kevent, kctx); if (ret < 0) { @@ -163,7 +165,7 @@ int add_kernel_context(struct ltt_kernel_session *ksession, } } else { /* Get kernel channel */ - kchan = get_kernel_channel_by_name(channel_name, ksession); + kchan = trace_kernel_get_channel_by_name(channel_name, ksession); if (kchan == NULL) { ret = LTTCOMM_KERN_CHAN_NOT_FOUND; goto error; diff --git a/ltt-sessiond/context.h b/ltt-sessiond/context.h index 28586521b..a3d82e0b7 100644 --- a/ltt-sessiond/context.h +++ b/ltt-sessiond/context.h @@ -1,33 +1,26 @@ /* * Copyright (C) 2011 - David Goulet * - * 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 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. + * 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. + * 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_CONTEXT_H #define _LTT_CONTEXT_H -#include -#include +#include -#include -#include - -#include "lttng-kernel.h" -#include "kernel-ctl.h" -#include "trace.h" +#include "trace-kernel.h" int add_kernel_context(struct ltt_kernel_session *ksession, struct lttng_kernel_context *kctx, char *event_name, diff --git a/ltt-sessiond/futex.c b/ltt-sessiond/futex.c new file mode 100644 index 000000000..0c333fce6 --- /dev/null +++ b/ltt-sessiond/futex.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 - David Goulet + * Mathieu Desnoyers + * + * 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 +#include +#include +#include + +#include + +#include "futex.h" + +/* + * This futex wait/wake scheme only works for N wakers / 1 waiters. Hence the + * "nto1" added to all function signature. + * + * Please see wait_gp()/update_counter_and_wait() calls in urcu.c in the urcu + * git tree for a detail example of this scheme being used. futex_async() is + * the urcu wrapper over the futex() sycall. + * + * There is also a formal verification available in the git tree. + * + * branch: formal-model + * commit id: 2a8044f3493046fcc8c67016902dc7beec6f026a + * + * Ref: git://git.lttng.org/userspace-rcu.git + */ + +/* + * Prepare futex. + */ +void futex_nto1_prepare(int32_t *futex) +{ + uatomic_set(futex, -1); + cmm_smp_mb(); + + DBG("Futex n to 1 prepare done"); +} + +/* + * Wait futex. + */ +void futex_nto1_wait(int32_t *futex) +{ + cmm_smp_mb(); + + if (uatomic_read(futex) == -1) { + futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0); + } + + DBG("Futex n to 1 wait done"); +} + +/* + * Wake 1 futex. + */ +void futex_nto1_wake(int32_t *futex) +{ + if (unlikely(uatomic_read(futex) == -1)) { + uatomic_set(futex, 0); + futex_async(futex, FUTEX_WAKE, 1, NULL, NULL, 0); + } + + DBG("Futex n to 1 wake done"); +} diff --git a/ltt-sessiond/futex.h b/ltt-sessiond/futex.h new file mode 100644 index 000000000..ebda1e06c --- /dev/null +++ b/ltt-sessiond/futex.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 - David Goulet + * Mathieu Desnoyers + * + * 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 _LTT_FUTEX_H +#define _LTT_FUTEX_H + +void futex_nto1_prepare(int32_t *futex); +void futex_nto1_wait(int32_t *futex); +void futex_nto1_wake(int32_t *futex); + +#endif /* _LTT_FUTEX_H */ diff --git a/ltt-sessiond/kernel-ctl.c b/ltt-sessiond/kernel-ctl.c index 3879c2bbb..3014620ba 100644 --- a/ltt-sessiond/kernel-ctl.c +++ b/ltt-sessiond/kernel-ctl.c @@ -24,14 +24,13 @@ #include #include -#include "lttngerr.h" -#include "kernelctl.h" +#include +#include + #include "kernel-ctl.h" /* - * kernel_add_channel_context - * - * Add context on a kernel channel. + * Add context on a kernel channel. */ int kernel_add_channel_context(struct ltt_kernel_channel *chan, struct lttng_kernel_context *ctx) @@ -65,9 +64,7 @@ error: } /* - * kernel_add_event_context - * - * Add context on a kernel event. + * Add context on a kernel event. */ int kernel_add_event_context(struct ltt_kernel_event *event, struct lttng_kernel_context *ctx) @@ -96,10 +93,8 @@ error: } /* - * kernel_create_session - * - * Create a new kernel session, register it to the kernel tracer and add it to - * the session daemon session. + * Create a new kernel session, register it to the kernel tracer and add it to + * the session daemon session. */ int kernel_create_session(struct ltt_session *session, int tracer_fd) { @@ -107,7 +102,7 @@ int kernel_create_session(struct ltt_session *session, int tracer_fd) struct ltt_kernel_session *lks; /* Allocate data structure */ - lks = trace_create_kernel_session(); + lks = trace_kernel_create_session(session->path); if (lks == NULL) { ret = -1; goto error; @@ -139,18 +134,17 @@ error: } /* - * kernel_create_channel - * - * Create a kernel channel, register it to the kernel tracer and add it to the - * kernel session. + * Create a kernel channel, register it to the kernel tracer and add it to the + * kernel session. */ -int kernel_create_channel(struct ltt_kernel_session *session, struct lttng_channel *chan, char *path) +int kernel_create_channel(struct ltt_kernel_session *session, + struct lttng_channel *chan, char *path) { int ret; struct ltt_kernel_channel *lkc; /* Allocate kernel channel */ - lkc = trace_create_kernel_channel(chan, path); + lkc = trace_kernel_create_channel(chan, path); if (lkc == NULL) { goto error; } @@ -184,17 +178,16 @@ error: } /* - * kernel_create_event - * - * Create a kernel event, enable it to the kernel tracer and add it to the - * channel event list of the kernel session. + * Create a kernel event, enable it to the kernel tracer and add it to the + * channel event list of the kernel session. */ -int kernel_create_event(struct lttng_event *ev, struct ltt_kernel_channel *channel) +int kernel_create_event(struct lttng_event *ev, + struct ltt_kernel_channel *channel) { int ret; struct ltt_kernel_event *event; - event = trace_create_kernel_event(ev); + event = trace_kernel_create_event(ev); if (event == NULL) { goto error; } @@ -227,9 +220,7 @@ error: } /* - * kernel_disable_channel - * - * Disable a kernel channel. + * Disable a kernel channel. */ int kernel_disable_channel(struct ltt_kernel_channel *chan) { @@ -252,9 +243,7 @@ error: } /* - * kernel_enable_channel - * - * Enable a kernel channel. + * Enable a kernel channel. */ int kernel_enable_channel(struct ltt_kernel_channel *chan) { @@ -277,9 +266,7 @@ error: } /* - * kernel_enable_event - * - * Enable a kernel event. + * Enable a kernel event. */ int kernel_enable_event(struct ltt_kernel_event *event) { @@ -304,9 +291,7 @@ error: } /* - * kernel_disable_event - * - * Disable a kernel event. + * Disable a kernel event. */ int kernel_disable_event(struct ltt_kernel_event *event) { @@ -328,10 +313,8 @@ error: } /* - * kernel_open_metadata - * - * Create kernel metadata, open from the kernel tracer and add it to the - * kernel session. + * Create kernel metadata, open from the kernel tracer and add it to the + * kernel session. */ int kernel_open_metadata(struct ltt_kernel_session *session, char *path) { @@ -339,7 +322,7 @@ int kernel_open_metadata(struct ltt_kernel_session *session, char *path) struct ltt_kernel_metadata *lkm; /* Allocate kernel metadata */ - lkm = trace_create_kernel_metadata(path); + lkm = trace_kernel_create_metadata(path); if (lkm == NULL) { goto error; } @@ -368,9 +351,7 @@ error: } /* - * kernel_start_session - * - * Start tracing session. + * Start tracing session. */ int kernel_start_session(struct ltt_kernel_session *session) { @@ -391,9 +372,7 @@ error: } /* - * kernel_wait_quiescent - * - * Make a kernel wait to make sure in-flight probe have completed. + * Make a kernel wait to make sure in-flight probe have completed. */ void kernel_wait_quiescent(int fd) { @@ -409,7 +388,7 @@ void kernel_wait_quiescent(int fd) } /* - * kernel_calibrate + * Kernel calibrate */ int kernel_calibrate(int fd, struct lttng_kernel_calibrate *calibrate) { @@ -426,8 +405,6 @@ int kernel_calibrate(int fd, struct lttng_kernel_calibrate *calibrate) /* - * kernel_metadata_flush_buffer - * * Force flush buffer of metadata. */ int kernel_metadata_flush_buffer(int fd) @@ -443,9 +420,7 @@ int kernel_metadata_flush_buffer(int fd) } /* - * kernel_flush_buffer - * - * Force flush buffer for channel. + * Force flush buffer for channel. */ int kernel_flush_buffer(struct ltt_kernel_channel *channel) { @@ -468,9 +443,7 @@ int kernel_flush_buffer(struct ltt_kernel_channel *channel) } /* - * kernel_stop_session - * - * Stop tracing session. + * Stop tracing session. */ int kernel_stop_session(struct ltt_kernel_session *session) { @@ -490,12 +463,10 @@ error: } /* - * kernel_open_channel_stream + * Open stream of channel, register it to the kernel tracer and add it + * to the stream list of the channel. * - * Open stream of channel, register it to the kernel tracer and add it - * to the stream list of the channel. - * - * Return the number of created stream. Else, a negative value. + * Return the number of created stream. Else, a negative value. */ int kernel_open_channel_stream(struct ltt_kernel_channel *channel) { @@ -503,7 +474,7 @@ int kernel_open_channel_stream(struct ltt_kernel_channel *channel) struct ltt_kernel_stream *lks; while ((ret = kernctl_create_stream(channel->fd)) > 0) { - lks = trace_create_kernel_stream(); + lks = trace_kernel_create_stream(); if (lks == NULL) { close(ret); goto error; @@ -538,9 +509,7 @@ error: } /* - * kernel_open_metadata_stream - * - * Open the metadata stream and set it to the kernel session. + * Open the metadata stream and set it to the kernel session. */ int kernel_open_metadata_stream(struct ltt_kernel_session *session) { diff --git a/ltt-sessiond/kernel-ctl.h b/ltt-sessiond/kernel-ctl.h index df0cca2af..2fbaca91e 100644 --- a/ltt-sessiond/kernel-ctl.h +++ b/ltt-sessiond/kernel-ctl.h @@ -8,7 +8,7 @@ * * 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 + * 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 @@ -20,15 +20,16 @@ #define _LTT_KERNEL_CTL_H #include "session.h" -#include "trace.h" +#include "trace-kernel.h" /* * Default size for the event list when kernel_list_events is called. This size - * value is based on the initial LTTng 2.0 version set of tracepoints. This is - * NOT an upper bound because if the real event list size is bigger, dynamic - * reallocation is performed. + * value is based on the initial LTTng 2.0 version set of tracepoints. + * + * This is NOT an upper bound because if the real event list size is bigger, + * dynamic reallocation is performed. */ -#define KERNEL_EVENT_LIST_SIZE 2000 +#define KERNEL_EVENT_LIST_SIZE 80 int kernel_add_channel_context(struct ltt_kernel_channel *chan, struct lttng_kernel_context *ctx); diff --git a/ltt-sessiond/ltt-sessiond.h b/ltt-sessiond/ltt-sessiond.h index acdc9724b..cc6a6ba15 100644 --- a/ltt-sessiond/ltt-sessiond.h +++ b/ltt-sessiond/ltt-sessiond.h @@ -8,7 +8,7 @@ * * 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 + * 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 @@ -19,10 +19,15 @@ #ifndef _LTT_SESSIOND_H #define _LTT_SESSIOND_H -#define DEFAULT_HOME_DIR "/tmp" -#define DEFAULT_UST_SOCK_DIR DEFAULT_HOME_DIR "/ust-app-socks" -#define DEFAULT_GLOBAL_APPS_PIPE DEFAULT_UST_SOCK_DIR "/global" -#define DEFAULT_TRACE_OUTPUT DEFAULT_HOME_DIR "/lttng" +#define _LGPL_SOURCE +#include + +#include "traceable-app.h" + +#define DEFAULT_HOME_DIR "/tmp" +#define DEFAULT_UST_SOCK_DIR DEFAULT_HOME_DIR "/ust-app-socks" +#define DEFAULT_GLOBAL_APPS_PIPE DEFAULT_UST_SOCK_DIR "/global" +#define DEFAULT_TRACE_OUTPUT DEFAULT_HOME_DIR "/lttng" struct module_param { const char *name; @@ -68,4 +73,19 @@ struct command_ctx { struct lttcomm_session_msg *lsm; }; +struct ust_command { + int sock; + struct ust_register_msg reg_msg; + struct cds_wfq_node node; +}; + +/* + * Queue used to enqueue UST registration request (ust_commant) and protected + * by a futex with a scheme N wakers / 1 waiters. See futex.c/.h + */ +struct ust_cmd_queue { + int32_t futex; + struct cds_wfq_queue queue; +}; + #endif /* _LTT_SESSIOND_H */ diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 70c194b22..edbdd643a 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -29,30 +29,26 @@ #include #include #include -#include #include -#include +#include #include #include #include -#include -#include #include -#include /* URCU list library (-lurcu) */ -#include -#include +#include #include +#include +#include #include "context.h" -#include "ltt-sessiond.h" -#include "lttngerr.h" +#include "futex.h" #include "kernel-ctl.h" -#include "ust-ctl.h" -#include "session.h" +#include "ltt-sessiond.h" #include "traceable-app.h" -#include "ltt-kconsumerd.h" +#include "ust-ctl.h" #include "utils.h" +#include "ust-comm.h" /* Const values */ const char default_home_dir[] = DEFAULT_HOME_DIR; @@ -73,6 +69,7 @@ static int is_root; /* Set to 1 if the daemon is running as root */ static pid_t ppid; /* Parent PID for --sig-parent option */ static pid_t kconsumerd_pid; static struct pollfd *kernel_pollfd; +static int dispatch_thread_exit; static char apps_unix_sock_path[PATH_MAX]; /* Global application Unix socket path */ static char client_unix_sock_path[PATH_MAX]; /* Global client Unix socket path */ @@ -93,17 +90,34 @@ static int kernel_poll_pipe[2]; */ static int thread_quit_pipe[2]; +/* + * This pipe is used to inform the thread managing application communication + * that a command is queued and ready to be processed. + */ +static int apps_cmd_pipe[2]; + /* Pthread, Mutexes and Semaphores */ static pthread_t kconsumerd_thread; static pthread_t apps_thread; +static pthread_t reg_apps_thread; static pthread_t client_thread; static pthread_t kernel_thread; +static pthread_t dispatch_thread; static sem_t kconsumerd_sem; static pthread_mutex_t kconsumerd_pid_mutex; /* Mutex to control kconsumerd pid assignation */ static int modprobe_remove_kernel_modules(void); +/* + * UST registration command queue. This queue is tied with a futex and uses a N + * wakers / 1 waiter implemented and detailed in futex.c/.h + * + * The thread_manage_apps and thread_dispatch_ust_registration interact with + * this queue and the wait/wake scheme. + */ +static struct ust_cmd_queue ust_cmd_queue; + /* * Pointer initialized before thread creation. * @@ -168,18 +182,24 @@ static void teardown_kernel_session(struct ltt_session *session) lttcomm_close_unix_sock(session->kernel_session->consumer_fd); } - trace_destroy_kernel_session(session->kernel_session); + trace_kernel_destroy_session(session->kernel_session); /* Extra precaution */ session->kernel_session = NULL; } } +/* + * Stop all threads by closing the thread quit pipe. + */ static void stop_threads(void) { /* Stopping all threads */ DBG("Terminating all threads"); close(thread_quit_pipe[0]); close(thread_quit_pipe[1]); + /* Dispatch thread */ + dispatch_thread_exit = 1; + futex_nto1_wake(&ust_cmd_queue.futex); } /* @@ -224,6 +244,9 @@ static void cleanup(void) } } + DBG("Closing all UST sockets"); + clean_traceable_apps_list(); + pthread_mutex_destroy(&kconsumerd_pid_mutex); DBG("Closing kernel fd"); @@ -408,7 +431,6 @@ static int ust_connect_app(pid_t pid) return sock; } -#endif /* DISABLED */ /* * Notify apps by writing 42 to a named pipe using name. Every applications @@ -439,6 +461,7 @@ static int notify_apps(const char *name) error: return ret; } +#endif /* DISABLED */ /* * Setup the outgoing data buffer for the response (llm) by allocating the @@ -801,24 +824,232 @@ error: } /* - * This thread manage the application socket communication + * Reallocate the apps command pollfd structure of nb_fd size. + * + * The first two fds must be there at all time. + */ +static int update_apps_cmd_pollfd(unsigned int nb_fd, struct pollfd **pollfd) +{ + /* Can't accept pollfd less than 2 */ + if (nb_fd < 2) { + goto end; + } + + *pollfd = realloc(*pollfd, nb_fd * sizeof(struct pollfd)); + if (*pollfd == NULL) { + perror("realloc manage apps pollfd"); + goto error; + } + + /* First fd is always the quit pipe */ + (*pollfd)[0].fd = thread_quit_pipe[0]; + /* Apps command pipe */ + (*pollfd)[1].fd = apps_cmd_pipe[0]; + (*pollfd)[1].events = POLLIN; + + DBG("Apps cmd pollfd realloc of size %d", nb_fd); + +end: + return 0; + +error: + return -1; +} + +/* + * Send registration done packet to the application. + */ +static int send_ust_register_done(int sock) +{ + struct lttcomm_ust_msg lum; + + DBG("Sending register done command to %d", sock); + + lum.cmd = LTTNG_UST_REGISTER_DONE; + lum.handle = LTTNG_UST_ROOT_HANDLE; + + return ustcomm_send_command(sock, &lum); +} + +/* + * This thread manage application communication. */ static void *thread_manage_apps(void *data) +{ + int i, ret, count; + unsigned int nb_fd = 2; + int update_poll_flag = 1; + struct pollfd *pollfd = NULL; + struct ust_command ust_cmd; + + DBG("[thread] Manage application started"); + + ust_cmd.sock = -1; + + while (1) { + /* See if we have a valid socket to add to pollfd */ + if (ust_cmd.sock != -1) { + nb_fd++; + update_poll_flag = 1; + } + + /* The pollfd struct must be updated */ + if (update_poll_flag) { + ret = update_apps_cmd_pollfd(nb_fd, &pollfd); + if (ret < 0) { + /* malloc failed so we quit */ + goto error; + } + if (ust_cmd.sock != -1) { + /* Update pollfd with the new UST socket */ + DBG("Adding sock %d to apps cmd pollfd", ust_cmd.sock); + pollfd[nb_fd - 1].fd = ust_cmd.sock; + pollfd[nb_fd - 1].events = POLLHUP | POLLNVAL; + ust_cmd.sock = -1; + } + } + + DBG("Apps thread polling on %d fds", nb_fd); + + /* Inifinite blocking call, waiting for transmission */ + ret = poll(pollfd, nb_fd, -1); + if (ret < 0) { + perror("poll apps thread"); + goto error; + } + + /* Thread quit pipe has been closed. Killing thread. */ + if (pollfd[0].revents == POLLNVAL) { + goto error; + } else if (pollfd[1].revents == POLLERR) { + ERR("Apps command pipe poll error"); + goto error; + } else if (pollfd[1].revents == POLLIN) { + /* Empty pipe */ + ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd)); + if (ret < 0 || ret < sizeof(ust_cmd)) { + perror("read apps cmd pipe"); + goto error; + } + + /* Register applicaton to the session daemon */ + ret = register_traceable_app(&ust_cmd.reg_msg, ust_cmd.sock); + if (ret < 0) { + /* Only critical ENOMEM error can be returned here */ + goto error; + } + + ret = send_ust_register_done(ust_cmd.sock); + if (ret < 0) { + /* + * If the registration is not possible, we simply unregister + * the apps and continue + */ + unregister_traceable_app(ust_cmd.sock); + } + } + + count = nb_fd; + for (i = 2; i < count; i++) { + /* Apps socket is closed/hungup */ + switch (pollfd[i].revents) { + case POLLNVAL: + case POLLHUP: + /* Pipe closed */ + unregister_traceable_app(pollfd[i].fd); + nb_fd--; + } + } + + if (nb_fd != count) { + update_poll_flag = 1; + } + } + +error: + DBG("Application communication apps dying"); + close(apps_cmd_pipe[0]); + close(apps_cmd_pipe[1]); + + free(pollfd); + + return NULL; +} + +/* + * Dispatch request from the registration threads to the application + * communication thread. + */ +static void *thread_dispatch_ust_registration(void *data) +{ + int ret; + struct cds_wfq_node *node; + struct ust_command *ust_cmd = NULL; + + DBG("[thread] Dispatch UST command started"); + + while (!dispatch_thread_exit) { + /* Atomically prepare the queue futex */ + futex_nto1_prepare(&ust_cmd_queue.futex); + + do { + /* Dequeue command for registration */ + node = cds_wfq_dequeue_blocking(&ust_cmd_queue.queue); + if (node == NULL) { + DBG("Waked up but nothing in the UST command queue"); + /* Continue thread execution */ + break; + } + + ust_cmd = caa_container_of(node, struct ust_command, node); + + DBG("Dispatching UST registration pid:%d sock:%d", + ust_cmd->reg_msg.pid, ust_cmd->sock); + /* + * Inform apps thread of the new application registration. This + * call is blocking so we can be assured that the data will be read + * at some point in time or wait to the end of the world :) + */ + ret = write(apps_cmd_pipe[1], ust_cmd, + sizeof(struct ust_command)); + if (ret < 0) { + perror("write apps cmd pipe"); + if (errno == EBADF) { + /* + * We can't inform the application thread to process + * registration. We will exit or else application + * registration will not occur and tracing will never + * start. + */ + goto error; + } + } + free(ust_cmd); + } while (node != NULL); + + /* Futex wait on queue. Blocking call on futex() */ + futex_nto1_wait(&ust_cmd_queue.futex); + } + +error: + DBG("Dispatch thread dying"); + return NULL; +} + +/* + * This thread manage application registration. + */ +static void *thread_registration_apps(void *data) { int sock = 0, ret; struct pollfd pollfd[2]; + /* + * Get allocated in this thread, enqueued to a global queue, dequeued and + * freed in the manage apps thread. + */ + struct ust_command *ust_cmd = NULL; - /* TODO: Something more elegant is needed but fine for now */ - /* FIXME: change all types to either uint8_t, uint32_t, uint64_t - * for 32-bit vs 64-bit compat processes. */ - /* replicate in ust with version number */ - struct { - int reg; /* 1:register, 0:unregister */ - pid_t pid; - uid_t uid; - } reg_msg; - - DBG("[thread] Manage apps started"); + DBG("[thread] Manage application registration started"); ret = lttcomm_listen_unix_sock(apps_sock); if (ret < 0) { @@ -833,7 +1064,7 @@ static void *thread_manage_apps(void *data) pollfd[1].events = POLLIN; /* Notify all applications to register */ - notify_apps(default_global_apps_pipe); + //notify_apps(default_global_apps_pipe); while (1) { DBG("Accepting application registration"); @@ -841,7 +1072,7 @@ static void *thread_manage_apps(void *data) /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, 2, -1); if (ret < 0) { - perror("poll apps thread"); + perror("poll register apps thread"); goto error; } @@ -849,7 +1080,7 @@ static void *thread_manage_apps(void *data) if (pollfd[0].revents == POLLNVAL) { goto error; } else if (pollfd[1].revents == POLLERR) { - ERR("Apps socket poll error"); + ERR("Register apps socket poll error"); goto error; } @@ -858,39 +1089,46 @@ static void *thread_manage_apps(void *data) goto error; } + /* Create UST registration command for enqueuing */ + ust_cmd = malloc(sizeof(struct ust_command)); + if (ust_cmd == NULL) { + perror("ust command malloc"); + goto error; + } + /* - * Using message-based transmissions to ensure we don't - * have to deal with partially received messages. + * Using message-based transmissions to ensure we don't have to deal + * with partially received messages. */ - ret = lttcomm_recv_unix_sock(sock, ®_msg, sizeof(reg_msg)); - if (ret < 0) { - perror("recv"); + ret = lttcomm_recv_unix_sock(sock, &ust_cmd->reg_msg, + sizeof(struct ust_register_msg)); + if (ret < 0 || ret != sizeof(struct ust_register_msg)) { + perror("lttcomm_recv_unix_sock register apps"); + free(ust_cmd); + close(sock); continue; } - /* Add application to the global traceable list */ - if (reg_msg.reg == 1) { - /* Registering */ - /* - * TODO: socket should be either passed to a - * listener thread (for more messages) or - * closed. It currently leaks. - */ - ret = register_traceable_app(reg_msg.pid, reg_msg.uid); - if (ret < 0) { - /* register_traceable_app only return an error with - * ENOMEM. At this point, we better stop everything. - */ - goto error; - } - } else { - /* Unregistering */ - unregister_traceable_app(reg_msg.pid); - } + ust_cmd->sock = sock; + + /* + * Lock free enqueue the registration request. + * The red pill has been taken! This apps will be part of the *system* + */ + cds_wfq_enqueue(&ust_cmd_queue.queue, &ust_cmd->node); + + /* + * Wake the registration queue futex. + * Implicit memory barrier with the exchange in cds_wfq_enqueue. + */ + futex_nto1_wake(&ust_cmd_queue.futex); + + DBG("Thread manage apps informed of queued node with sock:%d pid:%d", + sock, ust_cmd->reg_msg.pid); } error: - DBG("Apps thread dying"); + DBG("Register apps thread dying"); if (apps_sock) { close(apps_sock); } @@ -1323,13 +1561,6 @@ static int create_kernel_session(struct ltt_session *session) session->kernel_session->consumer_fd = kconsumerd_cmd_sock; } - ret = asprintf(&session->kernel_session->trace_path, "%s/kernel", - session->path); - if (ret < 0) { - perror("asprintf kernel traces path"); - goto error; - } - ret = mkdir_recursive(session->kernel_session->trace_path, S_IRWXU | S_IRWXG, geteuid(), allowed_group()); if (ret < 0) { @@ -1569,7 +1800,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: - kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, + kchan = trace_kernel_get_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { ret = LTTCOMM_KERN_CHAN_NOT_FOUND; @@ -1607,14 +1838,14 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: - kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, + kchan = trace_kernel_get_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { ret = LTTCOMM_KERN_CHAN_NOT_FOUND; goto error; } - kevent = get_kernel_event_by_name(cmd_ctx->lsm->u.disable.name, kchan); + kevent = trace_kernel_get_event_by_name(cmd_ctx->lsm->u.disable.name, kchan); if (kevent != NULL) { DBG("Disabling kernel event %s for channel %s.", kevent->event->name, kchan->channel->name); @@ -1650,7 +1881,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: DBG("Disabling all enabled kernel events"); - kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, + kchan = trace_kernel_get_channel_by_name(cmd_ctx->lsm->u.disable.channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { ret = LTTCOMM_KERN_CHAN_NOT_FOUND; @@ -1691,7 +1922,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: - kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name, + kchan = trace_kernel_get_channel_by_name(cmd_ctx->lsm->u.enable.channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { /* Channel not found, creating it */ @@ -1749,7 +1980,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: - kchan = get_kernel_channel_by_name(channel_name, + kchan = trace_kernel_get_channel_by_name(channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { DBG("Channel not found. Creating channel %s", channel_name); @@ -1766,7 +1997,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_KERN_CHAN_FAIL; goto error; } - kchan = get_kernel_channel_by_name(channel_name, + kchan = trace_kernel_get_channel_by_name(channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { ERR("Channel %s not found after creation. Internal error, giving up.", @@ -1776,7 +2007,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } } - kevent = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, kchan); + kevent = trace_kernel_get_event_by_name(cmd_ctx->lsm->u.enable.event.name, kchan); if (kevent == NULL) { DBG("Creating kernel event %s for channel %s.", cmd_ctx->lsm->u.enable.event.name, channel_name); @@ -1827,7 +2058,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: - kchan = get_kernel_channel_by_name(channel_name, + kchan = trace_kernel_get_channel_by_name(channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { DBG("Channel not found. Creating channel %s", channel_name); @@ -1844,7 +2075,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_KERN_CHAN_FAIL; goto error; } - kchan = get_kernel_channel_by_name(channel_name, + kchan = trace_kernel_get_channel_by_name(channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { ERR("Channel %s not found after creation. Internal error, giving up.", @@ -1871,7 +2102,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } for (i = 0; i < size; i++) { - kevent = get_kernel_event_by_name(event_list[i].name, kchan); + kevent = trace_kernel_get_event_by_name(event_list[i].name, kchan); if (kevent == NULL) { /* Default event type for enable all */ event_list[i].type = LTTNG_EVENT_TRACEPOINT; @@ -2155,7 +2386,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) struct ltt_kernel_channel *kchan = NULL; if (cmd_ctx->session->kernel_session != NULL) { - kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.list.channel_name, + kchan = trace_kernel_get_channel_by_name(cmd_ctx->lsm->u.list.channel_name, cmd_ctx->session->kernel_session); if (kchan == NULL) { ret = LTTCOMM_KERN_CHAN_NOT_FOUND; @@ -2586,13 +2817,15 @@ end: static int check_existing_daemon(void) { if (access(client_unix_sock_path, F_OK) < 0 && - access(apps_unix_sock_path, F_OK) < 0) + access(apps_unix_sock_path, F_OK) < 0) { return 0; + } /* Is there anybody out there ? */ - if (lttng_session_daemon_alive()) + if (lttng_session_daemon_alive()) { return -EEXIST; - else + } else { return 0; + } } /* @@ -2653,6 +2886,14 @@ static int create_kernel_poll_pipe(void) return pipe2(kernel_poll_pipe, O_CLOEXEC); } +/* + * Create the application command pipe to wake thread_manage_apps. + */ +static int create_apps_cmd_pipe(void) +{ + return pipe2(apps_cmd_pipe, O_CLOEXEC); +} + /* * Create the lttng run directory needed for all global sockets and pipe. */ @@ -2929,6 +3170,14 @@ int main(int argc, char **argv) goto exit; } + /* Setup the thread apps communication pipe. */ + if ((ret = create_apps_cmd_pipe()) < 0) { + goto exit; + } + + /* Init UST command queue. */ + cds_wfq_init(&ust_cmd_queue.queue); + /* * Get session list pointer. This pointer MUST NOT be free(). * This list is statically declared in session.c @@ -2936,23 +3185,40 @@ int main(int argc, char **argv) session_list_ptr = get_session_list(); /* Create thread to manage the client socket */ - ret = pthread_create(&client_thread, NULL, thread_manage_clients, (void *) NULL); + ret = pthread_create(&client_thread, NULL, + thread_manage_clients, (void *) NULL); if (ret != 0) { - perror("pthread_create"); + perror("pthread_create clients"); goto exit_client; } + /* Create thread to dispatch registration */ + ret = pthread_create(&dispatch_thread, NULL, + thread_dispatch_ust_registration, (void *) NULL); + if (ret != 0) { + perror("pthread_create dispatch"); + goto exit_dispatch; + } + + /* Create thread to manage application registration. */ + ret = pthread_create(®_apps_thread, NULL, + thread_registration_apps, (void *) NULL); + if (ret != 0) { + perror("pthread_create registration"); + goto exit_reg_apps; + } + /* Create thread to manage application socket */ ret = pthread_create(&apps_thread, NULL, thread_manage_apps, (void *) NULL); if (ret != 0) { - perror("pthread_create"); + perror("pthread_create apps"); goto exit_apps; } /* Create kernel thread to manage kernel event */ ret = pthread_create(&kernel_thread, NULL, thread_manage_kernel, (void *) NULL); if (ret != 0) { - perror("pthread_create"); + perror("pthread_create kernel"); goto exit_kernel; } @@ -2970,6 +3236,20 @@ exit_kernel: } exit_apps: + ret = pthread_join(reg_apps_thread, &status); + if (ret != 0) { + perror("pthread_join"); + goto error; /* join error, exit without cleanup */ + } + +exit_reg_apps: + ret = pthread_join(dispatch_thread, &status); + if (ret != 0) { + perror("pthread_join"); + goto error; /* join error, exit without cleanup */ + } + +exit_dispatch: ret = pthread_join(client_thread, &status); if (ret != 0) { perror("pthread_join"); diff --git a/ltt-sessiond/session.c b/ltt-sessiond/session.c index 3131006f1..118c8f57c 100644 --- a/ltt-sessiond/session.c +++ b/ltt-sessiond/session.c @@ -8,7 +8,7 @@ * * 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 + * 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 @@ -18,14 +18,12 @@ #define _GNU_SOURCE #include -#include #include #include #include -#include -#include -#include "lttngerr.h" +#include + #include "session.h" /* @@ -49,11 +47,9 @@ static struct ltt_session_list ltt_session_list = { }; /* - * add_session_list - * - * Add a ltt_session structure to the global list. + * Add a ltt_session structure to the global list. * - * The caller MUST acquire the session list lock before. + * The caller MUST acquire the session list lock before. */ static void add_session_list(struct ltt_session *ls) { @@ -62,11 +58,9 @@ static void add_session_list(struct ltt_session *ls) } /* - * del_session_list + * Delete a ltt_session structure to the global list. * - * Delete a ltt_session structure to the global list. - * - * The caller MUST acquire the session list lock before. + * The caller MUST acquire the session list lock before. */ static void del_session_list(struct ltt_session *ls) { @@ -78,9 +72,7 @@ static void del_session_list(struct ltt_session *ls) } /* - * get_session_list - * - * Return a pointer to the session list. + * Return a pointer to the session list. */ struct ltt_session_list *get_session_list(void) { @@ -120,10 +112,8 @@ void unlock_session(struct ltt_session *session) } /* - * find_session_by_name - * - * Return a ltt_session structure ptr that matches name. - * If no session found, NULL is returned. + * Return a ltt_session structure ptr that matches name. + * If no session found, NULL is returned. */ struct ltt_session *find_session_by_name(char *name) { @@ -147,11 +137,9 @@ struct ltt_session *find_session_by_name(char *name) } /* - * destroy_session - * - * Delete session from the session list and free the memory. + * Delete session from the session list and free the memory. * - * Return -1 if no session is found. On success, return 1; + * Return -1 if no session is found. On success, return 1; */ int destroy_session(char *name) { @@ -177,9 +165,7 @@ int destroy_session(char *name) } /* - * create_session - * - * Create a brand new session and add it to the session list. + * Create a brand new session and add it to the session list. */ int create_session(char *name, char *path) { diff --git a/ltt-sessiond/session.h b/ltt-sessiond/session.h index dad0cd929..fa1d064b6 100644 --- a/ltt-sessiond/session.h +++ b/ltt-sessiond/session.h @@ -19,9 +19,12 @@ #ifndef _LTT_SESSION_H #define _LTT_SESSION_H -//#include +#include #include +#include "trace-kernel.h" +#include "trace-ust.h" + /* * Tracing session list * diff --git a/ltt-sessiond/trace-kernel.c b/ltt-sessiond/trace-kernel.c new file mode 100644 index 000000000..113eebea8 --- /dev/null +++ b/ltt-sessiond/trace-kernel.c @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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 +#include +#include +#include + +#include + +#include "trace-kernel.h" + +/* + * Find the channel name for the given kernel session. + */ +struct ltt_kernel_channel *trace_kernel_get_channel_by_name( + char *name, struct ltt_kernel_session *session) +{ + struct ltt_kernel_channel *chan; + + if (session == NULL) { + ERR("Undefine session"); + goto error; + } + + cds_list_for_each_entry(chan, &session->channel_list.head, list) { + if (strcmp(name, chan->channel->name) == 0) { + DBG("Found channel by name %s", name); + return chan; + } + } + +error: + return NULL; +} + +/* + * Find the event name for the given channel. + */ +struct ltt_kernel_event *trace_kernel_get_event_by_name( + char *name, struct ltt_kernel_channel *channel) +{ + struct ltt_kernel_event *ev; + + if (channel == NULL) { + ERR("Undefine channel"); + goto error; + } + + cds_list_for_each_entry(ev, &channel->events_list.head, list) { + if (strcmp(name, ev->event->name) == 0) { + DBG("Found event by name %s for channel %s", name, + channel->channel->name); + return ev; + } + } + +error: + return NULL; +} + +/* + * Allocate and initialize a kernel session data structure. + * + * Return pointer to structure or NULL. + */ +struct ltt_kernel_session *trace_kernel_create_session(char *path) +{ + int ret; + struct ltt_kernel_session *lks; + + /* Allocate a new ltt kernel session */ + lks = malloc(sizeof(struct ltt_kernel_session)); + if (lks == NULL) { + perror("create kernel session malloc"); + goto error; + } + + /* Init data structure */ + lks->fd = 0; + lks->metadata_stream_fd = 0; + lks->channel_count = 0; + lks->stream_count_global = 0; + lks->metadata = NULL; + lks->consumer_fd = 0; + CDS_INIT_LIST_HEAD(&lks->channel_list.head); + + /* Set session path */ + ret = asprintf(&lks->trace_path, "%s/kernel", path); + if (ret < 0) { + perror("asprintf kernel traces path"); + goto error; + } + + return lks; + +error: + return NULL; +} + +/* + * Allocate and initialize a kernel channel data structure. + * + * Return pointer to structure or NULL. + */ +struct ltt_kernel_channel *trace_kernel_create_channel(struct lttng_channel *chan, char *path) +{ + int ret; + struct ltt_kernel_channel *lkc; + + lkc = malloc(sizeof(struct ltt_kernel_channel)); + if (lkc == NULL) { + perror("ltt_kernel_channel malloc"); + goto error; + } + + lkc->channel = malloc(sizeof(struct lttng_channel)); + if (lkc->channel == NULL) { + perror("lttng_channel malloc"); + goto error; + } + memcpy(lkc->channel, chan, sizeof(struct lttng_channel)); + + lkc->fd = 0; + lkc->stream_count = 0; + lkc->event_count = 0; + lkc->enabled = 1; + lkc->ctx = NULL; + /* Init linked list */ + CDS_INIT_LIST_HEAD(&lkc->events_list.head); + CDS_INIT_LIST_HEAD(&lkc->stream_list.head); + /* Set default trace output path */ + ret = asprintf(&lkc->pathname, "%s", path); + if (ret < 0) { + perror("asprintf kernel create channel"); + goto error; + } + + return lkc; + +error: + return NULL; +} + +/* + * Allocate and initialize a kernel event. Set name and event type. + * + * Return pointer to structure or NULL. + */ +struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev) +{ + struct ltt_kernel_event *lke; + struct lttng_kernel_event *attr; + + lke = malloc(sizeof(struct ltt_kernel_event)); + attr = malloc(sizeof(struct lttng_kernel_event)); + if (lke == NULL || attr == NULL) { + perror("kernel event malloc"); + goto error; + } + + switch (ev->type) { + case LTTNG_EVENT_PROBE: + attr->instrumentation = LTTNG_KERNEL_KPROBE; + attr->u.kprobe.addr = ev->attr.probe.addr; + attr->u.kprobe.offset = ev->attr.probe.offset; + strncpy(attr->u.kprobe.symbol_name, + ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN); + attr->u.kprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + break; + case LTTNG_EVENT_FUNCTION: + attr->instrumentation = LTTNG_KERNEL_KRETPROBE; + attr->u.kretprobe.addr = ev->attr.probe.addr; + attr->u.kretprobe.offset = ev->attr.probe.offset; + attr->u.kretprobe.offset = ev->attr.probe.offset; + strncpy(attr->u.kretprobe.symbol_name, + ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN); + attr->u.kretprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + break; + case LTTNG_EVENT_FUNCTION_ENTRY: + attr->instrumentation = LTTNG_KERNEL_FUNCTION; + strncpy(attr->u.ftrace.symbol_name, + ev->attr.ftrace.symbol_name, LTTNG_SYM_NAME_LEN); + attr->u.ftrace.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + break; + case LTTNG_EVENT_TRACEPOINT: + attr->instrumentation = LTTNG_KERNEL_TRACEPOINT; + break; + default: + ERR("Unknown kernel instrumentation type (%d)", ev->type); + goto error; + } + + /* Copy event name */ + strncpy(attr->name, ev->name, LTTNG_SYM_NAME_LEN); + attr->name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + + /* Setting up a kernel event */ + lke->fd = 0; + lke->event = attr; + lke->enabled = 1; + lke->ctx = NULL; + + return lke; + +error: + return NULL; +} + +/* + * Allocate and initialize a kernel metadata. + * + * Return pointer to structure or NULL. + */ +struct ltt_kernel_metadata *trace_kernel_create_metadata(char *path) +{ + int ret; + struct ltt_kernel_metadata *lkm; + struct lttng_channel *chan; + + lkm = malloc(sizeof(struct ltt_kernel_metadata)); + chan = malloc(sizeof(struct lttng_channel)); + if (lkm == NULL || chan == NULL) { + perror("kernel metadata malloc"); + goto error; + } + + /* Set default attributes */ + chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; + chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; + chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; + chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; + chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; + + /* Init metadata */ + lkm->fd = 0; + lkm->conf = chan; + /* Set default metadata path */ + ret = asprintf(&lkm->pathname, "%s/metadata", path); + if (ret < 0) { + perror("asprintf kernel metadata"); + goto error; + } + + return lkm; + +error: + return NULL; +} + +/* + * Allocate and initialize a kernel stream. The stream is set to ACTIVE_FD by + * default. + * + * Return pointer to structure or NULL. + */ +struct ltt_kernel_stream *trace_kernel_create_stream(void) +{ + struct ltt_kernel_stream *lks; + + lks = malloc(sizeof(struct ltt_kernel_stream)); + if (lks == NULL) { + perror("kernel stream malloc"); + goto error; + } + + /* Init stream */ + lks->fd = 0; + lks->pathname = NULL; + lks->state = 0; + + return lks; + +error: + return NULL; +} + +/* + * Cleanup kernel stream structure. + */ +void trace_kernel_destroy_stream(struct ltt_kernel_stream *stream) +{ + DBG("[trace] Closing stream fd %d", stream->fd); + /* Close kernel fd */ + close(stream->fd); + /* Remove from stream list */ + cds_list_del(&stream->list); + + free(stream->pathname); + free(stream); +} + +/* + * Cleanup kernel event structure. + */ +void trace_kernel_destroy_event(struct ltt_kernel_event *event) +{ + DBG("[trace] Closing event fd %d", event->fd); + /* Close kernel fd */ + close(event->fd); + + /* Remove from event list */ + cds_list_del(&event->list); + + free(event->event); + free(event->ctx); + free(event); +} + +/* + * Cleanup kernel channel structure. + */ +void trace_kernel_destroy_channel(struct ltt_kernel_channel *channel) +{ + struct ltt_kernel_stream *stream, *stmp; + struct ltt_kernel_event *event, *etmp; + + DBG("[trace] Closing channel fd %d", channel->fd); + /* Close kernel fd */ + close(channel->fd); + + /* For each stream in the channel list */ + cds_list_for_each_entry_safe(stream, stmp, &channel->stream_list.head, list) { + trace_kernel_destroy_stream(stream); + } + + /* For each event in the channel list */ + cds_list_for_each_entry_safe(event, etmp, &channel->events_list.head, list) { + trace_kernel_destroy_event(event); + } + + /* Remove from channel list */ + cds_list_del(&channel->list); + + free(channel->pathname); + free(channel->channel); + free(channel->ctx); + free(channel); +} + +/* + * Cleanup kernel metadata structure. + */ +void trace_kernel_destroy_metadata(struct ltt_kernel_metadata *metadata) +{ + DBG("[trace] Closing metadata fd %d", metadata->fd); + /* Close kernel fd */ + close(metadata->fd); + + free(metadata->conf); + free(metadata->pathname); + free(metadata); +} + +/* + * Cleanup kernel session structure + */ +void trace_kernel_destroy_session(struct ltt_kernel_session *session) +{ + struct ltt_kernel_channel *channel, *ctmp; + + DBG("[trace] Closing session fd %d", session->fd); + /* Close kernel fds */ + close(session->fd); + + if (session->metadata_stream_fd != 0) { + DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd); + close(session->metadata_stream_fd); + } + + if (session->metadata != NULL) { + trace_kernel_destroy_metadata(session->metadata); + } + + cds_list_for_each_entry_safe(channel, ctmp, &session->channel_list.head, list) { + trace_kernel_destroy_channel(channel); + } + + free(session->trace_path); + free(session); +} diff --git a/ltt-sessiond/trace-kernel.h b/ltt-sessiond/trace-kernel.h new file mode 100644 index 000000000..6bf5752fd --- /dev/null +++ b/ltt-sessiond/trace-kernel.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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 _LTT_TRACE_KERNEL_H +#define _LTT_TRACE_KERNEL_H + +#include +#include + +#include +#include + +/* Kernel event list */ +struct ltt_kernel_event_list { + struct cds_list_head head; +}; + +/* Channel stream list */ +struct ltt_kernel_stream_list { + struct cds_list_head head; +}; + +/* Channel list */ +struct ltt_kernel_channel_list { + struct cds_list_head head; +}; + +/* Kernel event */ +struct ltt_kernel_event { + int fd; + int enabled; + struct lttng_kernel_context *ctx; + struct lttng_kernel_event *event; + struct cds_list_head list; +}; + +/* Kernel channel */ +struct ltt_kernel_channel { + int fd; + int enabled; + char *pathname; + unsigned int stream_count; + unsigned int event_count; + struct lttng_kernel_context *ctx; + struct lttng_channel *channel; + struct ltt_kernel_event_list events_list; + struct ltt_kernel_stream_list stream_list; + struct cds_list_head list; +}; + +/* Metadata */ +struct ltt_kernel_metadata { + int fd; + char *pathname; + struct lttng_channel *conf; +}; + +/* Channel stream */ +struct ltt_kernel_stream { + int fd; + char *pathname; + int state; + struct cds_list_head list; +}; + +/* Kernel session */ +struct ltt_kernel_session { + int fd; + int metadata_stream_fd; + int kconsumer_fds_sent; + int consumer_fd; + unsigned int channel_count; + unsigned int stream_count_global; + char *trace_path; + struct ltt_kernel_metadata *metadata; + struct ltt_kernel_channel_list channel_list; +}; + +/* + * Lookup functions. NULL is returned if not found. + */ +struct ltt_kernel_event *trace_kernel_get_event_by_name( + char *name, struct ltt_kernel_channel *channel); +struct ltt_kernel_channel *trace_kernel_get_channel_by_name( + char *name, struct ltt_kernel_session *session); + +/* + * Create functions malloc() the data structure. + */ +struct ltt_kernel_session *trace_kernel_create_session(char *path); +struct ltt_kernel_channel *trace_kernel_create_channel(struct lttng_channel *chan, char *path); +struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev); +struct ltt_kernel_metadata *trace_kernel_create_metadata(char *path); +struct ltt_kernel_stream *trace_kernel_create_stream(void); + +/* + * Destroy functions free() the data structure and remove from linked list if + * it's applies. + */ +void trace_kernel_destroy_session(struct ltt_kernel_session *session); +void trace_kernel_destroy_metadata(struct ltt_kernel_metadata *metadata); +void trace_kernel_destroy_channel(struct ltt_kernel_channel *channel); +void trace_kernel_destroy_event(struct ltt_kernel_event *event); +void trace_kernel_destroy_stream(struct ltt_kernel_stream *stream); + +#endif /* _LTT_TRACE_KERNEL_H */ diff --git a/ltt-sessiond/trace-ust.c b/ltt-sessiond/trace-ust.c new file mode 100644 index 000000000..957ac770b --- /dev/null +++ b/ltt-sessiond/trace-ust.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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 +#include +#include +#include + +#include +#include + +#include "trace-ust.h" + +/* + * Find the channel name for the given ust session. + */ +struct ltt_ust_channel *trace_ust_get_channel_by_name( + char *name, struct ltt_ust_session *session) +{ + struct ltt_ust_channel *chan; + + if (session == NULL) { + ERR("Undefine session"); + goto error; + } + + cds_list_for_each_entry(chan, &session->channels.head, list) { + if (strcmp(name, chan->name) == 0) { + DBG("Found UST channel by name %s", name); + return chan; + } + } + +error: + return NULL; +} + +/* + * Find the event name for the given channel. + */ +struct ltt_ust_event *trace_ust_get_event_by_name( + char *name, struct ltt_ust_channel *channel) +{ + struct ltt_ust_event *ev; + + if (channel == NULL) { + ERR("Undefine channel"); + goto error; + } + + cds_list_for_each_entry(ev, &channel->events.head, list) { + if (strcmp(name, ev->event->name) == 0) { + DBG("Found UST event by name %s for channel %s", name, + channel->name); + return ev; + } + } + +error: + return NULL; +} + +/* + * Allocate and initialize a ust session data structure. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_session *trace_ust_create_session(void) +{ + struct ltt_ust_session *lus; + + /* Allocate a new ltt ust session */ + lus = malloc(sizeof(struct ltt_ust_session)); + if (lus == NULL) { + perror("create ust session malloc"); + goto error; + } + + /* Init data structure */ + lus->handle = -1; + lus->enabled = 1; + lus->uconsumer_fds_sent = 0; + lus->path = NULL; + lus->metadata = NULL; + lus->channels.count = 0; + CDS_INIT_LIST_HEAD(&lus->channels.head); + + return lus; + +error: + return NULL; +} + +/* + * Allocate and initialize a ust channel data structure. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path, + struct lttng_ust_channel *chan) +{ + int ret; + struct ltt_ust_channel *luc; + + luc = malloc(sizeof(struct ltt_ust_channel)); + if (luc == NULL) { + perror("ltt_ust_channel malloc"); + goto error; + } + + luc->attr = malloc(sizeof(struct lttng_ust_channel)); + if (luc->attr == NULL) { + perror("lttng_ust_channel malloc"); + goto error; + } + memcpy(luc->attr, chan, sizeof(struct lttng_ust_channel)); + + luc->handle = -1; + luc->enabled = 1; + luc->ctx = NULL; + luc->events.count = 0; + CDS_INIT_LIST_HEAD(&luc->events.head); + + /* Copy channel name */ + strncpy(luc->name, name, LTTNG_UST_SYM_NAME_LEN); + luc->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + + /* Set trace output path */ + ret = asprintf(&luc->trace_path, "%s", path); + if (ret < 0) { + perror("asprintf ust create channel"); + goto error; + } + + return luc; + +error: + return NULL; +} + +/* + * Allocate and initialize a ust event. Set name and event type. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev) +{ + struct ltt_ust_event *lue; + struct lttng_ust_event *event; + + lue = malloc(sizeof(struct ltt_ust_event)); + event = malloc(sizeof(struct lttng_ust_event)); + if (lue == NULL || event == NULL) { + perror("ust event malloc"); + goto error; + } + + switch (ev->type) { + case LTTNG_EVENT_PROBE: + event->instrumentation = LTTNG_UST_PROBE; + break; + case LTTNG_EVENT_FUNCTION: + event->instrumentation = LTTNG_UST_FUNCTION; + break; + case LTTNG_EVENT_FUNCTION_ENTRY: + event->instrumentation = LTTNG_UST_FUNCTION; + break; + case LTTNG_EVENT_TRACEPOINT: + event->instrumentation = LTTNG_UST_TRACEPOINT; + break; + default: + ERR("Unknown ust instrumentation type (%d)", ev->type); + goto error; + } + + /* Copy event name */ + strncpy(event->name, ev->name, LTTNG_UST_SYM_NAME_LEN); + event->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + + /* Setting up a ust event */ + lue->handle = -1; + lue->event = event; + lue->enabled = 1; + lue->ctx = NULL; + + return lue; + +error: + return NULL; +} + +/* + * Allocate and initialize a ust metadata. + * + * Return pointer to structure or NULL. + */ +struct ltt_ust_metadata *trace_ust_create_metadata(char *path) +{ + int ret; + struct ltt_ust_metadata *lum; + struct lttng_ust_channel *attr; + + lum = malloc(sizeof(struct ltt_ust_metadata)); + attr = malloc(sizeof(struct lttng_ust_channel)); + if (lum == NULL || attr == NULL) { + perror("ust metadata malloc"); + goto error; + } + + /* Set default attributes */ + attr->overwrite = DEFAULT_CHANNEL_OVERWRITE; + attr->subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + attr->num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; + attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; + attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; + attr->output = DEFAULT_UST_CHANNEL_OUTPUT; + + lum->attr = attr; + lum->handle = -1; + /* Set metadata trace path */ + ret = asprintf(&lum->trace_path, "%s/metadata", path); + if (ret < 0) { + perror("asprintf ust metadata"); + goto error; + } + + return lum; + +error: + return NULL; +} + +/* + * Cleanup ust event structure. + */ +void trace_ust_destroy_event(struct ltt_ust_event *event) +{ + DBG("[trace] Destroy ust event %s", event->event->name); + + /* Free attributes */ + free(event->event); + free(event->ctx); + + /* Remove from event list */ + cds_list_del(&event->list); + free(event); +} + +/* + * Cleanup ust channel structure. + */ +void trace_ust_destroy_channel(struct ltt_ust_channel *channel) +{ + struct ltt_ust_event *event, *etmp; + + DBG("[trace] Destroy ust channel %d", channel->handle); + + free(channel->trace_path); + /* Free attributes structure */ + free(channel->attr); + free(channel->ctx); + + /* For each event in the channel list */ + cds_list_for_each_entry_safe(event, etmp, &channel->events.head, list) { + trace_ust_destroy_event(event); + } + + /* Remove from channel list */ + cds_list_del(&channel->list); + free(channel); +} + +/* + * Cleanup ust metadata structure. + */ +void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata) +{ + DBG("[trace] Destroy ust metadata %d", metadata->handle); + + /* Free attributes */ + free(metadata->attr); + free(metadata->trace_path); + + free(metadata); +} + +/* + * Cleanup ust session structure + */ +void trace_ust_destroy_session(struct ltt_ust_session *session) +{ + struct ltt_ust_channel *channel, *ctmp; + + DBG("[trace] Destroy ust session %d", session->handle); + + /* Extra safety */ + if (session == NULL) { + return; + } + + if (session->metadata != NULL) { + trace_ust_destroy_metadata(session->metadata); + } + + cds_list_for_each_entry_safe(channel, ctmp, &session->channels.head, list) { + trace_ust_destroy_channel(channel); + } + + free(session->path); + free(session); +} diff --git a/ltt-sessiond/trace-ust.h b/ltt-sessiond/trace-ust.h new file mode 100644 index 000000000..fa86cb94f --- /dev/null +++ b/ltt-sessiond/trace-ust.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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 _LTT_TRACE_UST_H +#define _LTT_TRACE_UST_H + +#include +#include + +#include +#include + +/* UST event list */ +struct ltt_ust_event_list { + unsigned int count; + struct cds_list_head head; +}; + +/* UST Channel list */ +struct ltt_ust_channel_list { + unsigned int count; + struct cds_list_head head; +}; + +/* UST event */ +struct ltt_ust_event { + int handle; + int enabled; + struct lttng_ust_context *ctx; + struct lttng_ust_event *event; + struct cds_list_head list; +}; + +/* UST channel */ +struct ltt_ust_channel { + int handle; + int enabled; + char *name; + char *trace_path; /* Trace file path name */ + struct lttng_ust_context *ctx; + struct lttng_ust_channel *attr; + struct ltt_ust_event_list events; + struct cds_list_head list; +}; + +/* UST Metadata */ +struct ltt_ust_metadata { + int handle; + char *trace_path; /* Trace file path name */ + struct lttng_ust_channel *attr; +}; + +/* UST session */ +struct ltt_ust_session { + int handle; + int enabled; + int uconsumer_fds_sent; + char *path; + struct ltt_ust_metadata *metadata; + struct ltt_ust_channel_list channels; +}; + +/* + * Lookup functions. NULL is returned if not found. + */ +struct ltt_ust_event *trace_ust_get_event_by_name( + char *name, struct ltt_ust_channel *channel); +struct ltt_ust_channel *trace_ust_get_channel_by_name( + char *name, struct ltt_ust_session *session); + +/* + * Create functions malloc() the data structure. + */ +struct ltt_ust_session *trace_ust_create_session(void); +struct ltt_ust_channel *trace_ust_create_channel(char *name, char *path, + struct lttng_ust_channel *attr); +struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev); +struct ltt_ust_metadata *trace_ust_create_metadata(char *path); + +/* + * Destroy functions free() the data structure and remove from linked list if + * it's applies. + */ +void trace_ust_destroy_session(struct ltt_ust_session *session); +void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata); +void trace_ust_destroy_channel(struct ltt_ust_channel *channel); +void trace_ust_destroy_event(struct ltt_ust_event *event); + +#endif /* _LTT_TRACE_UST_H */ diff --git a/ltt-sessiond/trace.c b/ltt-sessiond/trace.c deleted file mode 100644 index 621e4dd3f..000000000 --- a/ltt-sessiond/trace.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (C) 2011 - David Goulet - * - * 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 -#include -#include -#include -#include - -#include "lttngerr.h" -#include "trace.h" - -/* - * get_kernel_channel_by_name - * - * Find the channel name for the given kernel session. - */ -struct ltt_kernel_channel *get_kernel_channel_by_name( - char *name, struct ltt_kernel_session *session) -{ - struct ltt_kernel_channel *chan; - - if (session == NULL) { - ERR("Undefine session"); - goto error; - } - - cds_list_for_each_entry(chan, &session->channel_list.head, list) { - if (strcmp(name, chan->channel->name) == 0) { - DBG("Found channel by name %s", name); - return chan; - } - } - -error: - return NULL; -} - -/* - * get_kernel_event_by_name - * - * Find the event name for the given channel. - */ -struct ltt_kernel_event *get_kernel_event_by_name( - char *name, struct ltt_kernel_channel *channel) -{ - struct ltt_kernel_event *ev; - - if (channel == NULL) { - ERR("Undefine channel"); - goto error; - } - - cds_list_for_each_entry(ev, &channel->events_list.head, list) { - if (strcmp(name, ev->event->name) == 0) { - DBG("Found event by name %s for channel %s", name, - channel->channel->name); - return ev; - } - } - -error: - return NULL; -} - -/* - * trace_create_kernel_session - * - * Allocate and initialize a kernel session data structure. - * - * Return pointer to structure or NULL. - */ -struct ltt_kernel_session *trace_create_kernel_session(void) -{ - struct ltt_kernel_session *lks; - - /* Allocate a new ltt kernel session */ - lks = malloc(sizeof(struct ltt_kernel_session)); - if (lks == NULL) { - perror("create kernel session malloc"); - goto error; - } - - /* Init data structure */ - lks->fd = 0; - lks->metadata_stream_fd = 0; - lks->channel_count = 0; - lks->stream_count_global = 0; - lks->metadata = NULL; - lks->consumer_fd = 0; - CDS_INIT_LIST_HEAD(&lks->channel_list.head); - - return lks; - -error: - return NULL; -} - -/* - * trace_create_kernel_channel - * - * Allocate and initialize a kernel channel data structure. - * - * Return pointer to structure or NULL. - */ -struct ltt_kernel_channel *trace_create_kernel_channel(struct lttng_channel *chan, char *path) -{ - int ret; - struct ltt_kernel_channel *lkc; - - lkc = malloc(sizeof(struct ltt_kernel_channel)); - if (lkc == NULL) { - perror("ltt_kernel_channel malloc"); - goto error; - } - - lkc->channel = malloc(sizeof(struct lttng_channel)); - if (lkc->channel == NULL) { - perror("lttng_channel malloc"); - goto error; - } - memcpy(lkc->channel, chan, sizeof(struct lttng_channel)); - - lkc->fd = 0; - lkc->stream_count = 0; - lkc->event_count = 0; - lkc->enabled = 1; - lkc->ctx = NULL; - /* Init linked list */ - CDS_INIT_LIST_HEAD(&lkc->events_list.head); - CDS_INIT_LIST_HEAD(&lkc->stream_list.head); - /* Set default trace output path */ - ret = asprintf(&lkc->pathname, "%s", path); - if (ret < 0) { - perror("asprintf kernel create channel"); - goto error; - } - - return lkc; - -error: - return NULL; -} - -/* - * trace_create_kernel_event - * - * Allocate and initialize a kernel event. Set name and event type. - * - * Return pointer to structure or NULL. - */ -struct ltt_kernel_event *trace_create_kernel_event(struct lttng_event *ev) -{ - struct ltt_kernel_event *lke; - struct lttng_kernel_event *attr; - - lke = malloc(sizeof(struct ltt_kernel_event)); - attr = malloc(sizeof(struct lttng_kernel_event)); - if (lke == NULL || attr == NULL) { - perror("kernel event malloc"); - goto error; - } - - switch (ev->type) { - case LTTNG_EVENT_PROBE: - attr->instrumentation = LTTNG_KERNEL_KPROBE; - attr->u.kprobe.addr = ev->attr.probe.addr; - attr->u.kprobe.offset = ev->attr.probe.offset; - strncpy(attr->u.kprobe.symbol_name, - ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN); - attr->u.kprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; - break; - case LTTNG_EVENT_FUNCTION: - attr->instrumentation = LTTNG_KERNEL_KRETPROBE; - attr->u.kretprobe.addr = ev->attr.probe.addr; - attr->u.kretprobe.offset = ev->attr.probe.offset; - attr->u.kretprobe.offset = ev->attr.probe.offset; - strncpy(attr->u.kretprobe.symbol_name, - ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN); - attr->u.kretprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; - break; - case LTTNG_EVENT_FUNCTION_ENTRY: - attr->instrumentation = LTTNG_KERNEL_FUNCTION; - strncpy(attr->u.ftrace.symbol_name, - ev->attr.ftrace.symbol_name, LTTNG_SYM_NAME_LEN); - attr->u.ftrace.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0'; - break; - case LTTNG_EVENT_TRACEPOINT: - attr->instrumentation = LTTNG_KERNEL_TRACEPOINT; - break; - default: - ERR("Unknown kernel instrumentation type (%d)", ev->type); - goto error; - } - - /* Copy event name */ - strncpy(attr->name, ev->name, LTTNG_SYM_NAME_LEN); - attr->name[LTTNG_SYM_NAME_LEN - 1] = '\0'; - - /* Setting up a kernel event */ - lke->fd = 0; - lke->event = attr; - lke->enabled = 1; - lke->ctx = NULL; - - return lke; - -error: - return NULL; -} - -/* - * trace_create_kernel_metadata - * - * Allocate and initialize a kernel metadata. - * - * Return pointer to structure or NULL. - */ -struct ltt_kernel_metadata *trace_create_kernel_metadata(char *path) -{ - int ret; - struct ltt_kernel_metadata *lkm; - struct lttng_channel *chan; - - lkm = malloc(sizeof(struct ltt_kernel_metadata)); - chan = malloc(sizeof(struct lttng_channel)); - if (lkm == NULL || chan == NULL) { - perror("kernel metadata malloc"); - goto error; - } - - /* Set default attributes */ - chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; - chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; - chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; - chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; - - /* Init metadata */ - lkm->fd = 0; - lkm->conf = chan; - /* Set default metadata path */ - ret = asprintf(&lkm->pathname, "%s/metadata", path); - if (ret < 0) { - perror("asprintf kernel metadata"); - goto error; - } - - return lkm; - -error: - return NULL; -} - -/* - * trace_create_kernel_stream - * - * Allocate and initialize a kernel stream. The stream is set to ACTIVE_FD by - * default. - * - * Return pointer to structure or NULL. - */ -struct ltt_kernel_stream *trace_create_kernel_stream(void) -{ - struct ltt_kernel_stream *lks; - - lks = malloc(sizeof(struct ltt_kernel_stream)); - if (lks == NULL) { - perror("kernel stream malloc"); - goto error; - } - - /* Init stream */ - lks->fd = 0; - lks->pathname = NULL; - lks->state = 0; - - return lks; - -error: - return NULL; -} - -void trace_destroy_kernel_stream(struct ltt_kernel_stream *stream) -{ - DBG("[trace] Closing stream fd %d", stream->fd); - /* Close kernel fd */ - close(stream->fd); - free(stream->pathname); - - /* Remove from stream list */ - cds_list_del(&stream->list); - free(stream); -} - -void trace_destroy_kernel_event(struct ltt_kernel_event *event) -{ - DBG("[trace] Closing event fd %d", event->fd); - /* Close kernel fd */ - close(event->fd); - /* Free attributes */ - free(event->event); - - /* Remove from event list */ - cds_list_del(&event->list); - free(event); -} - -void trace_destroy_kernel_channel(struct ltt_kernel_channel *channel) -{ - struct ltt_kernel_stream *stream, *stmp; - struct ltt_kernel_event *event, *etmp; - - DBG("[trace] Closing channel fd %d", channel->fd); - /* Close kernel fd */ - close(channel->fd); - free(channel->pathname); - /* Free attributes structure */ - free(channel->channel); - - /* For each stream in the channel list */ - cds_list_for_each_entry_safe(stream, stmp, &channel->stream_list.head, list) { - trace_destroy_kernel_stream(stream); - } - - /* For each event in the channel list */ - cds_list_for_each_entry_safe(event, etmp, &channel->events_list.head, list) { - trace_destroy_kernel_event(event); - } - - /* Remove from channel list */ - cds_list_del(&channel->list); - free(channel); -} - -void trace_destroy_kernel_metadata(struct ltt_kernel_metadata *metadata) -{ - DBG("[trace] Closing metadata fd %d", metadata->fd); - /* Close kernel fd */ - close(metadata->fd); - /* Free attributes */ - free(metadata->conf); - - free(metadata); -} - -void trace_destroy_kernel_session(struct ltt_kernel_session *session) -{ - struct ltt_kernel_channel *channel, *ctmp; - - DBG("[trace] Closing session fd %d", session->fd); - /* Close kernel fds */ - close(session->fd); - if (session->metadata_stream_fd != 0) { - DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd); - close(session->metadata_stream_fd); - } - - if (session->metadata != NULL) { - trace_destroy_kernel_metadata(session->metadata); - } - - cds_list_for_each_entry_safe(channel, ctmp, &session->channel_list.head, list) { - trace_destroy_kernel_channel(channel); - } - - free(session); -} diff --git a/ltt-sessiond/trace.h b/ltt-sessiond/trace.h deleted file mode 100644 index 9255bc932..000000000 --- a/ltt-sessiond/trace.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2011 - David Goulet - * - * 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 _LTT_TRACE_H -#define _LTT_TRACE_H - -#include -#include - -#include - -#include "lttng-kernel.h" - -/* Kernel event list */ -struct ltt_kernel_event_list { - struct cds_list_head head; -}; - -/* Channel stream list */ -struct ltt_kernel_stream_list { - struct cds_list_head head; -}; - -/* Channel list */ -struct ltt_kernel_channel_list { - struct cds_list_head head; -}; - -/* Kernel event */ -struct ltt_kernel_event { - int fd; - int enabled; - struct lttng_kernel_context *ctx; - struct lttng_kernel_event *event; - struct cds_list_head list; -}; - -/* Kernel channel */ -struct ltt_kernel_channel { - int fd; - int enabled; - char *pathname; - unsigned int stream_count; - unsigned int event_count; - struct lttng_kernel_context *ctx; - struct lttng_channel *channel; - struct ltt_kernel_event_list events_list; - struct ltt_kernel_stream_list stream_list; - struct cds_list_head list; -}; - -/* Metadata */ -struct ltt_kernel_metadata { - int fd; - char *pathname; - struct lttng_channel *conf; -}; - -/* Channel stream */ -struct ltt_kernel_stream { - int fd; - char *pathname; - int state; - struct cds_list_head list; -}; - -/* Kernel session */ -struct ltt_kernel_session { - int fd; - int metadata_stream_fd; - int kconsumer_fds_sent; - int consumer_fd; - unsigned int channel_count; - unsigned int stream_count_global; - char *trace_path; - struct ltt_kernel_metadata *metadata; - struct ltt_kernel_channel_list channel_list; -}; - -/* UST trace representation */ -struct ltt_ust_trace { - struct cds_list_head list; - char name[NAME_MAX]; - int shmid; - pid_t pid; - struct cds_list_head markers; -}; - -struct ltt_ust_marker { - struct cds_list_head list; - char *name; - char *channel; -}; - -/* - * Get functions. - */ -struct ltt_kernel_event *get_kernel_event_by_name( - char *name, struct ltt_kernel_channel *channel); -struct ltt_kernel_channel *get_kernel_channel_by_name( - char *name, struct ltt_kernel_session *session); - -/* - * Create functions malloc() the data structure. - */ -struct ltt_kernel_session *trace_create_kernel_session(void); -struct ltt_kernel_channel *trace_create_kernel_channel(struct lttng_channel *chan, char *path); -struct ltt_kernel_event *trace_create_kernel_event(struct lttng_event *ev); -struct ltt_kernel_metadata *trace_create_kernel_metadata(char *path); -struct ltt_kernel_stream *trace_create_kernel_stream(void); - -/* - * Destroy functions free() the data structure and remove from linked list if - * it's applies. - */ -void trace_destroy_kernel_session(struct ltt_kernel_session *session); -void trace_destroy_kernel_metadata(struct ltt_kernel_metadata *metadata); -void trace_destroy_kernel_channel(struct ltt_kernel_channel *channel); -void trace_destroy_kernel_event(struct ltt_kernel_event *event); -void trace_destroy_kernel_stream(struct ltt_kernel_stream *stream); - -#endif /* _LTT_TRACE_H */ diff --git a/ltt-sessiond/traceable-app.c b/ltt-sessiond/traceable-app.c index 52cfb0f0d..85d50393a 100644 --- a/ltt-sessiond/traceable-app.c +++ b/ltt-sessiond/traceable-app.c @@ -21,67 +21,90 @@ #include #include #include -#include +#include +#include -#include "lttngerr.h" -#include "traceable-app.h" +#include -/* Number of element for the list below. */ -static unsigned int traceable_app_count; +#include "traceable-app.h" /* Init ust traceabl application's list */ -struct ltt_traceable_app_list ltt_traceable_app_list = { +static struct ltt_traceable_app_list ltt_traceable_app_list = { .head = CDS_LIST_HEAD_INIT(ltt_traceable_app_list.head), + .lock = PTHREAD_MUTEX_INITIALIZER, + .count = 0, }; -/* List mutex */ -pthread_mutex_t ltt_traceable_app_list_mutex; - -/* Internal function */ -static void add_traceable_app(struct ltt_traceable_app *lta); -static void del_traceable_app(struct ltt_traceable_app *lta); - /* - * add_traceable_app - * - * Add a traceable application structure to the global - * list protected by a mutex. + * Add a traceable application structure to the global list. */ static void add_traceable_app(struct ltt_traceable_app *lta) { - pthread_mutex_lock(<t_traceable_app_list_mutex); cds_list_add(<a->list, <t_traceable_app_list.head); - traceable_app_count++; - pthread_mutex_unlock(<t_traceable_app_list_mutex); + ltt_traceable_app_list.count++; } /* - * del_traceable_app - * - * Delete a traceable application structure from the - * global list protected by a mutex. + * Delete a traceable application structure from the global list. */ static void del_traceable_app(struct ltt_traceable_app *lta) { - pthread_mutex_lock(<t_traceable_app_list_mutex); cds_list_del(<a->list); /* Sanity check */ - if (traceable_app_count != 0) { - traceable_app_count--; + if (ltt_traceable_app_list.count > 0) { + ltt_traceable_app_list.count--; } - pthread_mutex_unlock(<t_traceable_app_list_mutex); } /* - * register_traceable_app - * - * Using pid and uid (of the app), allocate - * a new ltt_traceable_app struct and add it - * to the global traceable app list. + * Return pointer to traceable apps list. + */ +struct ltt_traceable_app_list *get_traceable_apps_list(void) +{ + return <t_traceable_app_list; +} + +/* + * Acquire traceable apps list lock. + */ +void lock_apps_list(void) +{ + pthread_mutex_lock(<t_traceable_app_list.lock); +} + +/* + * Release traceable apps list lock. + */ +void unlock_apps_list(void) +{ + pthread_mutex_unlock(<t_traceable_app_list.lock); +} + +/* + * Iterate over the traceable apps list and return a pointer or NULL if not + * found. + */ +static struct ltt_traceable_app *find_app_by_sock(int sock) +{ + struct ltt_traceable_app *iter; + + cds_list_for_each_entry(iter, <t_traceable_app_list.head, list) { + if (iter->sock == sock) { + /* Found */ + return iter; + } + } + + return NULL; +} + +/* + * Using pid and uid (of the app), allocate a new ltt_traceable_app struct and + * add it to the global traceable app list. * - * On success, return 0, else return malloc ENOMEM. + * On success, return 0, else return malloc ENOMEM. */ -int register_traceable_app(pid_t pid, uid_t uid) +int register_traceable_app(struct ust_register_msg *msg, int sock) { struct ltt_traceable_app *lta; @@ -91,83 +114,76 @@ int register_traceable_app(pid_t pid, uid_t uid) return -ENOMEM; } - lta->uid = uid; - lta->pid = pid; + lta->uid = msg->uid; + lta->gid = msg->gid; + lta->pid = msg->pid; + lta->ppid = msg->ppid; + lta->v_major = msg->major; + lta->v_minor = msg->minor; + lta->sock = sock; + strncpy(lta->name, msg->name, sizeof(lta->name)); + lta->name[16] = '\0'; + + lock_apps_list(); add_traceable_app(lta); - DBG("Application %d registered with UID %d", pid, uid); + unlock_apps_list(); + + DBG("App registered with pid:%d ppid:%d uid:%d gid:%d sock:%d name:%s" + " (version %d.%d)", lta->pid, lta->ppid, lta->uid, lta->gid, + lta->sock, lta->name, lta->v_major, lta->v_minor); return 0; } /* - * unregister_traceable_app + * Unregister app by removing it from the global traceable app list and freeing + * the data struct. * - * Unregister app by removing it from the global - * traceable app list and freeing the data struct. + * The socket is already closed at this point so no close to sock. */ -void unregister_traceable_app(pid_t pid) +void unregister_traceable_app(int sock) { struct ltt_traceable_app *lta; - lta = find_app_by_pid(pid); - if (lta != NULL) { + lock_apps_list(); + lta = find_app_by_sock(sock); + if (lta) { + DBG("PID %d unregistered with sock %d", lta->pid, sock); + close(lta->sock); del_traceable_app(lta); + unlock_apps_list(); free(lta); - DBG("PID %d unregistered", pid); } + unlock_apps_list(); } /* - * get_app_count - * - * Return traceable_app_count + * Return traceable_app_count */ unsigned int get_app_count(void) { - return traceable_app_count; -} + unsigned int count; -/* - * find_app_by_pid - * - * Iterate over the traceable apps list and - * return a pointer or NULL if not found. - */ -struct ltt_traceable_app *find_app_by_pid(pid_t pid) -{ - struct ltt_traceable_app *iter; + lock_apps_list(); + count = ltt_traceable_app_list.count; + unlock_apps_list(); - pthread_mutex_lock(<t_traceable_app_list_mutex); - cds_list_for_each_entry(iter, <t_traceable_app_list.head, list) { - if (iter->pid == pid) { - pthread_mutex_unlock(<t_traceable_app_list_mutex); - /* Found */ - return iter; - } - } - pthread_mutex_unlock(<t_traceable_app_list_mutex); - - return NULL; + return count; } /* - * get_app_list_pids - * - * List traceable user-space application and fill an - * array of pids. + * Free and clean all traceable apps of the global list. */ -void get_app_list_pids(pid_t *pids) +void clean_traceable_apps_list(void) { - int i = 0; - struct ltt_traceable_app *iter; + struct ltt_traceable_app *iter, *tmp; - /* Protected by a mutex here because the threads manage_client - * and manage_apps can access this list. + /* + * Don't acquire list lock here. This function should be called from + * cleanup() functions meaning that the program will exit. */ - pthread_mutex_lock(<t_traceable_app_list_mutex); - cds_list_for_each_entry(iter, <t_traceable_app_list.head, list) { - pids[i] = iter->pid; - i++; + cds_list_for_each_entry_safe(iter, tmp, <t_traceable_app_list.head, list) { + close(iter->sock); + free(iter); } - pthread_mutex_unlock(<t_traceable_app_list_mutex); } diff --git a/ltt-sessiond/traceable-app.h b/ltt-sessiond/traceable-app.h index 364e70598..4d5e56a66 100644 --- a/ltt-sessiond/traceable-app.h +++ b/ltt-sessiond/traceable-app.h @@ -19,25 +19,67 @@ #ifndef _TRACEABLE_APP_H #define _TRACEABLE_APP_H -/* Traceable application list */ +#include +#include + +/* + * Application registration data structure. + */ +struct ust_register_msg { + uint32_t major; + uint32_t minor; + pid_t pid; + pid_t ppid; + uid_t uid; + gid_t gid; + char name[16]; +}; + +/* + * Traceable application list. + */ struct ltt_traceable_app_list { + /* + * This lock protects any read/write access to the list and count (which is + * basically the list size). All public functions in traceable-app.c + * acquire this lock and release it before returning. If none of those + * functions are used, the lock MUST be acquired in order to iterate or/and + * do any actions on that list. + */ + pthread_mutex_t lock; + + /* + * Number of element in the list. The session list lock MUST be acquired if + * this counter is used when iterating over the session list. + */ + unsigned int count; + + /* Linked list head */ struct cds_list_head head; }; -/* Registered traceable applications. Libust registers - * to the session daemon and a linked list is kept - * of all running traceable app. +/* Registered traceable applications. Libust registers to the session daemon + * and a linked list is kept of all running traceable app. */ struct ltt_traceable_app { - struct cds_list_head list; + int sock; /* Communication socket with the application */ pid_t pid; - uid_t uid; /* User ID that owns the apps */ + pid_t ppid; + uid_t uid; /* User ID that owns the apps */ + gid_t gid; /* Group ID that owns the apps */ + uint32_t v_major; /* Verion major number */ + uint32_t v_minor; /* Verion minor number */ + char name[17]; /* Process name (short) */ + struct cds_list_head list; }; -struct ltt_traceable_app *find_app_by_pid(pid_t pid); -int register_traceable_app(pid_t pid, uid_t uid); -void unregister_traceable_app(pid_t pid); -void get_app_list_pids(pid_t *pids); +int register_traceable_app(struct ust_register_msg *msg, int sock); +void unregister_traceable_app(int sock); unsigned int get_app_count(void); +void lock_apps_list(void); +void unlock_apps_list(void); +void clean_traceable_apps_list(void); +struct ltt_traceable_app_list *get_traceable_apps_list(void); + #endif /* _TRACEABLE_APP_H */ diff --git a/ltt-sessiond/ust-comm.c b/ltt-sessiond/ust-comm.c new file mode 100644 index 000000000..accd4276d --- /dev/null +++ b/ltt-sessiond/ust-comm.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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. + */ + +#include + +#include "ust-comm.h" + +/* + * Send msg containing a command to an UST application via sock and wait for + * the reply. + * + * Return -1 on error or if reply fails else return 0. + */ +int ustcomm_send_command(int sock, struct lttcomm_ust_msg *msg) +{ + ssize_t len; + struct lttcomm_ust_reply reply; + + DBG("Sending UST command %d to sock %d", msg->cmd, sock); + + /* Send UST msg */ + len = lttcomm_send_unix_sock(sock, msg, sizeof(*msg)); + if (len < 0) { + goto error; + } + + DBG("Receiving UST reply on sock %d", sock); + + /* Get UST reply */ + len = lttcomm_recv_unix_sock(sock, &reply, sizeof(reply)); + if (len < 0) { + goto error; + } + + if (reply.ret_code != LTTCOMM_OK) { + goto error; + } + + return 0; + +error: + return -1; +} diff --git a/ltt-sessiond/ust-comm.h b/ltt-sessiond/ust-comm.h new file mode 100644 index 000000000..8a04f85a5 --- /dev/null +++ b/ltt-sessiond/ust-comm.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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 _LTT_UST_COMM_H +#define _LTT_UST_COMM_H + +#include + +int ustcomm_send_command(int sock, struct lttcomm_ust_msg *msg); + +#endif /* _LTT_UST_COMM_H */ diff --git a/ltt-sessiond/ust-ctl.h b/ltt-sessiond/ust-ctl.h index b864c0802..6ec5fbdc4 100644 --- a/ltt-sessiond/ust-ctl.h +++ b/ltt-sessiond/ust-ctl.h @@ -19,15 +19,4 @@ #ifndef _LTT_UST_CTL_H #define _LTT_UST_CTL_H -#include "session.h" -#include "trace.h" - -/* -int get_trace_count_per_session(struct ltt_session *session); -void get_traces_per_session(struct ltt_session *session, struct lttng_trace *traces); -int ust_create_trace(struct command_ctx *cmd_ctx); -int ust_start_trace(struct command_ctx *cmd_ctx); -int ust_stop_trace(struct command_ctx *cmd_ctx); -*/ - -#endif /* _LTT_TRACE_H */ +#endif /* _LTT_UST_CTL_H */ diff --git a/ltt-sessiond/utils.c b/ltt-sessiond/utils.c index 5b8e31b8d..91972e9a8 100644 --- a/ltt-sessiond/utils.c +++ b/ltt-sessiond/utils.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 - David Goulet - * Copyright (C) 2011 - Mathieu Desnoyers + * Mathieu Desnoyers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,10 +30,9 @@ #include "utils.h" /* - * get_home_dir + * Return pointer to home directory path using the env variable HOME. * - * Return pointer to home directory path using the env variable HOME. - * No home, NULL is returned. + * No home, NULL is returned. */ const char *get_home_dir(void) { @@ -41,9 +40,7 @@ const char *get_home_dir(void) } /* - * mkdir_recursive - * - * Create recursively directory using the FULL path. + * Create recursively directory using the FULL path. */ int mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) { @@ -76,9 +73,8 @@ int mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) } } else if (ret == 0) { /* - * We created the directory. Set its - * ownership to the user/group - * specified. + * We created the directory. Set its ownership to the + * user/group specified. */ ret = chown(tmp, uid, gid); if (ret < 0) { @@ -96,8 +92,8 @@ int mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) ret = -errno; } else if (ret == 0) { /* - * We created the directory. Set its ownership to the - * user/group specified. + * We created the directory. Set its ownership to the user/group + * specified. */ ret = chown(tmp, uid, gid); if (ret < 0) { diff --git a/ltt-sessiond/utils.h b/ltt-sessiond/utils.h index 41aad2557..4da5f498e 100644 --- a/ltt-sessiond/utils.h +++ b/ltt-sessiond/utils.h @@ -5,25 +5,24 @@ * Copyright (C) 2011 - David Goulet * Copyright (C) 2011 - Mathieu Desnoyers * - * 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 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. + * 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. + * 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 #ifndef ARRAY_SIZE -#define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0]))) +#define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0]))) #endif int mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid); diff --git a/lttng/Makefile.am b/lttng/Makefile.am index 8dc68e45b..1105143f3 100644 --- a/lttng/Makefile.am +++ b/lttng/Makefile.am @@ -1,4 +1,5 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -DINSTALL_BIN_PATH=\""$(bindir)"\" +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -DINSTALL_BIN_PATH=\""$(bindir)"\" bin_PROGRAMS = lttng diff --git a/tests/Makefile.am b/tests/Makefile.am index a10390614..06a1f23ce 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,7 +8,7 @@ noinst_PROGRAMS = test_sessions test_kernel_data_trace kernel_all_events_basic \ UTILS=utils.h SESSIONS=$(top_srcdir)/ltt-sessiond/session.c -KERN_DATA_TRACE=$(top_srcdir)/ltt-sessiond/trace.c +KERN_DATA_TRACE=$(top_srcdir)/ltt-sessiond/trace-kernel.c LIBLTTNG=$(top_srcdir)/liblttngctl/lttngctl.c \ $(top_srcdir)/liblttng-sessiond-comm/lttng-sessiond-comm.c diff --git a/tests/test_kernel_data_trace.c b/tests/test_kernel_data_trace.c index 2892ab236..e46d90186 100644 --- a/tests/test_kernel_data_trace.c +++ b/tests/test_kernel_data_trace.c @@ -25,7 +25,7 @@ #include #include -#include "ltt-sessiond/trace.h" +#include "ltt-sessiond/trace-kernel.h" #include "utils.h" /* This path will NEVER be created in this test */ @@ -62,7 +62,7 @@ static char *get_random_string(void) static void create_one_kernel_session(void) { printf("Create kernel session: "); - kern = trace_create_kernel_session(); + kern = trace_kernel_create_session(PATH1); assert(kern != NULL); PRINT_OK(); @@ -77,7 +77,7 @@ static void create_one_kernel_session(void) PRINT_OK(); /* Init list in order to avoid sefaults from cds_list_del */ - trace_destroy_kernel_session(kern); + trace_kernel_destroy_session(kern); } static void create_kernel_metadata(void) @@ -85,7 +85,7 @@ static void create_kernel_metadata(void) assert(kern != NULL); printf("Create kernel metadata: "); - kern->metadata = trace_create_kernel_metadata(PATH1); + kern->metadata = trace_kernel_create_metadata(PATH1); assert(kern->metadata != NULL); PRINT_OK(); @@ -107,7 +107,7 @@ static void create_kernel_metadata(void) == DEFAULT_KERNEL_CHANNEL_OUTPUT); PRINT_OK(); - trace_destroy_kernel_metadata(kern->metadata); + trace_kernel_destroy_metadata(kern->metadata); } static void create_kernel_channel(void) @@ -116,7 +116,7 @@ static void create_kernel_channel(void) struct lttng_channel attr; printf("Creating kernel channel: "); - chan = trace_create_kernel_channel(&attr, PATH1); + chan = trace_kernel_create_channel(&attr, PATH1); assert(chan != NULL); PRINT_OK(); @@ -131,7 +131,7 @@ static void create_kernel_channel(void) /* Init list in order to avoid sefaults from cds_list_del */ CDS_INIT_LIST_HEAD(&chan->list); - trace_destroy_kernel_channel(chan); + trace_kernel_destroy_channel(chan); } static void create_kernel_event(void) @@ -143,7 +143,7 @@ static void create_kernel_event(void) ev.type = LTTNG_EVENT_TRACEPOINT; printf("Creating kernel event: "); - event = trace_create_kernel_event(&ev); + event = trace_kernel_create_event(&ev); assert(event != NULL); PRINT_OK(); @@ -157,7 +157,7 @@ static void create_kernel_event(void) /* Init list in order to avoid sefaults from cds_list_del */ CDS_INIT_LIST_HEAD(&event->list); - trace_destroy_kernel_event(event); + trace_kernel_destroy_event(event); } static void create_kernel_stream(void) @@ -165,7 +165,7 @@ static void create_kernel_stream(void) struct ltt_kernel_stream *stream; printf("Creating kernel stream: "); - stream = trace_create_kernel_stream(); + stream = trace_kernel_create_stream(); assert(stream != NULL); PRINT_OK(); @@ -177,7 +177,7 @@ static void create_kernel_stream(void) /* Init list in order to avoid sefaults from cds_list_del */ CDS_INIT_LIST_HEAD(&stream->list); - trace_destroy_kernel_stream(stream); + trace_kernel_destroy_stream(stream); } int main(int argc, char **argv)