+2012-03-20 lttng-tools 2.0.0
+ * Fist STABLE version
+ * Add version name: Annedd'ale
+
+2012-03-20 lttng-tools 2.0.0-rc4
+ * Fix: add small detail to enable-channel man page
+ * Fix: warned of arbitrary time for ust-nprocesses test
+ * Fix. add limitation to man page
+ * Fix: minor changes to lttng.1
+ * Fix: add exit values to lttng.1 man page
+ * Fix: add delay before validating apps in test nproc
+ * Fix: error handling in lttng enable-event
+ * Fix: document structure init. to 0 in lttng.h
+ * Fix: uninitialized variable
+ * Keep track of FD used for UST applications (v2)
+ * Fix: lttng view, error message and exit code
+ * Small fixes to lttng man pages (v2)
+ * Fix: handle EINTR for sendmsg syscall
+ * Fix: lttng UI exit value and error message
+ * Fix: session lock use after free
+ * Fix kernel_list_events memleaks
+ * Fix debug message use uninitialized variable
+ * Fix: trace_ust_destroy_metadata should check for NULL pointer
+ * Fix: various memleaks
+ * Fix: hash table allocation out of order on error
+ * fix: lttng_ht_destroy memleak
+
+2012-03-16 lttng-tools 2.0.0-rc3
+ * Fix: missing headers for make dist
+ * Fix: install lttng-consumerd in lib/lttng/libexec/
+ * Fix: Redefine MAP_STACK to 0 if not defined by the architecture
+ * Fix: consumer CPU hotplug support
+ * Fix: double PID registration race
+ * Make libcompat independent not to confuse automake
+ * Clarify the license of lttng-ust-abi.h
+ * Fix: License header
+ * Fix: wrong return value on consumer socket creation
+ * Fix: test for UST invalid channel parameters at channel creation
+ * Fix: recvmsg should handle EINTR
+ * Fix: error.h non-static variables for liblttng-ctl
+ * Fix: missing _GNU_SOURCE define
+ * Fix: improve need root for kernel tracing error message
+ * Fix: start/stop lttng message error
+
+2012-03-02 lttng-tools 2.0.0-rc2
+ * Fix: meaningful error message
+ * Fix: UST consumer need to iterate on streams, just change their key
+ * Fix: add missing rcu read lock across RCU HT iteration
+ * Fix: kernel session closes fd 0 after create
+ * Fix: sendmsg EPIPE should be quiet by default (expected)
+ * Fix: thread_registration_apps should set its local sock to -1 when passing it
+ * Fix: clock -> sock typo
+ * Fix: consumer race: should allow reuse of FD key
+ * Fix: Use PERROR all across lttng-tools, never make it quiet
+ * Fix: test all close return values in sessiond
+ * Fix: All perror turned into PERROR to show file and line number
+ * Fix: large audit of close() use in sessiond main.c
+ * Fix: main.c client/apps sockets and kernel_trace_fd close(0)
+ * Fix: incorrect close of fd 0 for syscall kernel event destroy
+ * Fix: sessiond has incorrect missing 0 value in FD check
+ * Fix: sessiond app listening: use posix-compliant poll flags
+ * Fix: consumer printf type should match ssize_t (%zd)
+ * Fix: make ust consumer posix compliant for poll flags
+ * Fix security permission on lttng run directory
+ * Fix: Display right loglevel_type in error message
+ * Fix documentation in lttng.h
+ * Fix: lttng UST and kernel consumer: fix ret vs errno mixup
+ * Fix: restart consumerd and sessiond when interrupted in poll()
+ * Fix: handling bad channel when sending to consumer
+ * Fix useless variable
+ * Fix add-context returned error
+ * fix: add missing break in command handling
+ * fix: command handling: do not check domain for commands not requiring domain
+ * fix: if tracing group does not exist, do not report a client error
+ * Fix: run_as error handling
+ * Fix usage note on -a
+ * Revert FreeBSD compatibility layer
+ * Fix: documented number of subbuffers is incorrect
+ * Document that num-subbuf and subbuf-size need to be power of 2
+ * Merge branch 'master' of git://git.lttng.org/lttng-tools
+
2012-02-20 lttng-tools 2.0.0-rc1
* Fix lttcomm_close_unix_sock to actually close the socket
* lttng-sessiond: Set group permissions explicitly
The library part is distributed under LGPLv2.1. See lgpl-2.1.txt for details.
This applies to:
--) lttng.h
--) liblttngctl.c
+-) include/lttng/lttng.h
+-) src/lib/lttng-ctl/lttng-ctl.c
LGPL-compatible source code can statically use the library header using:
-AC_INIT([lttng-tools],[2.0.0-rc1],[dgoulet@efficios.com],[],[http://lttng.org])
+AC_INIT([lttng-tools],[2.0.0],[dgoulet@efficios.com],[],[http://lttng.org])
AC_CONFIG_AUX_DIR([config])
AC_CANONICAL_TARGET
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+version_name="Annedd'ale"
+version_description="New type of beer, 100% from Quebec, flavored with sapin beaumier needles, with a touch of hops."
+
+AC_DEFINE_UNQUOTED([VERSION_NAME], ["$version_name"], "")
+AC_DEFINE_UNQUOTED([VERSION_DESCRIPTION], ["$version_description"], "")
+
AC_CONFIG_HEADERS([include/config.h])
AC_CHECK_HEADERS([ \
AC_CHECK_FUNCS([sched_getcpu sysconf])
+# check for dlopen
+AC_CHECK_LIB([dl], [dlopen],
+[
+ have_libdl=yes
+],
+[
+ #libdl not found, check for dlopen in libc.
+ AC_CHECK_LIB([c], [dlopen],
+ [
+ have_libc_dl=yes
+ ],
+ [
+ AC_MSG_ERROR([Cannot find dlopen in libdl nor libc. Use [LDFLAGS]=-Ldir to specify their location.])
+ ])
+])
+AM_CONDITIONAL([LTTNG_TOOLS_BUILD_WITH_LIBDL], [test "x$have_libdl" = "xyes"])
+AM_CONDITIONAL([LTTNG_TOOLS_BUILD_WITH_LIBC_DL], [test "x$have_libc_dl" = "xyes"])
+
# Option to only build the consumer daemon and its libraries
AC_ARG_WITH([consumerd-only],
AS_HELP_STRING([--with-consumerd-only],[Only build the consumer daemon [default=no]]),
AC_SUBST(lttngincludedir)
AC_SUBST(DEFAULT_INCLUDES)
+lttnglibexecdir="${libdir}/lttng/libexec"
+AC_SUBST(lttnglibexecdir)
+
AC_CONFIG_FILES([
Makefile
doc/Makefile
src/common/ust-consumer/Makefile
src/common/hashtable/Makefile
src/common/sessiond-comm/Makefile
+ src/common/compat/Makefile
src/lib/Makefile
src/lib/lttng-ctl/Makefile
src/bin/Makefile
#
AS_ECHO()
+AS_ECHO("Version name: $version_name")
+AS_ECHO("$version_description")
+
+AS_ECHO()
+
# Target architecture we're building for
target_arch=$host_cpu
[
AS_ECHO("The sessiond daemon will look in the following directories: ")
AS_ECHO_N("32-bit consumerd executable at: ")
AS_IF([test "$CONSUMERD32_BIN" = ""],[
- AS_ECHO_N("`eval eval echo $bindir`")
+ AS_ECHO_N("`eval eval echo $lttnglibexecdir`")
AS_ECHO("/lttng-consumerd")
],[
AS_ECHO("$CONSUMERD32_BIN")
AS_ECHO_N("64-bit consumerd executable at: ")
AS_IF([test "$CONSUMERD64_BIN" = ""],[
- AS_ECHO_N("`eval eval echo $bindir`")
+ AS_ECHO_N("`eval eval echo $lttnglibexecdir`")
AS_ECHO("/lttng-consumerd")
],[
AS_ECHO("$CONSUMERD64_BIN")
involving multiple concurrent processes and threads. Tracing across multiple
systems is also possible.
-The session daemon, acting as a tracing registry, allow you to interact with
+The session daemon, acting as a tracing registry, allow you to interact with
multiple tracers (kernel and user-space) inside the same container, a tracing
session. Trace can be gathered from the kernel and/or instrumented applications
-(lttng-ust(3)). Aggregating those traces is done using the babeltrace(1) text
-viewer.
+(lttng-ust(3)). Aggregating those traces is done using a viewer, like the
+babeltrace(1) text viewer.
In order to trace the kernel, the session daemon needs to be running as root.
LTTng provides the use of a \fBtracing group\fP (default: tracing). Whomever is
in that group can interact with the root session daemon and thus trace the
kernel. Session daemons can co-exist meaning that you can have a session daemon
-running as Alice that can be use to trace her applications along side with a
-root daemon or even a Bob daemon. We highly recommand to start the session
+running as Alice that can be used to trace her applications along side with a
+root daemon or even a Bob daemon. We highly recommend to start the session
daemon at boot time for stable and long term tracing.
The session daemon is in charge of managing trace data consumers by spawning
-one when the time as come. The user don't need to manage the lttng-consumerd.
+them when the time has come. The user don't need to manage the lttng-consumerd.
.SH "OPTIONS"
.PP
Send SIGCHLD to parent pid to notify readiness.
This is used by \fBlttng(1)\fP to get notified when the session daemon is ready
-to accept command. By building a third part tool over liblttng-ctl, this option
+to accept command. When building a third party tool over liblttng-ctl, this option
can be very handy to synchronize the control tool and the session daemon.
.TP
.BR "-q, --quiet"
.SH "ENVIRONMENT VARIABLES"
.PP
-Note that all command line options will override environmenal variables.
+Note that all command line options will override environment variables.
.PP
.PP
.IP "LTTNG_CONSUMERD32_BIN"
-Allow to specify the 32-bit consumer binary path. \fB--consumerd32-path\fP
+Specify the 32-bit consumer binary path. \fB--consumerd32-path\fP
override this variable.
.IP "LTTNG_CONSUMERD64_BIN"
-Allow to specify the 64-bit consumer binary path. \fB--consumerd64-path\fP
+Specify the 64-bit consumer binary path. \fB--consumerd64-path\fP
override this variable.
.IP "LTTNG_CONSUMERD32_LIBDIR"
-Allow to specifiy the 64-bit library path containing libconsumer.so.
+Specifiy the 64-bit library path containing libconsumer.so.
\fB--consumerd32-libdir\fP override this variable.
.IP "LTTNG_CONSUMERD64_LIBDIR"
-Allow to specifiy the 32-bit library path containing libconsumer.so.
+Specifiy the 32-bit library path containing libconsumer.so.
\fB--consumerd64-libdir\fP override this variable.
+.IP "LTTNG_DEBUG_NOCLONE"
+Debug-mode disabling use of clone/fork. Insecure, but required to allow
+debuggers to work with sessiond on some operating systems.
.SH "SEE ALSO"
.PP
babeltrace(1), lttng-ust(3), lttng(1)
.PP
+
+.SH "LIMITATIONS"
+
+.PP
+For unprivileged user running lttng-sessiond, the maximum number of file
+descriptors per process is usually 1024. This limits the number of traceable
+applications since for each instrumented application there is two file
+descriptors per-CPU and one more socktet for bidirectional communication.
+
+For the root user, the limit is bumped to 65535. Future version will deal with
+this limitation.
+.PP
+
.SH "BUGS"
.PP
-No show stopper bugs known yet at this stable version.
+No show stopper bugs are known yet in this version.
If you encounter any issues or usability problem, please report it on our
mailing list <lttng-dev@lists.lttng.org> to help improve this project.
.PP
Thanks to Yannick Brosseau without whom this project would never have been so
-lean and mean! Also thanks to the Ericsson teams working on tracing which help
-us greatly with detailled bug reports and unsual use cases.
+lean and mean! Also thanks to the Ericsson teams working on tracing which helped
+us greatly with detailed bug reports and unusual test cases.
Thanks to our beloved packager Alexandre Montplaisir-Goncalves (Ubuntu and PPA
maintainer) and Jon Bernard for our Debian packages.
involving multiple concurrent processes and threads. Tracing across multiple
systems is also possible.
-The \fBlttng\fP command line tool from lttng-tools package is used to control
+The \fBlttng\fP command line tool from the lttng-tools package is used to control
both kernel and user-space tracing. Every interactions with the tracer should
be done by this tool or by the liblttng-ctl provided with the lttng-tools
package.
LTTng provides the use of a \fBtracing group\fP (default: tracing). Whomever is
in that group can interact with the root session daemon and thus trace the
kernel. Session daemons can co-exist meaning that you can have a session daemon
-running as Alice that can be use to trace her applications along side with a
-root daemon or even a Bob daemon. We highly recommand to start the session
+running as Alice that can be used to trace her applications along side with a
+root daemon or even a Bob daemon. We highly recommend to start the session
daemon at boot time for stable and long term tracing.
Every user-space applications instrumented with lttng-ust(3), will
.TP
.BR "\-v, \-\-verbose"
Increase verbosity.
-FIXME : details (\-v : sessiond verbose, \-vv : consumerd verbose, etc) ?
+Three levels of verbosity are available which are triggered by putting additional v to
+the option (\-vv or \-vvv)
.TP
.BR "\-q, \-\-quiet"
Suppress all messages (even errors).
On creation, a \fB.lttngrc\fP file is created in your $HOME directory
containing the current session name. If NAME is omitted, a session name is
-automatically created having this form: 'auto-yyyymmdd-hhmms'.
+automatically created having this form: 'auto-yyyymmdd-hhmmss'.
If no \fB\-o, \-\-output\fP is specified, the traces will be written in
$HOME/lttng-traces.
.nf
Enable tracing channel
+To enable event, you must first enable a channel which contains event(s).
+
If \fB\-s, \-\-session\fP is omitted, the session name is taken from the .lttngrc
file.
.fi
\-\-subbuf-size
Subbuffer size in bytes (default: 4096, kernel default: 262144)
\-\-num-subbuf
- Number of subbufers (default: 4)
+ Number of subbuffers (default: 4)
Needs to be a power of 2 for kernel and ust tracers
\-\-switch-timer
Switch subbuffer timer interval in usec (default: 0)
With no arguments, it will list available tracing session(s).
+With the session name, it will display the details of the session including
+the trace file path, the associated channels and their state (activated
+and deactivated), the activated events and more.
+
With \-k alone, it will list all available kernel events (except the system
calls events).
With \-u alone, it will list all available user-space events from registered
\-\-list-options
Simple listing of options
\-k, \-\-kernel
- Select kernel domain (FIXME : apparition de la notion de "domain" ici)
+ Select kernel domain
\-u, \-\-userspace
Select user-space domain.
By default, the babeltrace viewer will be used for text viewing.
-The SESSION_NAME is an optional session name. If not specified, lttng will get
-it from the configuration file (.lttngrc).
+If SESSION_NAME is omitted, the session name is taken from the .lttngrc file.
+
.fi
.B OPTIONS:
to the arguments
.fi
+.SH "EXIT VALUES"
+
+.IP "0"
+Success
+
+.IP "1"
+Command error
+
+.IP "2"
+Undefined command
+
+.IP "3"
+Fatal error
+
+.IP "4"
+Command warning
+
+.IP "16"
+No session found by the name given
+
+.IP "18"
+Error in session creation
+
+.IP "21"
+Error in application(s) listing
+
+.IP "28"
+Session name already exists
+
+.IP "33"
+Kernel tracer unavailable
+
+.IP "35"
+Kernel event exists
+
+.IP "37"
+Kernel channel exists
+
+.IP "38"
+Kernel channel creation failed
+
+.IP "39"
+Kernel channel not found
+
+.IP "40"
+Kernel channel disable failed
+
+.IP "41"
+Kernel channel enable failed
+
+.IP "42"
+Kernel context failed
+
+.IP "43"
+Kernel enable event failed
+
+.IP "44"
+Kernel disable event failed
+
+.IP "53"
+Kernel listing events failed
+
+.IP "60"
+UST channel disable failed
+
+.IP "61"
+UST channel enable failed
+
+.IP "62"
+UST adding context failed
+
+.IP "63"
+UST event enable failed
+
+.IP "64"
+UST event disable failed
+
+.IP "66"
+UST start failed
+
+.IP "67"
+UST stop failed
+
+.IP "75"
+UST event exists
+
+.IP "76"
+UST event not found
+
+.IP "77"
+UST context exists
+
+.IP "78"
+UST invalid context
+
+.IP "79"
+Tracing the kernel requires a root lttng-sessiond daemon and "tracing" group
+user membership.
+
+.IP "80"
+Tracing already started
+
+.IP "81"
+Tracing already stopped
+.PP
.SH "ENVIRONMENT VARIABLES"
.PP
.SH "BUGS"
.PP
-No show stopper bugs known yet at this stable version.
+No show stopper bugs are known yet in this version.
If you encounter any issues or usability problem, please report it on our
mailing list <lttng-dev@lists.lttng.org> to help improve this project.
.PP
Thanks to Yannick Brosseau without whom this project would never have been so
lean and mean! Also thanks to the Ericsson teams working on tracing which
-helped us greatly with detailled bug reports and unusual test cases.
+helped us greatly with detailed bug reports and unusual test cases.
Thanks to our beloved packager Alexandre Montplaisir-Goncalves (Ubuntu and PPA
maintainer) and Jon Bernard for our Debian packages.
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
* This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation; only version 2.1 of the License.
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
LTTNG_CALIBRATE_FUNCTION = 0,
};
+/*
+ * The structures should be initialized to zero before use.
+ */
#define LTTNG_DOMAIN_PADDING1 16
#define LTTNG_DOMAIN_PADDING2 LTTNG_SYMBOL_NAME_LEN + 32
struct lttng_domain {
} attr;
};
-/* Perf counter attributes */
+/*
+ * Perf counter attributes
+ *
+ * The structures should be initialized to zero before use.
+ */
#define LTTNG_PERF_EVENT_PADDING1 16
struct lttng_event_perf_counter_ctx {
uint32_t type;
char padding[LTTNG_PERF_EVENT_PADDING1];
};
-/* Event/Channel context */
+/*
+ * Event/channel context
+ *
+ * The structures should be initialized to zero before use.
+ */
#define LTTNG_EVENT_CONTEXT_PADDING1 16
#define LTTNG_EVENT_CONTEXT_PADDING2 LTTNG_SYMBOL_NAME_LEN + 32
struct lttng_event_context {
* Event probe.
*
* Either addr is used or symbol_name and offset.
+ *
+ * The structures should be initialized to zero before use.
*/
#define LTTNG_EVENT_PROBE_PADDING1 16
struct lttng_event_probe_attr {
/*
* Function tracer
+ *
+ * The structures should be initialized to zero before use.
*/
#define LTTNG_EVENT_FUNCTION_PADDING1 16
struct lttng_event_function_attr {
/*
* Generic lttng event
+ *
+ * The structures should be initialized to zero before use.
*/
#define LTTNG_EVENT_PADDING1 16
#define LTTNG_EVENT_PADDING2 LTTNG_SYMBOL_NAME_LEN + 32
/*
* Tracer channel attributes. For both kernel and user-space.
+ *
+ * The structures should be initialized to zero before use.
*/
#define LTTNG_CHANNEL_ATTR_PADDING1 LTTNG_SYMBOL_NAME_LEN + 32
struct lttng_channel_attr {
/*
* Channel information structure. For both kernel and user-space.
+ *
+ * The structures should be initialized to zero before use.
*/
#define LTTNG_CHANNEL_PADDING1 16
struct lttng_channel {
* This is an 'output data' meaning that it only comes *from* the session
* daemon *to* the lttng client. It's basically a 'human' representation of
* tracing entities (here a session).
+ *
+ * The structures should be initialized to zero before use.
*/
#define LTTNG_SESSION_PADDING1 16
struct lttng_session {
/*
* Handle used as a context for commands.
+ *
+ * The structures should be initialized to zero before use.
*/
#define LTTNG_HANDLE_PADDING1 16
struct lttng_handle {
const char *channel_name);
/*
- * Create or enable a kernel event (or events) for a channel.
+ * Create or enable an event (or events) for a channel.
*
* If the event you are trying to enable does not exist, it will be created,
* else it is enabled.
struct lttng_event *ev, const char *channel_name);
/*
- * Create or enable a kernel channel.
+ * Create or enable a channel.
* The channel name cannot be NULL.
*/
extern int lttng_enable_channel(struct lttng_handle *handle,
struct lttng_channel *chan);
/*
- * Disable kernel event(s) of a channel and domain.
+ * Disable event(s) of a channel and domain.
*
* If event_name is NULL, all events are disabled.
* If channel_name is NULL, the default channel is used (channel0).
const char *name, const char *channel_name);
/*
- * Disable kernel channel.
+ * Disable channel.
*
* The channel name cannot be NULL.
*/
AM_CPPFLAGS =
-bin_PROGRAMS = lttng-consumerd
+lttnglibexec_PROGRAMS = lttng-consumerd
lttng_consumerd_SOURCES = lttng-consumerd.c lttng-consumerd.h
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
static int sigintcount = 0;
/* Argument variables */
-int opt_quiet;
-int opt_verbose;
+int lttng_opt_quiet; /* not static in error.h */
+int lttng_opt_verbose; /* not static in error.h */
static int opt_daemon;
static const char *progname;
static char command_sock_path[PATH_MAX]; /* Global command socket path */
usage(stdout);
exit(EXIT_SUCCESS);
case 'q':
- opt_quiet = 1;
+ lttng_opt_quiet = 1;
break;
case 'v':
- opt_verbose = 1;
+ lttng_opt_verbose = 1;
break;
case 'V':
fprintf(stdout, "%s\n", VERSION);
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only verion 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_CONSUMERD_H
+<<<<<<< HEAD
AM_CPPFLAGS = -I$(top_srcdir)/benchmark \
- -DINSTALL_BIN_PATH=\""$(bindir)"\" \
+ -DINSTALL_BIN_PATH=\""$(lttnglibexecdir)"\" \
-DINSTALL_LIB_PATH=\""$(libdir)"\"
AM_CFLAGS = -fno-strict-aliasing
shm.c shm.h \
session.c session.h \
modprobe.c modprobe.h kern-modules.h \
- lttng-ust-ctl.h lttng-ust-abi.h
+ lttng-ust-ctl.h lttng-ust-abi.h \
+ fd-limit.c fd-limit.h
if HAVE_LIBLTTNG_UST_CTL
lttng_sessiond_SOURCES += trace-ust.c ust-app.c ust-consumer.c ust-consumer.h
$(top_builddir)/src/common/kernel-ctl/libkernel-ctl.la \
$(top_builddir)/src/common/hashtable/libhashtable.la \
$(top_builddir)/src/common/libcommon.la \
- $(top_builddir)/benchmark/liblttng-benchmark.la \
- $(top_builddir)/src/common/libcompat.la
+ $(top_builddir)/src/common/compat/libcompat.la \
+ $(top_builddir)/benchmark/liblttng-benchmark.la
if HAVE_LIBLTTNG_UST_CTL
lttng_sessiond_LDADD += -llttng-ust-ctl
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
ret = LTTCOMM_KERN_CHAN_ENABLE_FAIL;
goto error;
}
+ } else {
+ ret = LTTCOMM_KERN_CHAN_EXIST;
+ goto error;
}
ret = LTTCOMM_OK;
/* If already enabled, everything is OK */
if (uchan->enabled) {
DBG3("Channel %s already enabled. Skipping", uchan->name);
+ ret = LTTCOMM_UST_CHAN_EXIST;
goto end;
}
attr = defattr;
}
+ /*
+ * Validate UST buffer size and number of buffers: must both be
+ * power of 2 and nonzero. We validate right here for UST,
+ * because applications will not report the error to the user
+ * (unlike kernel tracing).
+ */
+ if (!attr->attr.subbuf_size || (attr->attr.subbuf_size & (attr->attr.subbuf_size - 1))) {
+ ret = LTTCOMM_INVALID;
+ goto error;
+ }
+ if (!attr->attr.num_subbuf || (attr->attr.num_subbuf & (attr->attr.num_subbuf - 1))) {
+ ret = LTTCOMM_INVALID;
+ goto error;
+ }
+
/* Create UST channel */
uchan = trace_ust_create_channel(attr, usess->pathname);
if (uchan == NULL) {
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_CHANNEL_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
struct lttng_event_context *ctx, char *event_name,
char *channel_name)
{
- int ret = LTTCOMM_OK, have_event = 0, no_chan = 1;
+ int ret = LTTCOMM_OK, have_event = 0;
struct lttng_ht_iter iter;
struct lttng_ht *chan_ht;
struct ltt_ust_channel *uchan = NULL;
} else if (!uchan && !have_event) { /* Add ctx all events, all channels */
/* For all channels */
cds_lfht_for_each_entry(chan_ht->ht, &iter.iter, uchan, node.node) {
- no_chan = 0;
ret = add_uctx_to_channel(usess, domain, uchan, ctx);
if (ret < 0) {
ERR("Context failed for channel %s", uchan->name);
break;
}
- if (no_chan) {
- ret = LTTCOMM_UST_CHAN_NOT_FOUND;
- }
-
error:
return ret;
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_CONTEXT_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
ret = LTTCOMM_KERN_ENABLE_FAIL;
goto end;
}
+ } else {
+ /* At this point, the event is considered enabled */
+ ret = LTTCOMM_KERN_EVENT_EXIST;
+ goto end;
}
+
ret = LTTCOMM_OK;
end:
return ret;
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_EVENT_H
--- /dev/null
+/*
+ * Copyright (C) 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+#include <urcu/uatomic.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <errno.h>
+#include <stdio.h>
+#include "fd-limit.h"
+
+/* total count of fd. */
+static long fd_count;
+
+/*
+ * threshold in % of number of fd allowed.
+ */
+static long fd_threshold[LTTNG_FD_NR_TYPES] = {
+ [LTTNG_FD_APPS] = 75,
+};
+
+static rlim_t max_nr_fd;
+
+int lttng_fd_get(enum lttng_fd_type type, unsigned int nr)
+{
+ long newval;
+
+ if (type >= LTTNG_FD_NR_TYPES) {
+ return -EINVAL;
+ }
+
+ newval = uatomic_add_return(&fd_count, (long) nr);
+ if ((long) (newval * 100)
+ - (long) (max_nr_fd * fd_threshold[type]) > 0) {
+ uatomic_sub(&fd_count, (long) nr);
+ return -EPERM;
+ }
+ return 0;
+}
+
+void lttng_fd_put(enum lttng_fd_type type, unsigned int nr)
+{
+ uatomic_sub(&fd_count, (long) nr);
+}
+
+void lttng_fd_init(void)
+{
+ struct rlimit rlim;
+ int ret;
+
+ ret = getrlimit(RLIMIT_NOFILE, &rlim);
+ if (ret < 0) {
+ perror("getrlimit");
+ }
+ max_nr_fd = rlim.rlim_cur;
+}
--- /dev/null
+#ifndef _LTTNG_FD_LIMIT_H
+#define _LTTNG_FD_LIMIT_H
+
+/*
+ * Copyright (C) 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+enum lttng_fd_type {
+ LTTNG_FD_APPS,
+ LTTNG_FD_NR_TYPES,
+};
+
+int lttng_fd_get(enum lttng_fd_type type, unsigned int nr);
+void lttng_fd_put(enum lttng_fd_type type, unsigned int nr);
+void lttng_fd_init(void);
+
+#endif /* _LTTNG_FD_LIMIT_H */
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_FUTEX_H
/*
* Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _KERN_MODULES_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include <common/common.h>
#include <common/kernel-ctl/kernel-ctl.h>
+#include <common/sessiond-comm/sessiond-comm.h>
#include "kernel.h"
#include "kern-modules.h"
ret = kernctl_add_context(chan->fd, ctx);
if (ret < 0) {
if (errno != EEXIST) {
- perror("add context ioctl");
+ PERROR("add context ioctl");
} else {
/* If EEXIST, we just ignore the error */
ret = 0;
chan->ctx = zmalloc(sizeof(struct lttng_kernel_context));
if (chan->ctx == NULL) {
- perror("zmalloc event context");
+ PERROR("zmalloc event context");
goto error;
}
DBG("Adding context to event %s", event->event->name);
ret = kernctl_add_context(event->fd, ctx);
if (ret < 0) {
- perror("add context ioctl");
+ PERROR("add context ioctl");
goto error;
}
event->ctx = zmalloc(sizeof(struct lttng_kernel_context));
if (event->ctx == NULL) {
- perror("zmalloc event context");
+ PERROR("zmalloc event context");
goto error;
}
/* Kernel tracer session creation */
ret = kernctl_create_session(tracer_fd);
if (ret < 0) {
- perror("ioctl kernel create session");
+ PERROR("ioctl kernel create session");
goto error;
}
/* Prevent fd duplication after execlp() */
ret = fcntl(lks->fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
- perror("fcntl session fd");
+ PERROR("fcntl session fd");
}
lks->consumer_fds_sent = 0;
/* Kernel tracer channel creation */
ret = kernctl_create_channel(session->fd, &lkc->channel->attr);
if (ret < 0) {
- perror("ioctl kernel create channel");
+ PERROR("ioctl kernel create channel");
goto error;
}
/* Prevent fd duplication after execlp() */
ret = fcntl(lkc->fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
- perror("fcntl session fd");
+ PERROR("fcntl session fd");
}
/* Add channel to session */
*/
if (ret == 0 && event->event->instrumentation == LTTNG_KERNEL_SYSCALL) {
DBG2("Kernel event syscall creation success");
+ /*
+ * We use fd == -1 to ensure that we never trigger a close of fd
+ * 0.
+ */
+ event->fd = -1;
goto add_list;
}
/* Prevent fd duplication after execlp() */
ret = fcntl(event->fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
- perror("fcntl session fd");
+ PERROR("fcntl session fd");
}
add_list:
ret = kernctl_disable(chan->fd);
if (ret < 0) {
- perror("disable chan ioctl");
+ PERROR("disable chan ioctl");
ret = errno;
goto error;
}
ret = kernctl_enable(chan->fd);
if (ret < 0 && errno != EEXIST) {
- perror("Enable kernel chan");
+ PERROR("Enable kernel chan");
goto error;
}
int ret;
ret = kernctl_enable(event->fd);
- if (ret < 0 && errno != EEXIST) {
- perror("enable kernel event");
+ if (ret < 0) {
+ switch (errno) {
+ case EEXIST:
+ ret = LTTCOMM_KERN_EVENT_EXIST;
+ break;
+ default:
+ PERROR("enable kernel event");
+ break;
+ }
goto error;
}
int ret;
ret = kernctl_disable(event->fd);
- if (ret < 0 && errno != EEXIST) {
- perror("disable kernel event");
+ if (ret < 0) {
+ switch (errno) {
+ case EEXIST:
+ ret = LTTCOMM_KERN_EVENT_EXIST;
+ break;
+ default:
+ PERROR("disable kernel event");
+ break;
+ }
goto error;
}
/* Prevent fd duplication after execlp() */
ret = fcntl(lkm->fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
- perror("fcntl session fd");
+ PERROR("fcntl session fd");
}
session->metadata = lkm;
ret = kernctl_start_session(session->fd);
if (ret < 0) {
- perror("ioctl start session");
+ PERROR("ioctl start session");
goto error;
}
ret = kernctl_wait_quiescent(fd);
if (ret < 0) {
- perror("wait quiescent ioctl");
+ PERROR("wait quiescent ioctl");
ERR("Kernel quiescent wait failed");
}
}
ret = kernctl_calibrate(fd, calibrate);
if (ret < 0) {
- perror("calibrate ioctl");
+ PERROR("calibrate ioctl");
return -1;
}
DBG("Flushing channel stream %d", stream->fd);
ret = kernctl_buffer_flush(stream->fd);
if (ret < 0) {
- perror("ioctl");
+ PERROR("ioctl");
ERR("Fail to flush buffer for stream %d (ret: %d)",
stream->fd, ret);
}
int ret;
struct ltt_kernel_stream *lks;
- while ((ret = kernctl_create_stream(channel->fd)) > 0) {
+ while ((ret = kernctl_create_stream(channel->fd)) >= 0) {
lks = trace_kernel_create_stream();
if (lks == NULL) {
- close(ret);
+ ret = close(ret);
+ if (ret) {
+ PERROR("close");
+ }
goto error;
}
/* Prevent fd duplication after execlp() */
ret = fcntl(lks->fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
- perror("fcntl session fd");
+ PERROR("fcntl session fd");
}
ret = asprintf(&lks->pathname, "%s/%s_%d",
channel->pathname, channel->channel->name, channel->stream_count);
if (ret < 0) {
- perror("asprintf kernel create stream");
+ PERROR("asprintf kernel create stream");
goto error;
}
ret = kernctl_create_stream(session->metadata->fd);
if (ret < 0) {
- perror("kernel create metadata stream");
+ PERROR("kernel create metadata stream");
goto error;
}
/* Prevent fd duplication after execlp() */
ret = fcntl(session->metadata_stream_fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
- perror("fcntl session fd");
+ PERROR("fcntl session fd");
}
return 0;
*/
ssize_t kernel_list_events(int tracer_fd, struct lttng_event **events)
{
- int fd, pos;
+ int fd, pos, ret;
char *event;
size_t nbmem, count = 0;
ssize_t size;
fd = kernctl_tracepoint_list(tracer_fd);
if (fd < 0) {
- perror("kernel tracepoint list");
+ PERROR("kernel tracepoint list");
goto error;
}
fp = fdopen(fd, "r");
if (fp == NULL) {
- perror("kernel tracepoint list fdopen");
+ PERROR("kernel tracepoint list fdopen");
goto error_fp;
}
*/
nbmem = KERNEL_EVENT_INIT_LIST_SIZE;
elist = zmalloc(sizeof(struct lttng_event) * nbmem);
+ if (elist == NULL) {
+ PERROR("alloc list events");
+ count = -ENOMEM;
+ goto end;
+ }
while ((size = fscanf(fp, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) {
if (count >= nbmem) {
+ struct lttng_event *new_elist;
+
DBG("Reallocating event list from %zu to %zu bytes", nbmem,
nbmem * 2);
/* Double the size */
nbmem <<= 1;
- elist = realloc(elist, nbmem * sizeof(struct lttng_event));
- if (elist == NULL) {
- perror("realloc list events");
+ new_elist = realloc(elist, nbmem * sizeof(struct lttng_event));
+ if (new_elist == NULL) {
+ PERROR("realloc list events");
+ free(event);
+ free(elist);
count = -ENOMEM;
goto end;
}
+ elist = new_elist;
}
strncpy(elist[count].name, event, LTTNG_SYMBOL_NAME_LEN);
elist[count].name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
elist[count].enabled = -1;
count++;
+ free(event);
}
*events = elist;
DBG("Kernel list events done (%zu events)", count);
end:
- fclose(fp); /* closes both fp and fd */
+ ret = fclose(fp); /* closes both fp and fd */
+ if (ret) {
+ PERROR("fclose");
+ }
return count;
error_fp:
- close(fd);
+ ret = close(fd);
+ if (ret) {
+ PERROR("close");
+ }
error:
return -1;
}
/* Ignore error, we don't really care */
}
}
- fclose(fp);
+ ret = fclose(fp);
+ if (ret) {
+ PERROR("fclose");
+ }
end_boot_id:
-
return 0;
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_KERNEL_CTL_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_SESSIOND_H
#include <urcu/wfqueue.h>
#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/compat/socket.h>
#include "session.h"
#include "ust-app.h"
struct command_ctx {
int ust_sock;
unsigned int lttng_msg_size;
- struct ucred creds;
struct ltt_session *session;
struct lttcomm_lttng_msg *llm;
struct lttcomm_session_msg *lsm;
+ lttng_sock_cred creds;
};
struct ust_command {
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
*
- * Permission is hereby granted to use or copy this program
- * for any purpose, provided the above notices are retained on all copies.
- * Permission to modify the code and to distribute modified code is granted,
- * provided the above notices are retained, and a notice that the code was
- * modified is included with the above copyright notice.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*/
#include <stdint.h>
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_UST_CTL_H
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
-#include <fcntl.h>
#include <getopt.h>
#include <grp.h>
#include <limits.h>
#include <common/common.h>
#include <common/compat/poll.h>
+#include <common/compat/socket.h>
#include <common/defaults.h>
#include <common/kernel-consumer/kernel-consumer.h>
#include <common/ust-consumer/ust-consumer.h>
#include "shm.h"
#include "ust-ctl.h"
#include "utils.h"
+#include "fd-limit.h"
#define CONSUMERD_FILE "lttng-consumerd"
const char default_ust_sock_dir[] = DEFAULT_UST_SOCK_DIR;
const char default_global_apps_pipe[] = DEFAULT_GLOBAL_APPS_PIPE;
-/* Variables */
-int opt_verbose; /* Not static for lttngerr.h */
-int opt_verbose_consumer; /* Not static for lttngerr.h */
-int opt_quiet; /* Not static for lttngerr.h */
-
const char *progname;
const char *opt_tracing_group;
static int opt_sig_parent;
+static int opt_verbose_consumer;
static int opt_daemon;
static int opt_no_kernel;
static int is_root; /* Set to 1 if the daemon is running as root */
.type = LTTNG_CONSUMER_KERNEL,
.err_unix_sock_path = DEFAULT_KCONSUMERD_ERR_SOCK_PATH,
.cmd_unix_sock_path = DEFAULT_KCONSUMERD_CMD_SOCK_PATH,
+ .err_sock = -1,
+ .cmd_sock = -1,
};
static struct consumer_data ustconsumer64_data = {
.type = LTTNG_CONSUMER64_UST,
.err_unix_sock_path = DEFAULT_USTCONSUMERD64_ERR_SOCK_PATH,
.cmd_unix_sock_path = DEFAULT_USTCONSUMERD64_CMD_SOCK_PATH,
+ .err_sock = -1,
+ .cmd_sock = -1,
};
static struct consumer_data ustconsumer32_data = {
.type = LTTNG_CONSUMER32_UST,
.err_unix_sock_path = DEFAULT_USTCONSUMERD32_ERR_SOCK_PATH,
.cmd_unix_sock_path = DEFAULT_USTCONSUMERD32_CMD_SOCK_PATH,
+ .err_sock = -1,
+ .cmd_sock = -1,
};
static int dispatch_thread_exit;
static char wait_shm_path[PATH_MAX];
/* Sockets and FDs */
-static int client_sock;
-static int apps_sock;
-static int kernel_tracer_fd;
-static int kernel_poll_pipe[2];
+static int client_sock = -1;
+static int apps_sock = -1;
+static int kernel_tracer_fd = -1;
+static int kernel_poll_pipe[2] = { -1, -1 };
/*
* Quit pipe for all threads. This permits a single cancellation point
* for all threads when receiving an event on the pipe.
*/
-static int thread_quit_pipe[2];
+static int thread_quit_pipe[2] = { -1, -1 };
/*
* 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];
+static int apps_cmd_pipe[2] = { -1, -1 };
/* Pthread, Mutexes and Semaphores */
static pthread_t apps_thread;
*/
static int init_thread_quit_pipe(void)
{
- int ret;
+ int ret, i;
- ret = pipe2(thread_quit_pipe, O_CLOEXEC);
+ ret = pipe(thread_quit_pipe);
if (ret < 0) {
- perror("thread quit pipe");
+ PERROR("thread quit pipe");
goto error;
}
+ for (i = 0; i < 2; i++) {
+ ret = fcntl(thread_quit_pipe[i], F_SETFD, FD_CLOEXEC);
+ if (ret < 0) {
+ PERROR("fcntl");
+ goto error;
+ }
+ }
+
error:
return ret;
}
* If a custom kernel consumer was registered, close the socket before
* tearing down the complete kernel session structure
*/
- if (session->kernel_session->consumer_fd != kconsumer_data.cmd_sock) {
+ if (kconsumer_data.cmd_sock >= 0 &&
+ session->kernel_session->consumer_fd != kconsumer_data.cmd_sock) {
lttcomm_close_unix_sock(session->kernel_session->consumer_fd);
}
*/
static void cleanup(void)
{
- int ret;
+ int ret, i;
char *cmd;
struct ltt_session *sess, *stmp;
if (is_root && !opt_no_kernel) {
DBG2("Closing kernel fd");
- close(kernel_tracer_fd);
+ if (kernel_tracer_fd >= 0) {
+ ret = close(kernel_tracer_fd);
+ if (ret) {
+ PERROR("close");
+ }
+ }
DBG("Unloading kernel modules");
modprobe_remove_lttng_all();
}
- close(thread_quit_pipe[0]);
- close(thread_quit_pipe[1]);
+ /*
+ * Closing all pipes used for communication between threads.
+ */
+ for (i = 0; i < 2; i++) {
+ if (kernel_poll_pipe[i] >= 0) {
+ ret = close(kernel_poll_pipe[i]);
+ if (ret) {
+ PERROR("close");
+ }
+
+ }
+ }
+ for (i = 0; i < 2; i++) {
+ if (thread_quit_pipe[i] >= 0) {
+ ret = close(thread_quit_pipe[i]);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ }
+ for (i = 0; i < 2; i++) {
+ if (apps_cmd_pipe[i] >= 0) {
+ ret = close(apps_cmd_pipe[i]);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ }
/* OUTPUT BENCHMARK RESULTS */
bench_init();
DBG("Sending channel %d to consumer", lkm.u.channel.channel_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer channel");
+ PERROR("send consumer channel");
goto error;
}
DBG("Sending stream %d to consumer", lkm.u.stream.stream_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
ret = lttcomm_send_fds_unix_sock(sock, &stream->fd, 1);
if (ret < 0) {
- perror("send consumer stream ancillary data");
+ PERROR("send consumer stream ancillary data");
goto error;
}
}
DBG("Sending metadata stream fd");
- /* Extra protection. It's NOT supposed to be set to 0 at this point */
- if (session->consumer_fd == 0) {
+ /* Extra protection. It's NOT supposed to be set to -1 at this point */
+ if (session->consumer_fd < 0) {
session->consumer_fd = consumer_data->cmd_sock;
}
- if (session->metadata_stream_fd != 0) {
+ if (session->metadata_stream_fd >= 0) {
/* Send metadata channel fd */
lkm.cmd_type = LTTNG_CONSUMER_ADD_CHANNEL;
lkm.u.channel.channel_key = session->metadata->fd;
lkm.u.channel.max_sb_size = session->metadata->conf->attr.subbuf_size;
lkm.u.channel.mmap_len = 0; /* for kernel */
- DBG("Sending metadata channel %d to consumer", lkm.u.stream.stream_key);
+ DBG("Sending metadata channel %d to consumer", lkm.u.channel.channel_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer channel");
+ PERROR("send consumer channel");
goto error;
}
DBG("Sending metadata stream %d to consumer", lkm.u.stream.stream_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
ret = lttcomm_send_fds_unix_sock(sock, &session->metadata_stream_fd, 1);
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
}
cmd_ctx->llm = zmalloc(sizeof(struct lttcomm_lttng_msg) + buf_size);
if (cmd_ctx->llm == NULL) {
- perror("zmalloc");
+ PERROR("zmalloc");
ret = -ENOMEM;
goto error;
}
continue;
}
- /* This is not suppose to be 0 but this is an extra security check */
- if (session->kernel_session->consumer_fd == 0) {
+ /* This is not suppose to be -1 but this is an extra security check */
+ if (session->kernel_session->consumer_fd < 0) {
session->kernel_session->consumer_fd = consumer_data->cmd_sock;
}
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_poll_create;
}
ret = lttng_poll_add(&events, kernel_poll_pipe[0], LPOLLIN);
tracepoint(sessiond_th_kern_poll);
/* Poll infinite value of time */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
} else if (ret == 0) {
/* Should not happen since timeout is infinite */
}
error:
- DBG("Kernel thread dying");
- close(kernel_poll_pipe[0]);
- close(kernel_poll_pipe[1]);
-
lttng_poll_clean(&events);
-
+error_poll_create:
+ DBG("Kernel thread dying");
return NULL;
}
*/
static void *thread_manage_consumer(void *data)
{
- int sock = 0, i, ret, pollfd;
+ int sock = -1, i, ret, pollfd;
uint32_t revents, nb_fd;
enum lttcomm_return_code code;
struct lttng_poll_event events;
ret = lttcomm_listen_unix_sock(consumer_data->err_sock);
if (ret < 0) {
- goto error;
+ goto error_listen;
}
/*
*/
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_poll;
}
ret = lttng_poll_add(&events, consumer_data->err_sock, LPOLLIN | LPOLLRDHUP);
tracepoint(sessiond_th_kcon_poll);
/* Inifinite blocking call, waiting for transmission */
+restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
+restart_poll:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart_poll;
+ }
goto error;
}
ERR("consumer return code : %s", lttcomm_get_readable_code(-code));
error:
- DBG("consumer thread dying");
- close(consumer_data->err_sock);
- close(consumer_data->cmd_sock);
- close(sock);
+ if (consumer_data->err_sock >= 0) {
+ ret = close(consumer_data->err_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (consumer_data->cmd_sock >= 0) {
+ ret = close(consumer_data->cmd_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (sock >= 0) {
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
unlink(consumer_data->err_unix_sock_path);
unlink(consumer_data->cmd_unix_sock_path);
consumer_data->pid = 0;
lttng_poll_clean(&events);
+error_poll:
+error_listen:
+ DBG("consumer thread cleanup completed");
return NULL;
}
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_poll_create;
}
ret = lttng_poll_add(&events, apps_cmd_pipe[0], LPOLLIN | LPOLLRDHUP);
tracepoint(sessiond_th_apps_poll);
/* Inifinite blocking call, waiting for transmission */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
/* 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");
+ PERROR("read apps cmd pipe");
goto error;
}
tracepoint(ust_register_read_stop);
/*
* We just need here to monitor the close of the UST
* socket and poll set monitor those by default.
+ * Listen on POLLIN (even if we never expect any
+ * data) to ensure that hangup wakes us.
*/
- ret = lttng_poll_add(&events, ust_cmd.sock, 0);
+ ret = lttng_poll_add(&events, ust_cmd.sock, LPOLLIN);
if (ret < 0) {
goto error;
}
}
error:
- DBG("Application communication apps dying");
- close(apps_cmd_pipe[0]);
- close(apps_cmd_pipe[1]);
-
lttng_poll_clean(&events);
-
+error_poll_create:
+ DBG("Application communication apps thread cleanup complete");
rcu_thread_offline();
rcu_unregister_thread();
return NULL;
ret = write(apps_cmd_pipe[1], ust_cmd,
sizeof(struct ust_command));
if (ret < 0) {
- perror("write apps cmd pipe");
+ PERROR("write apps cmd pipe");
if (errno == EBADF) {
/*
* We can't inform the application thread to process
*/
static void *thread_registration_apps(void *data)
{
- int sock = 0, i, ret, pollfd;
+ int sock = -1, i, ret, pollfd;
uint32_t revents, nb_fd;
struct lttng_poll_event events;
/*
ret = lttcomm_listen_unix_sock(apps_sock);
if (ret < 0) {
- goto error;
+ goto error_listen;
}
/*
*/
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_create_poll;
}
/* Add the application registration socket */
ret = lttng_poll_add(&events, apps_sock, LPOLLIN | LPOLLRDHUP);
if (ret < 0) {
- goto error;
+ goto error_poll_add;
}
/* Notify all applications to register */
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
/* Create UST registration command for enqueuing */
ust_cmd = zmalloc(sizeof(struct ust_command));
if (ust_cmd == NULL) {
- perror("ust command zmalloc");
+ PERROR("ust command zmalloc");
goto error;
}
* Using message-based transmissions to ensure we don't
* have to deal with partially received messages.
*/
+ ret = lttng_fd_get(LTTNG_FD_APPS, 1);
+ if (ret < 0) {
+ ERR("Exhausted file descriptors allowed for applications.");
+ free(ust_cmd);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
+ continue;
+ }
ret = lttcomm_recv_unix_sock(sock, &ust_cmd->reg_msg,
sizeof(struct ust_register_msg));
if (ret < 0 || ret < sizeof(struct ust_register_msg)) {
if (ret < 0) {
- perror("lttcomm_recv_unix_sock register apps");
+ PERROR("lttcomm_recv_unix_sock register apps");
} else {
ERR("Wrong size received on apps register");
}
free(ust_cmd);
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ lttng_fd_put(LTTNG_FD_APPS, 1);
+ sock = -1;
continue;
}
ust_cmd->sock = sock;
+ sock = -1;
DBG("UST registration received with pid:%d ppid:%d uid:%d"
" gid:%d sock:%d name:%s (version %d.%d)",
}
error:
- DBG("UST Registration thread dying");
-
/* Notify that the registration thread is gone */
notify_ust_apps(0);
- close(apps_sock);
- close(sock);
+ if (apps_sock >= 0) {
+ ret = close(apps_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (sock >= 0) {
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ lttng_fd_put(LTTNG_FD_APPS, 1);
+ }
unlink(apps_unix_sock_path);
+error_poll_add:
lttng_poll_clean(&events);
+error_listen:
+error_create_poll:
+ DBG("UST Registration thread cleanup complete");
return NULL;
}
break;
}
default:
- perror("unknown consumer type");
+ PERROR("unknown consumer type");
exit(EXIT_FAILURE);
}
if (errno != 0) {
- perror("kernel start consumer exec");
+ PERROR("kernel start consumer exec");
}
exit(EXIT_FAILURE);
} else if (pid > 0) {
ret = pid;
} else {
- perror("start consumer fork");
+ PERROR("start consumer fork");
ret = -errno;
}
error:
error_version:
modprobe_remove_lttng_control();
- close(kernel_tracer_fd);
- kernel_tracer_fd = 0;
+ ret = close(kernel_tracer_fd);
+ if (ret) {
+ PERROR("close");
+ }
+ kernel_tracer_fd = -1;
return LTTCOMM_KERN_VERSION;
error_modules:
- close(kernel_tracer_fd);
+ ret = close(kernel_tracer_fd);
+ if (ret) {
+ PERROR("close");
+ }
error_open:
modprobe_remove_lttng_control();
error:
WARN("No kernel tracer available");
- kernel_tracer_fd = 0;
- return LTTCOMM_KERN_NA;
+ kernel_tracer_fd = -1;
+ if (!is_root) {
+ return LTTCOMM_NEED_ROOT_SESSIOND;
+ } else {
+ return LTTCOMM_KERN_NA;
+ }
}
/*
if (session->consumer_fds_sent == 0) {
/*
* Assign default kernel consumer socket if no consumer assigned to the
- * kernel session. At this point, it's NOT suppose to be 0 but this is
+ * kernel session. At this point, it's NOT supposed to be -1 but this is
* an extra security check.
*/
- if (session->consumer_fd == 0) {
+ if (session->consumer_fd < 0) {
session->consumer_fd = kconsumer_data.cmd_sock;
}
}
/* Set kernel consumer socket fd */
- if (kconsumer_data.cmd_sock) {
+ if (kconsumer_data.cmd_sock >= 0) {
session->kernel_session->consumer_fd = kconsumer_data.cmd_sock;
}
usess = session->ust_session;
if (session->enabled) {
- ret = LTTCOMM_UST_START_FAIL;
+ /* Already started. */
+ ret = LTTCOMM_TRACE_ALREADY_STARTED;
goto error;
}
}
/* Open kernel metadata stream */
- if (ksession->metadata_stream_fd == 0) {
+ if (ksession->metadata_stream_fd < 0) {
ret = kernel_open_metadata_stream(ksession);
if (ret < 0) {
ERR("Kernel create metadata stream failed");
usess = session->ust_session;
if (!session->enabled) {
- ret = LTTCOMM_UST_STOP_FAIL;
+ ret = LTTCOMM_TRACE_ALREADY_STOPPED;
goto error;
}
/*
* Command LTTNG_CREATE_SESSION processed by the client thread.
*/
-static int cmd_create_session(char *name, char *path, struct ucred *creds)
+static int cmd_create_session(char *name, char *path, lttng_sock_cred *creds)
{
int ret;
- ret = session_create(name, path, creds->uid, creds->gid);
+ ret = session_create(name, path, LTTNG_SOCK_GET_UID_CRED(creds),
+ LTTNG_SOCK_GET_GID_CRED(creds));
if (ret != LTTCOMM_OK) {
goto error;
}
*/
ret = notify_thread_pipe(kernel_poll_pipe[1]);
if (ret < 0) {
- perror("write kernel poll pipe");
+ PERROR("write kernel poll pipe");
}
ret = session_destroy(session);
{
int ret = LTTCOMM_OK;
int need_tracing_session = 1;
+ int need_domain;
DBG("Processing client command %d", cmd_ctx->lsm->cmd_type);
- if (opt_no_kernel && cmd_ctx->lsm->domain.type == LTTNG_DOMAIN_KERNEL) {
- ret = LTTCOMM_KERN_NA;
+ switch (cmd_ctx->lsm->cmd_type) {
+ case LTTNG_CREATE_SESSION:
+ case LTTNG_DESTROY_SESSION:
+ case LTTNG_LIST_SESSIONS:
+ case LTTNG_LIST_DOMAINS:
+ case LTTNG_START_TRACE:
+ case LTTNG_STOP_TRACE:
+ need_domain = 0;
+ break;
+ default:
+ need_domain = 1;
+ }
+
+ if (opt_no_kernel && need_domain
+ && cmd_ctx->lsm->domain.type == LTTNG_DOMAIN_KERNEL) {
+ if (!is_root) {
+ ret = LTTCOMM_NEED_ROOT_SESSIOND;
+ } else {
+ ret = LTTCOMM_KERN_NA;
+ }
goto error;
}
/* Commands that DO NOT need a session. */
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_CALIBRATE:
case LTTNG_CREATE_SESSION:
+ case LTTNG_CALIBRATE:
case LTTNG_LIST_SESSIONS:
case LTTNG_LIST_TRACEPOINTS:
need_tracing_session = 0;
break;
default:
DBG("Getting session %s by name", cmd_ctx->lsm->session.name);
+ /*
+ * We keep the session list lock across _all_ commands
+ * for now, because the per-session lock does not
+ * handle teardown properly.
+ */
session_lock_list();
cmd_ctx->session = session_find_by_name(cmd_ctx->lsm->session.name);
- session_unlock_list();
if (cmd_ctx->session == NULL) {
if (cmd_ctx->lsm->session.name != NULL) {
ret = LTTCOMM_SESS_NOT_FOUND;
break;
}
+ if (!need_domain) {
+ goto skip_domain;
+ }
/*
* Check domain type for specific "pre-action".
*/
switch (cmd_ctx->lsm->domain.type) {
case LTTNG_DOMAIN_KERNEL:
if (!is_root) {
- ret = LTTCOMM_KERN_NA;
+ ret = LTTCOMM_NEED_ROOT_SESSIOND;
goto error;
}
/* Kernel tracer check */
- if (kernel_tracer_fd == 0) {
+ if (kernel_tracer_fd == -1) {
/* Basically, load kernel tracer modules */
ret = init_kernel_tracer();
if (ret != 0) {
default:
break;
}
+skip_domain:
/*
* Check that the UID or GID match that of the tracing session.
*/
if (need_tracing_session) {
if (!session_access_ok(cmd_ctx->session,
- cmd_ctx->creds.uid, cmd_ctx->creds.gid)) {
+ LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds),
+ LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds))) {
ret = LTTCOMM_EPERM;
goto error;
}
ret = cmd_destroy_session(cmd_ctx->session,
cmd_ctx->lsm->session.name);
tracepoint(destroy_session_end);
+ /*
+ * Set session to NULL so we do not unlock it after
+ * free.
+ */
+ cmd_ctx->session = NULL;
break;
}
case LTTNG_LIST_DOMAINS:
unsigned int nr_sessions;
session_lock_list();
- nr_sessions = lttng_sessions_count(cmd_ctx->creds.uid, cmd_ctx->creds.gid);
+ nr_sessions = lttng_sessions_count(
+ LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds),
+ LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds));
ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * nr_sessions);
if (ret < 0) {
/* Filled the session array */
list_lttng_sessions((struct lttng_session *)(cmd_ctx->llm->payload),
- cmd_ctx->creds.uid, cmd_ctx->creds.gid);
+ LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds),
+ LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds));
session_unlock_list();
if (cmd_ctx->session) {
session_unlock(cmd_ctx->session);
}
+ if (need_tracing_session) {
+ session_unlock_list();
+ }
init_setup_error:
return ret;
}
*/
static void *thread_manage_clients(void *data)
{
- int sock = 0, ret, i, pollfd;
+ int sock = -1, ret, i, pollfd;
uint32_t revents, nb_fd;
struct command_ctx *cmd_ctx = NULL;
struct lttng_poll_event events;
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
/* Allocate context command to process the client request */
cmd_ctx = zmalloc(sizeof(struct command_ctx));
if (cmd_ctx == NULL) {
- perror("zmalloc cmd_ctx");
+ PERROR("zmalloc cmd_ctx");
goto error;
}
/* Allocate data buffer for reception */
cmd_ctx->lsm = zmalloc(sizeof(struct lttcomm_session_msg));
if (cmd_ctx->lsm == NULL) {
- perror("zmalloc cmd_ctx->lsm");
+ PERROR("zmalloc cmd_ctx->lsm");
goto error;
}
sizeof(struct lttcomm_session_msg), &cmd_ctx->creds);
if (ret <= 0) {
DBG("Nothing recv() from client... continuing");
- close(sock);
- free(cmd_ctx);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
+ clean_command_ctx(&cmd_ctx);
continue;
}
}
/* End of transmission */
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
clean_command_ctx(&cmd_ctx);
}
error:
DBG("Client thread dying");
unlink(client_unix_sock_path);
- close(client_sock);
- close(sock);
+ if (client_sock >= 0) {
+ ret = close(client_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (sock >= 0) {
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
lttng_poll_clean(&events);
clean_command_ctx(&cmd_ctx);
opt_no_kernel = 1;
break;
case 'q':
- opt_quiet = 1;
+ lttng_opt_quiet = 1;
break;
case 'v':
/* Verbose level can increase using multiple -v */
- opt_verbose += 1;
+ lttng_opt_verbose += 1;
break;
case 'Z':
opt_verbose_consumer += 1;
ret = chmod(client_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (ret < 0) {
ERR("Set file permissions failed: %s", client_unix_sock_path);
- perror("chmod");
+ PERROR("chmod");
goto end;
}
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (ret < 0) {
ERR("Set file permissions failed: %s", apps_unix_sock_path);
- perror("chmod");
+ PERROR("chmod");
goto end;
}
ret = chown(rundir, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", rundir);
- perror("chown");
+ PERROR("chown");
}
/* Ensure tracing group can search the run dir */
- ret = chmod(rundir, S_IRWXU | S_IXGRP);
+ ret = chmod(rundir, S_IRWXU | S_IXGRP | S_IXOTH);
if (ret < 0) {
ERR("Unable to set permissions on %s", rundir);
- perror("chmod");
+ PERROR("chmod");
}
/* lttng client socket path */
ret = chown(client_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", client_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
/* kconsumer error socket path */
ret = chown(kconsumer_data.err_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", kconsumer_data.err_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
/* 64-bit ustconsumer error socket path */
ret = chown(ustconsumer64_data.err_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", ustconsumer64_data.err_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
/* 32-bit ustconsumer compat32 error socket path */
ret = chown(ustconsumer32_data.err_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", ustconsumer32_data.err_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
DBG("All permissions are set");
/*
* Create the pipe used to wake up the kernel thread.
+ * Closed in cleanup().
*/
static int create_kernel_poll_pipe(void)
{
- return pipe2(kernel_poll_pipe, O_CLOEXEC);
+ int ret, i;
+
+ ret = pipe(kernel_poll_pipe);
+ if (ret < 0) {
+ PERROR("kernel poll pipe");
+ goto error;
+ }
+
+ for (i = 0; i < 2; i++) {
+ ret = fcntl(kernel_poll_pipe[i], F_SETFD, FD_CLOEXEC);
+ if (ret < 0) {
+ PERROR("fcntl kernel_poll_pipe");
+ goto error;
+ }
+ }
+
+error:
+ return ret;
}
/*
* Create the application command pipe to wake thread_manage_apps.
+ * Closed in cleanup().
*/
static int create_apps_cmd_pipe(void)
{
- return pipe2(apps_cmd_pipe, O_CLOEXEC);
+ int ret, i;
+
+ ret = pipe(apps_cmd_pipe);
+ if (ret < 0) {
+ PERROR("apps cmd pipe");
+ goto error;
+ }
+
+ for (i = 0; i < 2; i++) {
+ ret = fcntl(apps_cmd_pipe[i], F_SETFD, FD_CLOEXEC);
+ if (ret < 0) {
+ PERROR("fcntl apps_cmd_pipe");
+ goto error;
+ }
+ }
+
+error:
+ return ret;
}
/*
ret = mkdir(path, S_IRWXU);
if (ret < 0) {
if (errno != EEXIST) {
+ PERROR("mkdir");
ERR("Failed to create %s", path);
goto error;
}
- ret = 0;
+ ret = -1;
}
/* Create the kconsumerd error unix socket */
sigset_t sigset;
if ((ret = sigemptyset(&sigset)) < 0) {
- perror("sigemptyset");
+ PERROR("sigemptyset");
return ret;
}
sa.sa_mask = sigset;
sa.sa_flags = 0;
if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
- perror("sigaction");
+ PERROR("sigaction");
return ret;
}
if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
- perror("sigaction");
+ PERROR("sigaction");
return ret;
}
if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) {
- perror("sigaction");
+ PERROR("sigaction");
return ret;
}
ret = setrlimit(RLIMIT_NOFILE, &lim);
if (ret < 0) {
- perror("failed to set open files limit");
+ PERROR("failed to set open files limit");
}
}
if (opt_daemon) {
ret = daemon(0, 0);
if (ret < 0) {
- perror("daemon");
+ PERROR("daemon");
goto error;
}
}
goto error;
}
+ /*
+ * Init UST app hash table. Alloc hash table before this point since
+ * cleanup() can get called after that point.
+ */
+ ust_app_ht_alloc();
+
/* After this point, we can safely call cleanup() with "goto exit" */
/*
/* Set ulimit for open files */
set_ulimit();
}
+ /* init lttng_fd tracking must be done after set_ulimit. */
+ lttng_fd_init();
ret = set_consumer_sockets(&ustconsumer64_data, rundir);
if (ret < 0) {
/* Init UST command queue. */
cds_wfq_init(&ust_cmd_queue.queue);
- /* Init UST app hash table */
- ust_app_ht_alloc();
-
/*
* Get session list pointer. This pointer MUST NOT be free(). This list is
* statically declared in session.c
ret = pthread_create(&client_thread, NULL,
thread_manage_clients, (void *) NULL);
if (ret != 0) {
- perror("pthread_create clients");
+ PERROR("pthread_create clients");
goto exit_client;
}
ret = pthread_create(&dispatch_thread, NULL,
thread_dispatch_ust_registration, (void *) NULL);
if (ret != 0) {
- perror("pthread_create dispatch");
+ PERROR("pthread_create dispatch");
goto exit_dispatch;
}
ret = pthread_create(®_apps_thread, NULL,
thread_registration_apps, (void *) NULL);
if (ret != 0) {
- perror("pthread_create registration");
+ PERROR("pthread_create registration");
goto exit_reg_apps;
}
ret = pthread_create(&apps_thread, NULL,
thread_manage_apps, (void *) NULL);
if (ret != 0) {
- perror("pthread_create apps");
+ PERROR("pthread_create apps");
goto exit_apps;
}
ret = pthread_create(&kernel_thread, NULL,
thread_manage_kernel, (void *) NULL);
if (ret != 0) {
- perror("pthread_create kernel");
+ PERROR("pthread_create kernel");
goto exit_kernel;
}
ret = pthread_join(kernel_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
exit_kernel:
ret = pthread_join(apps_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
exit_apps:
ret = pthread_join(reg_apps_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ 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");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
exit_dispatch:
ret = pthread_join(client_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
ret = join_consumer_thread(&kconsumer_data);
if (ret != 0) {
- perror("join_consumer");
+ PERROR("join_consumer");
goto error; /* join error, exit without cleanup */
}
/*
* Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
"/sbin/modprobe -r -q %s",
kern_modules_list[i].name);
if (ret < 0) {
- perror("snprintf modprobe -r");
+ PERROR("snprintf modprobe -r");
goto error;
}
modprobe[sizeof(modprobe) - 1] = '\0';
kern_modules_list[i].required ? "" : "-q ",
kern_modules_list[i].name);
if (ret < 0) {
- perror("snprintf modprobe");
+ PERROR("snprintf modprobe");
goto error;
}
modprobe[sizeof(modprobe) - 1] = '\0';
/*
* Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _MODPROBE_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/* Allocate session data structure */
new_session = zmalloc(sizeof(struct ltt_session));
if (new_session == NULL) {
- perror("zmalloc");
+ PERROR("zmalloc");
ret = LTTCOMM_FATAL;
goto error_malloc;
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_SESSION_H
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
ret = chown(shm_path, 0, 0);
if (ret < 0) {
if (errno != ENOENT) {
- perror("chown wait shm");
+ PERROR("chown wait shm");
goto error;
}
}
ret = chown(shm_path, getuid(), getgid());
if (ret < 0) {
if (errno != ENOENT) {
- perror("chown wait shm");
+ PERROR("chown wait shm");
goto error;
}
}
ret = chmod(shm_path, mode);
if (ret < 0) {
if (errno != ENOENT) {
- perror("chmod wait shm");
+ PERROR("chmod wait shm");
goto error;
}
}
*/
wait_shm_fd = shm_open(shm_path, O_RDWR | O_CREAT, mode);
if (wait_shm_fd < 0) {
- perror("shm_open wait shm");
+ PERROR("shm_open wait shm");
goto error;
}
ret = ftruncate(wait_shm_fd, mmap_size);
if (ret < 0) {
- perror("ftruncate wait shm");
+ PERROR("ftruncate wait shm");
exit(EXIT_FAILURE);
}
+#ifndef __FreeBSD__
ret = fchmod(wait_shm_fd, mode);
if (ret < 0) {
- perror("fchmod");
+ PERROR("fchmod");
exit(EXIT_FAILURE);
}
+#else
+#warning "FreeBSD does not support setting file mode on shm FD. Remember that for secure use, lttng-sessiond should be started before applications linked on lttng-ust."
+#endif
tracepoint(ust_notify_shm_stop);
/* close shm fd immediately after taking the mmap reference */
ret = close(wait_shm_fd);
if (ret) {
- perror("Error closing fd");
+ PERROR("Error closing fd");
}
if (wait_shm_mmap == MAP_FAILED) {
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_SHM_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/* Allocate a new ltt kernel session */
lks = zmalloc(sizeof(struct ltt_kernel_session));
if (lks == NULL) {
- perror("create kernel session zmalloc");
+ PERROR("create kernel session zmalloc");
goto error;
}
/* Init data structure */
- lks->fd = 0;
- lks->metadata_stream_fd = 0;
+ lks->fd = -1;
+ lks->metadata_stream_fd = -1;
lks->channel_count = 0;
lks->stream_count_global = 0;
lks->metadata = NULL;
- lks->consumer_fd = 0;
+ lks->consumer_fd = -1;
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");
+ PERROR("asprintf kernel traces path");
goto error;
}
lkc = zmalloc(sizeof(struct ltt_kernel_channel));
if (lkc == NULL) {
- perror("ltt_kernel_channel zmalloc");
+ PERROR("ltt_kernel_channel zmalloc");
goto error;
}
lkc->channel = zmalloc(sizeof(struct lttng_channel));
if (lkc->channel == NULL) {
- perror("lttng_channel zmalloc");
+ PERROR("lttng_channel zmalloc");
goto error;
}
memcpy(lkc->channel, chan, sizeof(struct lttng_channel));
- lkc->fd = 0;
+ lkc->fd = -1;
lkc->stream_count = 0;
lkc->event_count = 0;
lkc->enabled = 1;
/* Set default trace output path */
ret = asprintf(&lkc->pathname, "%s", path);
if (ret < 0) {
- perror("asprintf kernel create channel");
+ PERROR("asprintf kernel create channel");
goto error;
}
lke = zmalloc(sizeof(struct ltt_kernel_event));
attr = zmalloc(sizeof(struct lttng_kernel_event));
if (lke == NULL || attr == NULL) {
- perror("kernel event zmalloc");
+ PERROR("kernel event zmalloc");
goto error;
}
attr->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
/* Setting up a kernel event */
- lke->fd = 0;
+ lke->fd = -1;
lke->event = attr;
lke->enabled = 1;
lke->ctx = NULL;
return lke;
error:
+ free(lke);
+ free(attr);
return NULL;
}
lkm = zmalloc(sizeof(struct ltt_kernel_metadata));
chan = zmalloc(sizeof(struct lttng_channel));
if (lkm == NULL || chan == NULL) {
- perror("kernel metadata zmalloc");
+ PERROR("kernel metadata zmalloc");
goto error;
}
chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
/* Init metadata */
- lkm->fd = 0;
+ lkm->fd = -1;
lkm->conf = chan;
/* Set default metadata path */
ret = asprintf(&lkm->pathname, "%s/metadata", path);
if (ret < 0) {
- perror("asprintf kernel metadata");
+ PERROR("asprintf kernel metadata");
goto error;
}
return lkm;
error:
+ free(lkm);
+ free(chan);
return NULL;
}
lks = zmalloc(sizeof(struct ltt_kernel_stream));
if (lks == NULL) {
- perror("kernel stream zmalloc");
+ PERROR("kernel stream zmalloc");
goto error;
}
/* Init stream */
- lks->fd = 0;
+ lks->fd = -1;
lks->pathname = NULL;
lks->state = 0;
*/
void trace_kernel_destroy_stream(struct ltt_kernel_stream *stream)
{
+ int ret;
+
DBG("[trace] Closing stream fd %d", stream->fd);
/* Close kernel fd */
- close(stream->fd);
+ if (stream->fd >= 0) {
+ ret = close(stream->fd);
+ if (ret) {
+ PERROR("close");
+ }
+ }
/* Remove from stream list */
cds_list_del(&stream->list);
*/
void trace_kernel_destroy_event(struct ltt_kernel_event *event)
{
- DBG("[trace] Closing event fd %d", event->fd);
- /* Close kernel fd */
- close(event->fd);
+ int ret;
+
+ if (event->fd >= 0) {
+ DBG("[trace] Closing event fd %d", event->fd);
+ /* Close kernel fd */
+ ret = close(event->fd);
+ if (ret) {
+ PERROR("close");
+ }
+ } else {
+ DBG("[trace] Tearing down event (no associated fd)");
+ }
/* Remove from event list */
cds_list_del(&event->list);
{
struct ltt_kernel_stream *stream, *stmp;
struct ltt_kernel_event *event, *etmp;
+ int ret;
DBG("[trace] Closing channel fd %d", channel->fd);
/* Close kernel fd */
- close(channel->fd);
+ if (channel->fd >= 0) {
+ ret = close(channel->fd);
+ if (ret) {
+ PERROR("close");
+ }
+ }
/* For each stream in the channel list */
cds_list_for_each_entry_safe(stream, stmp, &channel->stream_list.head, list) {
*/
void trace_kernel_destroy_metadata(struct ltt_kernel_metadata *metadata)
{
+ int ret;
+
DBG("[trace] Closing metadata fd %d", metadata->fd);
/* Close kernel fd */
- close(metadata->fd);
+ if (metadata->fd >= 0) {
+ ret = close(metadata->fd);
+ if (ret) {
+ PERROR("close");
+ }
+ }
free(metadata->conf);
free(metadata->pathname);
void trace_kernel_destroy_session(struct ltt_kernel_session *session)
{
struct ltt_kernel_channel *channel, *ctmp;
+ int ret;
DBG("[trace] Closing session fd %d", session->fd);
/* Close kernel fds */
- close(session->fd);
+ if (session->fd >= 0) {
+ ret = close(session->fd);
+ if (ret) {
+ PERROR("close");
+ }
+ }
- if (session->metadata_stream_fd != 0) {
+ if (session->metadata_stream_fd >= 0) {
DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd);
- close(session->metadata_stream_fd);
+ ret = close(session->metadata_stream_fd);
+ if (ret) {
+ PERROR("close");
+ }
}
if (session->metadata != NULL) {
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_TRACE_KERNEL_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
return lus;
error_free_session:
+ lttng_ht_destroy(lus->domain_global.channels);
+ lttng_ht_destroy(lus->domain_exec);
+ lttng_ht_destroy(lus->domain_pid);
free(lus);
error:
return NULL;
luc = zmalloc(sizeof(struct ltt_ust_channel));
if (luc == NULL) {
- perror("ltt_ust_channel zmalloc");
+ PERROR("ltt_ust_channel zmalloc");
goto error;
}
/* Set trace output path */
ret = snprintf(luc->pathname, PATH_MAX, "%s", path);
if (ret < 0) {
- perror("asprintf ust create channel");
+ PERROR("asprintf ust create channel");
goto error_free_channel;
}
return luc;
error_free_channel:
+ lttng_ht_destroy(luc->ctx);
+ lttng_ht_destroy(luc->events);
free(luc);
error:
return NULL;
lue->attr.loglevel = ev->loglevel;
break;
default:
- ERR("Unknown ust loglevel type (%d)", ev->type);
+ ERR("Unknown ust loglevel type (%d)", ev->loglevel_type);
goto error_free_event;
}
return lue;
error_free_event:
+ lttng_ht_destroy(lue->ctx);
free(lue);
error:
return NULL;
lum = zmalloc(sizeof(struct ltt_ust_metadata));
if (lum == NULL) {
- perror("ust metadata zmalloc");
+ PERROR("ust metadata zmalloc");
goto error;
}
/* Set metadata trace path */
ret = snprintf(lum->pathname, PATH_MAX, "%s/metadata", path);
if (ret < 0) {
- perror("asprintf ust metadata");
+ PERROR("asprintf ust metadata");
goto error_free_metadata;
}
*/
void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata)
{
+ if (!metadata->handle) {
+ return;
+ }
DBG2("Trace UST destroy metadata %d", metadata->handle);
-
free(metadata);
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_TRACE_UST_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include "ust-app.h"
#include "ust-consumer.h"
#include "ust-ctl.h"
+#include "fd-limit.h"
/*
* Delete ust context safely. RCU read lock must be held before calling
{
if (stream->obj) {
ustctl_release_object(sock, stream->obj);
+ lttng_fd_put(LTTNG_FD_APPS, 2);
free(stream->obj);
}
free(stream);
if (ua_chan->obj != NULL) {
ustctl_release_object(sock, ua_chan->obj);
+ lttng_fd_put(LTTNG_FD_APPS, 2);
free(ua_chan->obj);
}
free(ua_chan);
if (ua_sess->metadata) {
if (ua_sess->metadata->stream_obj) {
ustctl_release_object(sock, ua_sess->metadata->stream_obj);
+ lttng_fd_put(LTTNG_FD_APPS, 2);
free(ua_sess->metadata->stream_obj);
}
if (ua_sess->metadata->obj) {
ustctl_release_object(sock, ua_sess->metadata->obj);
+ lttng_fd_put(LTTNG_FD_APPS, 2);
free(ua_sess->metadata->obj);
}
+ trace_ust_destroy_metadata(ua_sess->metadata);
}
cds_lfht_for_each_entry(ua_sess->channels->ht, &iter.iter, ua_chan,
rcu_read_lock();
/* Delete ust app sessions info */
- sock = app->key.sock;
- app->key.sock = -1;
+ sock = app->sock;
+ app->sock = -1;
/* Wipe sessions */
cds_lfht_for_each_entry(app->sessions->ht, &iter.iter, ua_sess,
node.node) {
ret = lttng_ht_del(app->sessions, &iter);
assert(!ret);
- delete_ust_app_session(app->key.sock, ua_sess);
+ delete_ust_app_session(app->sock, ua_sess);
}
lttng_ht_destroy(app->sessions);
/*
- * Wait until we have removed the key from the sock hash table before
- * closing this socket, otherwise an application could re-use the socket ID
- * and race with the teardown, using the same hash table entry.
+ * Wait until we have deleted the application from the sock hash table
+ * before closing this socket, otherwise an application could re-use the
+ * socket ID and race with the teardown, using the same hash table entry.
+ *
+ * It's OK to leave the close in call_rcu. We want it to stay unique for
+ * all RCU readers that could run concurrently with unregister app,
+ * therefore we _need_ to only close that socket after a grace period. So
+ * it should stay in this RCU callback.
+ *
+ * This close() is a very important step of the synchronization model so
+ * every modification to this function must be carefully reviewed.
*/
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ lttng_fd_put(LTTNG_FD_APPS, 1);
- DBG2("UST app pid %d deleted", app->key.pid);
+ DBG2("UST app pid %d deleted", app->pid);
free(app);
rcu_read_unlock();
struct lttng_ht_node_ulong *node =
caa_container_of(head, struct lttng_ht_node_ulong, head);
struct ust_app *app =
- caa_container_of(node, struct ust_app, node);
+ caa_container_of(node, struct ust_app, pid_n);
- DBG3("Call RCU deleting app PID %d", app->key.pid);
+ DBG3("Call RCU deleting app PID %d", app->pid);
delete_ust_app(app);
}
struct ust_app *find_app_by_sock(int sock)
{
struct lttng_ht_node_ulong *node;
- struct ust_app_key *key;
struct lttng_ht_iter iter;
- lttng_ht_lookup(ust_app_sock_key_map, (void *)((unsigned long) sock),
- &iter);
- node = lttng_ht_iter_get_node_ulong(&iter);
- if (node == NULL) {
- DBG2("UST app find by sock %d key not found", sock);
- goto error;
- }
- key = caa_container_of(node, struct ust_app_key, node);
-
- lttng_ht_lookup(ust_app_ht, (void *)((unsigned long) key->pid), &iter);
+ lttng_ht_lookup(ust_app_ht_by_sock, (void *)((unsigned long) sock), &iter);
node = lttng_ht_iter_get_node_ulong(&iter);
if (node == NULL) {
DBG2("UST app find by sock %d not found", sock);
goto error;
}
- return caa_container_of(node, struct ust_app, node);
+
+ return caa_container_of(node, struct ust_app, sock_n);
error:
return NULL;
{
int ret;
- ret = ustctl_add_context(app->key.sock, &ua_ctx->ctx,
+ ret = ustctl_add_context(app->sock, &ua_ctx->ctx,
ua_chan->obj, &ua_ctx->obj);
if (ret < 0) {
goto error;
{
int ret;
- ret = ustctl_add_context(app->key.sock, &ua_ctx->ctx,
+ ret = ustctl_add_context(app->sock, &ua_ctx->ctx,
ua_event->obj, &ua_ctx->obj);
if (ret < 0) {
goto error;
{
int ret;
- ret = ustctl_disable(app->key.sock, ua_event->obj);
+ ret = ustctl_disable(app->sock, ua_event->obj);
if (ret < 0) {
ERR("UST app event %s disable failed for app (pid: %d) "
"and session handle %d with ret %d",
- ua_event->attr.name, app->key.pid, ua_sess->handle, ret);
+ ua_event->attr.name, app->pid, ua_sess->handle, ret);
goto error;
}
DBG2("UST app event %s disabled successfully for app (pid: %d)",
- ua_event->attr.name, app->key.pid);
+ ua_event->attr.name, app->pid);
error:
return ret;
{
int ret;
- ret = ustctl_disable(app->key.sock, ua_chan->obj);
+ ret = ustctl_disable(app->sock, ua_chan->obj);
if (ret < 0) {
ERR("UST app channel %s disable failed for app (pid: %d) "
"and session handle %d with ret %d",
- ua_chan->name, app->key.pid, ua_sess->handle, ret);
+ ua_chan->name, app->pid, ua_sess->handle, ret);
goto error;
}
DBG2("UST app channel %s disabled successfully for app (pid: %d)",
- ua_chan->name, app->key.pid);
+ ua_chan->name, app->pid);
error:
return ret;
{
int ret;
- ret = ustctl_enable(app->key.sock, ua_chan->obj);
+ ret = ustctl_enable(app->sock, ua_chan->obj);
if (ret < 0) {
ERR("UST app channel %s enable failed for app (pid: %d) "
"and session handle %d with ret %d",
- ua_chan->name, app->key.pid, ua_sess->handle, ret);
+ ua_chan->name, app->pid, ua_sess->handle, ret);
goto error;
}
ua_chan->enabled = 1;
DBG2("UST app channel %s enabled successfully for app (pid: %d)",
- ua_chan->name, app->key.pid);
+ ua_chan->name, app->pid);
error:
return ret;
{
int ret;
- ret = ustctl_enable(app->key.sock, ua_event->obj);
+ ret = ustctl_enable(app->sock, ua_event->obj);
if (ret < 0) {
ERR("UST app event %s enable failed for app (pid: %d) "
"and session handle %d with ret %d",
- ua_event->attr.name, app->key.pid, ua_sess->handle, ret);
+ ua_event->attr.name, app->pid, ua_sess->handle, ret);
goto error;
}
DBG2("UST app event %s enabled successfully for app (pid: %d)",
- ua_event->attr.name, app->key.pid);
+ ua_event->attr.name, app->pid);
error:
return ret;
ua_sess->metadata->attr.read_timer_interval;
uattr.output = ua_sess->metadata->attr.output;
+ /* We are going to receive 2 fds, we need to reserve them. */
+ ret = lttng_fd_get(LTTNG_FD_APPS, 2);
+ if (ret < 0) {
+ ERR("Exhausted number of available FD upon metadata open");
+ goto error;
+ }
/* UST tracer metadata creation */
- ret = ustctl_open_metadata(app->key.sock, ua_sess->handle, &uattr,
+ ret = ustctl_open_metadata(app->sock, ua_sess->handle, &uattr,
&ua_sess->metadata->obj);
if (ret < 0) {
ERR("UST app open metadata failed for app pid:%d with ret %d",
- app->key.pid, ret);
+ app->pid, ret);
goto error;
}
{
int ret;
- ret = ustctl_create_stream(app->key.sock, ua_sess->metadata->obj,
+ /* We are going to receive 2 fds, we need to reserve them. */
+ ret = lttng_fd_get(LTTNG_FD_APPS, 2);
+ if (ret < 0) {
+ ERR("Exhausted number of available FD upon metadata stream create");
+ goto error;
+ }
+ ret = ustctl_create_stream(app->sock, ua_sess->metadata->obj,
&ua_sess->metadata->stream_obj);
if (ret < 0) {
ERR("UST create metadata stream failed");
int ret;
/* TODO: remove cast and use lttng-ust-abi.h */
- ret = ustctl_create_channel(app->key.sock, ua_sess->handle,
+
+ /* We are going to receive 2 fds, we need to reserve them. */
+ ret = lttng_fd_get(LTTNG_FD_APPS, 2);
+ if (ret < 0) {
+ ERR("Exhausted number of available FD upon create channel");
+ goto error;
+ }
+ ret = ustctl_create_channel(app->sock, ua_sess->handle,
(struct lttng_ust_channel_attr *)&ua_chan->attr, &ua_chan->obj);
if (ret < 0) {
ERR("Creating channel %s for app (pid: %d, sock: %d) "
"and session handle %d with ret %d",
- ua_chan->name, app->key.pid, app->key.sock,
+ ua_chan->name, app->pid, app->sock,
ua_sess->handle, ret);
+ lttng_fd_put(LTTNG_FD_APPS, 2);
goto error;
}
ua_chan->handle = ua_chan->obj->handle;
DBG2("UST app channel %s created successfully for pid:%d and sock:%d",
- ua_chan->name, app->key.pid, app->key.sock);
+ ua_chan->name, app->pid, app->sock);
/* If channel is not enabled, disable it on the tracer */
if (!ua_chan->enabled) {
int ret = 0;
/* Create UST event on tracer */
- ret = ustctl_create_event(app->key.sock, &ua_event->attr, ua_chan->obj,
+ ret = ustctl_create_event(app->sock, &ua_event->attr, ua_chan->obj,
&ua_event->obj);
if (ret < 0) {
if (ret == -EEXIST) {
goto error;
}
ERR("Error ustctl create event %s for app pid: %d with ret %d",
- ua_event->attr.name, app->key.pid, ret);
+ ua_event->attr.name, app->pid, ret);
goto error;
}
ua_event->handle = ua_event->obj->handle;
DBG2("UST app event %s created successfully for pid:%d",
- ua_event->attr.name, app->key.pid);
+ ua_event->attr.name, app->pid);
/* If event not enabled, disable it on the tracer */
if (ua_event->enabled == 0) {
ua_sess->gid = usess->gid;
ret = snprintf(ua_sess->path, PATH_MAX, "%s/%s-%d-%s", usess->pathname,
- app->name, app->key.pid, datetime);
+ app->name, app->pid, datetime);
if (ret < 0) {
PERROR("asprintf UST shadow copy session");
/* TODO: We cannot return an error from here.. */
ua_sess = lookup_session_by_app(usess, app);
if (ua_sess == NULL) {
DBG2("UST app pid: %d session id %d not found, creating it",
- app->key.pid, usess->id);
+ app->pid, usess->id);
ua_sess = alloc_ust_app_session();
if (ua_sess == NULL) {
/* Only malloc can failed so something is really wrong */
}
if (ua_sess->handle == -1) {
- ret = ustctl_create_session(app->key.sock);
+ ret = ustctl_create_session(app->sock);
if (ret < 0) {
- ERR("Creating session for app pid %d", app->key.pid);
+ ERR("Creating session for app pid %d", app->pid);
/* This means that the tracer is gone... */
ua_sess = (void*) -1UL;
goto error;
lttng_ht_add_unique_str(ua_sess->channels, &ua_chan->node);
DBG2("UST app create channel %s for PID %d completed", ua_chan->name,
- app->key.pid);
+ app->pid);
end:
return ua_chan;
lttng_ht_add_unique_str(ua_chan->events, &ua_event->node);
DBG2("UST app create event %s for PID %d completed", ua_event->name,
- app->key.pid);
+ app->pid);
end:
return ret;
goto error;
}
- DBG2("UST metadata opened for app pid %d", app->key.pid);
+ DBG2("UST metadata opened for app pid %d", app->pid);
}
/* Open UST metadata stream */
}
DBG2("UST metadata stream object created for app pid %d",
- app->key.pid);
+ app->pid);
} else {
ERR("Attempting to create stream without metadata opened");
goto error;
DBG2("Found UST app by pid %d", pid);
- return caa_container_of(node, struct ust_app, node);
+ return caa_container_of(node, struct ust_app, pid_n);
error:
rcu_read_unlock();
int ust_app_register(struct ust_register_msg *msg, int sock)
{
struct ust_app *lta;
+ int ret;
if ((msg->bits_per_long == 64 && ust_consumerd64_fd == -EINVAL)
|| (msg->bits_per_long == 32 && ust_consumerd32_fd == -EINVAL)) {
ERR("Registration failed: application \"%s\" (pid: %d) has "
"%d-bit long, but no consumerd for this long size is available.\n",
msg->name, msg->pid, msg->bits_per_long);
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ lttng_fd_put(LTTNG_FD_APPS, 1);
return -EINVAL;
}
if (msg->major != LTTNG_UST_COMM_MAJOR) {
ERR("Registration failed: application \"%s\" (pid: %d) has "
"communication protocol version %u.%u, but sessiond supports 2.x.\n",
msg->name, msg->pid, msg->major, msg->minor);
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ lttng_fd_put(LTTNG_FD_APPS, 1);
return -EINVAL;
}
lta = zmalloc(sizeof(struct ust_app));
lta->name[16] = '\0';
lta->sessions = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
- /* Set key map */
- lta->key.pid = msg->pid;
- lttng_ht_node_init_ulong(<a->node, (unsigned long)lta->key.pid);
- lta->key.sock = sock;
- lttng_ht_node_init_ulong(<a->key.node, (unsigned long)lta->key.sock);
+ lta->pid = msg->pid;
+ lttng_ht_node_init_ulong(<a->pid_n, (unsigned long)lta->pid);
+ lta->sock = sock;
+ lttng_ht_node_init_ulong(<a->sock_n, (unsigned long)lta->sock);
rcu_read_lock();
- lttng_ht_add_unique_ulong(ust_app_sock_key_map, <a->key.node);
- lttng_ht_add_unique_ulong(ust_app_ht, <a->node);
+
+ /*
+ * On a re-registration, we want to kick out the previous registration of
+ * that pid
+ */
+ lttng_ht_add_replace_ulong(ust_app_ht, <a->pid_n);
+
+ /*
+ * The socket _should_ be unique until _we_ call close. So, a add_unique
+ * for the ust_app_ht_by_sock is used which asserts fail if the entry was
+ * already in the table.
+ */
+ lttng_ht_add_unique_ulong(ust_app_ht_by_sock, <a->sock_n);
+
rcu_read_unlock();
DBG("App registered with pid:%d ppid:%d uid:%d gid:%d sock:%d name:%s"
- " (version %d.%d)", lta->key.pid, lta->ppid, lta->uid, lta->gid,
- lta->key.sock, lta->name, lta->v_major, lta->v_minor);
+ " (version %d.%d)", lta->pid, lta->ppid, lta->uid, lta->gid,
+ lta->sock, lta->name, lta->v_major, lta->v_minor);
return 0;
}
int ret;
rcu_read_lock();
- lta = find_app_by_sock(sock);
- if (lta == NULL) {
- ERR("Unregister app sock %d not found!", sock);
- goto error;
- }
-
- DBG("PID %d unregistering with sock %d", lta->key.pid, sock);
-
- /* Remove application from socket hash table */
- lttng_ht_lookup(ust_app_sock_key_map, (void *)((unsigned long) sock), &iter);
- ret = lttng_ht_del(ust_app_sock_key_map, &iter);
- assert(!ret);
/* Get the node reference for a call_rcu */
- lttng_ht_lookup(ust_app_ht, (void *)((unsigned long) lta->key.pid), &iter);
+ lttng_ht_lookup(ust_app_ht_by_sock, (void *)((unsigned long) sock), &iter);
node = lttng_ht_iter_get_node_ulong(&iter);
if (node == NULL) {
- ERR("Unable to find app sock %d by pid %d", sock, lta->key.pid);
+ ERR("Unable to find app by sock %d", sock);
goto error;
}
+ lta = caa_container_of(node, struct ust_app, sock_n);
+
+ DBG("PID %d unregistering with sock %d", lta->pid, sock);
+
/* Remove application from PID hash table */
+ ret = lttng_ht_del(ust_app_ht_by_sock, &iter);
+ assert(!ret);
+
+ /* Assign second node for deletion */
+ iter.iter.node = <a->pid_n.node;
+
ret = lttng_ht_del(ust_app_ht, &iter);
assert(!ret);
- call_rcu(&node->head, delete_ust_app_rcu);
+
+ /* Free memory */
+ call_rcu(<a->pid_n.head, delete_ust_app_rcu);
+
error:
rcu_read_unlock();
return;
rcu_read_lock();
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
struct lttng_ust_tracepoint_iter uiter;
if (!app->compatible) {
*/
continue;
}
- handle = ustctl_tracepoint_list(app->key.sock);
+ handle = ustctl_tracepoint_list(app->sock);
if (handle < 0) {
ERR("UST app list events getting handle failed for app pid %d",
- app->key.pid);
+ app->pid);
continue;
}
- while ((ret = ustctl_tracepoint_list_get(app->key.sock, handle,
+ while ((ret = ustctl_tracepoint_list_get(app->sock, handle,
&uiter)) != -ENOENT) {
if (count >= nbmem) {
DBG2("Reallocating event list from %zu to %zu entries", nbmem,
memcpy(tmp[count].name, uiter.name, LTTNG_UST_SYM_NAME_LEN);
tmp[count].loglevel = uiter.loglevel;
tmp[count].type = LTTNG_UST_TRACEPOINT;
- tmp[count].pid = app->key.pid;
+ tmp[count].pid = app->pid;
tmp[count].enabled = -1;
count++;
}
assert(!ret);
call_rcu(&node->head, delete_ust_app_rcu);
}
- /* Destroy is done only when the ht is empty */
- lttng_ht_destroy(ust_app_ht);
- cds_lfht_for_each_entry(ust_app_sock_key_map->ht, &iter.iter, node, node) {
- ret = lttng_ht_del(ust_app_sock_key_map, &iter);
+ /* Cleanup socket hash table */
+ cds_lfht_for_each_entry(ust_app_ht_by_sock->ht, &iter.iter, node, node) {
+ ret = lttng_ht_del(ust_app_ht_by_sock, &iter);
assert(!ret);
}
+
/* Destroy is done only when the ht is empty */
- lttng_ht_destroy(ust_app_sock_key_map);
+ lttng_ht_destroy(ust_app_ht);
+ lttng_ht_destroy(ust_app_ht_by_sock);
rcu_read_unlock();
}
void ust_app_ht_alloc(void)
{
ust_app_ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
- ust_app_sock_key_map = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
+ ust_app_ht_by_sock = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
}
/*
rcu_read_lock();
/* For every registered applications */
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
struct lttng_ht_iter uiter;
if (!app->compatible) {
/*
rcu_read_lock();
/* For every registered applications */
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
rcu_read_lock();
/* For all registered applications */
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
if (ua_chan_node == NULL) {
DBG2("Channel %s not found in session id %d for app pid %d."
- "Skipping", uchan->name, usess->id, app->key.pid);
+ "Skipping", uchan->name, usess->id, app->pid);
continue;
}
ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
ua_event_node = lttng_ht_iter_get_node_str(&uiter);
if (ua_event_node == NULL) {
DBG2("Event %s not found in channel %s for app pid %d."
- "Skipping", uevent->attr.name, uchan->name, app->key.pid);
+ "Skipping", uevent->attr.name, uchan->name, app->pid);
continue;
}
ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
rcu_read_lock();
/* For all registered applications */
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
rcu_read_lock();
/* For every registered applications */
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
rcu_read_lock();
/* For all registered applications */
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
ua_event_node = lttng_ht_iter_get_node_str(&uiter);
if (ua_event_node == NULL) {
DBG3("UST app enable event %s not found for app PID %d."
- "Skipping app", uevent->attr.name, app->key.pid);
+ "Skipping app", uevent->attr.name, app->pid);
continue;
}
ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
rcu_read_lock();
/* For all registered applications */
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
break;
}
DBG2("UST app event %s already exist on app PID %d",
- uevent->attr.name, app->key.pid);
+ uevent->attr.name, app->pid);
continue;
}
}
struct ltt_ust_stream *ustream;
int consumerd_fd;
- DBG("Starting tracing for ust app pid %d", app->key.pid);
+ DBG("Starting tracing for ust app pid %d", app->pid);
rcu_read_lock();
goto error_rcu_unlock;
}
- ret = ustctl_create_stream(app->key.sock, ua_chan->obj,
+ /* We are going to receive 2 fds, we need to reserve them. */
+ ret = lttng_fd_get(LTTNG_FD_APPS, 2);
+ if (ret < 0) {
+ ERR("Exhausted number of available FD upon stream create");
+ free(ustream);
+ goto error_rcu_unlock;
+ }
+ ret = ustctl_create_stream(app->sock, ua_chan->obj,
&ustream->obj);
if (ret < 0) {
/* Got all streams */
+ lttng_fd_put(LTTNG_FD_APPS, 2);
+ free(ustream);
break;
}
ustream->handle = ustream->obj->handle;
ua_chan->streams.count++);
if (ret < 0) {
PERROR("asprintf UST create stream");
+ /*
+ * XXX what should we do here with the
+ * stream ?
+ */
continue;
}
DBG2("UST stream %d ready at %s", ua_chan->streams.count,
skip_setup:
/* This start the UST tracing */
- ret = ustctl_start_session(app->key.sock, ua_sess->handle);
+ ret = ustctl_start_session(app->sock, ua_sess->handle);
if (ret < 0) {
- ERR("Error starting tracing for app pid: %d", app->key.pid);
+ ERR("Error starting tracing for app pid: %d", app->pid);
goto error_rcu_unlock;
}
/* Quiescent wait after starting trace */
- ustctl_wait_quiescent(app->key.sock);
+ ustctl_wait_quiescent(app->sock);
end:
rcu_read_unlock();
struct ust_app_session *ua_sess;
struct ust_app_channel *ua_chan;
- DBG("Stopping tracing for ust app pid %d", app->key.pid);
+ DBG("Stopping tracing for ust app pid %d", app->pid);
rcu_read_lock();
assert(ua_sess->started == 1);
/* This inhibits UST tracing */
- ret = ustctl_stop_session(app->key.sock, ua_sess->handle);
+ ret = ustctl_stop_session(app->sock, ua_sess->handle);
if (ret < 0) {
- ERR("Error stopping tracing for app pid: %d", app->key.pid);
+ ERR("Error stopping tracing for app pid: %d", app->pid);
goto error_rcu_unlock;
}
/* Quiescent wait after stopping trace */
- ustctl_wait_quiescent(app->key.sock);
+ ustctl_wait_quiescent(app->sock);
/* Flushing buffers */
cds_lfht_for_each_entry(ua_sess->channels->ht, &iter.iter, ua_chan,
node.node) {
- ret = ustctl_sock_flush_buffer(app->key.sock, ua_chan->obj);
+ ret = ustctl_sock_flush_buffer(app->sock, ua_chan->obj);
if (ret < 0) {
ERR("UST app PID %d channel %s flush failed with ret %d",
- app->key.pid, ua_chan->name, ret);
+ app->pid, ua_chan->name, ret);
/* Continuing flushing all buffers */
continue;
}
}
/* Flush all buffers before stopping */
- ret = ustctl_sock_flush_buffer(app->key.sock, ua_sess->metadata->obj);
+ ret = ustctl_sock_flush_buffer(app->sock, ua_sess->metadata->obj);
if (ret < 0) {
- ERR("UST app PID %d metadata flush failed with ret %d", app->key.pid,
+ ERR("UST app PID %d metadata flush failed with ret %d", app->pid,
ret);
}
struct lttng_ht_node_ulong *node;
int ret;
- DBG("Destroy tracing for ust app pid %d", app->key.pid);
+ DBG("Destroy tracing for ust app pid %d", app->pid);
rcu_read_lock();
obj.shm_fd = -1;
obj.wait_fd = -1;
obj.memory_map_size = 0;
- ustctl_release_object(app->key.sock, &obj);
+ ustctl_release_object(app->sock, &obj);
- delete_ust_app_session(app->key.sock, ua_sess);
+ delete_ust_app_session(app->sock, ua_sess);
/* Quiescent wait after stopping trace */
- ustctl_wait_quiescent(app->key.sock);
+ ustctl_wait_quiescent(app->sock);
end:
rcu_read_unlock();
rcu_read_lock();
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
ret = ust_app_start_trace(usess, app);
if (ret < 0) {
/* Continue to next apps even on error */
rcu_read_lock();
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
ret = ust_app_stop_trace(usess, app);
if (ret < 0) {
/* Continue to next apps even on error */
rcu_read_lock();
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
ret = ust_app_destroy_trace(usess, app);
if (ret < 0) {
/* Continue to next apps even on error */
goto error;
}
- DBG2("UST trace started for app pid %d", app->key.pid);
+ DBG2("UST trace started for app pid %d", app->pid);
}
error:
rcu_read_lock();
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
rcu_read_lock();
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
}
DBG2("UST app PID %d is compatible with major version %d "
- "(supporting <= %d)", app->key.pid, app->version.major,
+ "(supporting <= %d)", app->pid, app->version.major,
UST_APP_MAJOR_VERSION);
app->compatible = 1;
rcu_read_unlock();
error:
DBG2("UST app PID %d is not compatible with major version %d "
- "(supporting <= %d)", app->key.pid, app->version.major,
+ "(supporting <= %d)", app->pid, app->version.major,
UST_APP_MAJOR_VERSION);
app->compatible = 0;
rcu_read_unlock();
rcu_read_lock();
- cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, node.node) {
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
if (!app->compatible) {
/*
* TODO: In time, we should notice the caller of this error by
continue;
}
- ret = ustctl_calibrate(app->key.sock, calibrate);
+ ret = ustctl_calibrate(app->sock, calibrate);
if (ret < 0) {
switch (ret) {
case -ENOSYS:
default:
/* TODO: Report error to user */
DBG2("Calibrate app PID %d returned with error %d",
- app->key.pid, ret);
+ app->pid, ret);
break;
}
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_UST_APP_H
};
/*
- * Global applications HT used by the session daemon.
+ * Global applications HT used by the session daemon. This table is indexed by
+ * PID using the pid_n node and pid value of an ust_app.
*/
struct lttng_ht *ust_app_ht;
-struct lttng_ht *ust_app_sock_key_map;
-
-struct ust_app_key {
- pid_t pid;
- int sock;
- struct lttng_ht_node_ulong node;
-};
+/*
+ * Global applications HT used by the session daemon. This table is indexed by
+ * socket using the sock_n node and sock value of an ust_app.
+ */
+struct lttng_ht *ust_app_ht_by_sock;
struct ust_app_ctx {
int handle;
* and a linked list is kept of all running traceable app.
*/
struct ust_app {
+ int sock;
+ pid_t pid;
pid_t ppid;
uid_t uid; /* User ID that owns the apps */
gid_t gid; /* Group ID that owns the apps */
uint32_t v_minor; /* Verion minor number */
char name[17]; /* Process name (short) */
struct lttng_ht *sessions;
- struct lttng_ht_node_ulong node;
- struct ust_app_key key;
+ struct lttng_ht_node_ulong pid_n;
+ struct lttng_ht_node_ulong sock_n;
};
#ifdef HAVE_LIBLTTNG_UST_CTL
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
DBG("Sending channel %d to consumer", lum.u.channel.channel_key);
ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
if (ret < 0) {
- perror("send consumer channel");
+ PERROR("send consumer channel");
goto error;
}
fd = uchan->obj->shm_fd;
ret = lttcomm_send_fds_unix_sock(sock, &fd, 1);
if (ret < 0) {
- perror("send consumer channel ancillary data");
+ PERROR("send consumer channel ancillary data");
goto error;
}
DBG("Sending stream %d to consumer", lum.u.stream.stream_key);
ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
fds[1] = stream->obj->wait_fd;
ret = lttcomm_send_fds_unix_sock(sock, fds, 2);
if (ret < 0) {
- perror("send consumer stream ancillary data");
+ PERROR("send consumer stream ancillary data");
goto error;
}
}
DBG("Sending metadata channel %d to consumer", lum.u.channel.channel_key);
ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
if (ret < 0) {
- perror("send consumer channel");
+ PERROR("send consumer channel");
goto error;
}
fd = usess->metadata->obj->shm_fd;
ret = lttcomm_send_fds_unix_sock(sock, &fd, 1);
if (ret < 0) {
- perror("send consumer metadata channel");
+ PERROR("send consumer metadata channel");
goto error;
}
DBG("Sending metadata stream %d to consumer", lum.u.stream.stream_key);
ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
if (ret < 0) {
- perror("send consumer metadata stream");
+ PERROR("send consumer metadata stream");
goto error;
}
fds[0] = usess->metadata->stream_obj->shm_fd;
fds[1] = usess->metadata->stream_obj->wait_fd;
ret = lttcomm_send_fds_unix_sock(sock, fds, 2);
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
}
rcu_read_lock();
cds_lfht_for_each_entry(usess->channels->ht, &iter.iter, ua_chan,
node.node) {
+ /*
+ * Indicate that the channel was not created on the tracer side so skip
+ * sending unexisting streams.
+ */
+ if (ua_chan->obj == NULL) {
+ continue;
+ }
+
ret = send_channel_streams(sock, ua_chan, usess->uid, usess->gid);
if (ret < 0) {
rcu_read_unlock();
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _UST_CONSUMER_H
*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_UST_CTL_H
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_UTILS_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_CMD_H
#include "utils.h"
enum cmd_error_code {
- CMD_SUCCESS,
+ CMD_SUCCESS = 0,
CMD_ERROR,
CMD_UNDEFINED,
CMD_FATAL,
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include "../command.h"
#include "../utils.h"
+#include <common/sessiond-comm/sessiond-comm.h>
+
static char *opt_output_path;
static char *opt_session_name;
ret = lttng_create_session(session_name, traces_path);
if (ret < 0) {
/* Don't set ret so lttng can interpret the sessiond error. */
+ switch (-ret) {
+ case LTTCOMM_EXIST_SESS:
+ WARN("Session %s already exists", session_name);
+ break;
+ }
goto error;
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include "../command.h"
+#include <common/sessiond-comm/sessiond-comm.h>
+
static char *opt_session_name;
enum {
ret = lttng_destroy_session(session_name);
if (ret < 0) {
- /* Don't set ret so lttng can interpret the sessiond error. */
+ switch (-ret) {
+ case LTTCOMM_SESS_NOT_FOUND:
+ WARN("Session name %s not found", session_name);
+ break;
+ default:
+ break;
+ }
goto free_name;
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include "../command.h"
+#include <src/common/sessiond-comm/sessiond-comm.h>
+
static char *opt_channels;
static int opt_kernel;
static char *opt_session_name;
ret = lttng_enable_channel(handle, &chan);
if (ret < 0) {
- ERR("Channel %s: %s (session %s)", channel_name,
- lttng_strerror(ret), session_name);
+ switch (-ret) {
+ case LTTCOMM_KERN_CHAN_EXIST:
+ case LTTCOMM_UST_CHAN_EXIST:
+ WARN("Channel %s: %s (session %s", channel_name,
+ lttng_strerror(ret), session_name);
+ goto error;
+ default:
+ ERR("Channel %s: %s (session %s)", channel_name,
+ lttng_strerror(ret), session_name);
+ break;
+ }
warn = 1;
} else {
MSG("%s channel %s enabled for session %s",
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include <ctype.h>
#include "../command.h"
+#include <src/common/sessiond-comm/sessiond-comm.h>
static char *opt_event_list;
static int opt_event_type;
ret = lttng_enable_event(handle, &ev, channel_name);
if (ret < 0) {
- goto error;
+ switch (-ret) {
+ case LTTCOMM_KERN_EVENT_EXIST:
+ WARN("Kernel events already enabled (channel %s, session %s)",
+ channel_name, session_name);
+ break;
+ default:
+ ERR("Events: %s (channel %s, session %s)",
+ lttng_strerror(ret), channel_name, session_name);
+ break;
+ }
+ goto end;
}
switch (opt_event_type) {
ret = lttng_enable_event(handle, &ev, channel_name);
if (ret < 0) {
- ERR("Event %s: %s (channel %s, session %s)", event_name,
- lttng_strerror(ret), channel_name, session_name);
+ /* Turn ret to positive value to handle the positive error code */
+ switch (-ret) {
+ case LTTCOMM_KERN_EVENT_EXIST:
+ WARN("Kernel event %s already enabled (channel %s, session %s)",
+ event_name, channel_name, session_name);
+ break;
+ default:
+ ERR("Event %s: %s (channel %s, session %s)", event_name,
+ lttng_strerror(ret), channel_name, session_name);
+ break;
+ }
warn = 1;
} else {
MSG("%s event %s created in channel %s",
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include "../command.h"
+#include <common/sessiond-comm/sessiond-comm.h>
+
static char *opt_session_name;
enum {
ret = lttng_start_tracing(session_name);
if (ret < 0) {
- /* Don't set ret so lttng can interpret the sessiond error. */
+ switch (-ret) {
+ case LTTCOMM_TRACE_ALREADY_STARTED:
+ WARN("Tracing already started for session %s", session_name);
+ break;
+ default:
+ ERR("%s", lttng_strerror(ret));
+ break;
+ }
goto free_name;
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include "../command.h"
+#include <common/sessiond-comm/sessiond-comm.h>
+
static char *opt_session_name;
enum {
ret = lttng_stop_tracing(session_name);
if (ret < 0) {
- /* Don't set ret so lttng can interpret the sessiond error. */
+ switch (-ret) {
+ case LTTCOMM_TRACE_ALREADY_STOPPED:
+ WARN("Tracing already stopped for session %s", session_name);
+ break;
+ default:
+ ERR("%s", lttng_strerror(ret));
+ break;
+ }
goto free_name;
}
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
}
}
- MSG("lttng version " VERSION);
+ MSG("lttng version " VERSION " - " VERSION_NAME);
MSG("Web site: http://lttng.org/");
- MSG("\nlttng is free software and under the GPL license.");
+ MSG("\nlttng is free software and under the GPL license and part LGPL");
end:
poptFreeContext(pc);
/*
* Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
ret = execvp(viewer_bin, argv);
if (ret) {
- PERROR("exec: %s", viewer_bin);
+ if (errno == ENOENT) {
+ ERR("%s not found on the system", viewer_bin);
+ } else {
+ PERROR("exec: %s", viewer_bin);
+ }
free(argv);
ret = CMD_FATAL;
goto error;
goto free_sessions;
}
- ret = CMD_SUCCESS;
-
free_sessions:
if (sessions) {
free(sessions);
* Copyright (c) 2011 David Goulet <david.goulet@polymtl.ca>
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_CONFIG_H
* Copyright (c) 2011 David Goulet <david.goulet@polymtl.ca>
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
#include <sys/wait.h>
#include <unistd.h>
#include <config.h>
+#include <ctype.h>
#include <lttng/lttng.h>
#include <common/error.h>
/* Variables */
static char *progname;
-
-int opt_quiet;
-int opt_verbose;
static int opt_no_sessiond;
static char *opt_sessiond_path;
static pid_t sessiond_pid;
static void usage(FILE *ofp)
{
- fprintf(ofp, "LTTng Trace Control " VERSION"\n\n");
+ fprintf(ofp, "LTTng Trace Control " VERSION" - " VERSION_NAME"\n\n");
fprintf(ofp, "usage: lttng [OPTIONS] <COMMAND>\n");
fprintf(ofp, "\n");
fprintf(ofp, "Options:\n");
ret = 0;
goto end;
case 'v':
- opt_verbose += 1;
+ lttng_opt_verbose += 1;
break;
case 'q':
- opt_quiet = 1;
+ lttng_opt_quiet = 1;
break;
case 'g':
lttng_set_tracing_group(optarg);
}
/* If both options are specified, quiet wins */
- if (opt_verbose && opt_quiet) {
- opt_verbose = 0;
+ if (lttng_opt_verbose && lttng_opt_quiet) {
+ lttng_opt_verbose = 0;
}
/* Spawn session daemon if needed */
case 0:
break;
default:
- ERR("%s", lttng_strerror(ret));
+ if (ret < 0) {
+ ret = -ret;
+ }
break;
}
/*
* Copyright (c) 2011 David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#define _GNU_SOURCE
#include <stdlib.h>
#include <ctype.h>
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_UTILS_H
AM_CPPFLAGS =
-SUBDIRS = hashtable kernel-ctl sessiond-comm kernel-consumer ust-consumer
+SUBDIRS = compat hashtable kernel-ctl sessiond-comm kernel-consumer ust-consumer
AM_CFLAGS = -fno-strict-aliasing
libconsumer_la_LIBADD = \
$(top_builddir)/src/common/sessiond-comm/libsessiond-comm.la \
$(top_builddir)/src/common/kernel-consumer/libkernel-consumer.la \
- $(top_builddir)/src/common/hashtable/libhashtable.la
+ $(top_builddir)/src/common/hashtable/libhashtable.la \
+ $(top_builddir)/src/common/compat/libcompat.la
if HAVE_LIBLTTNG_UST_CTL
libconsumer_la_LIBADD += \
$(top_builddir)/src/common/ust-consumer/libust-consumer.la
endif
-
-if COMPAT_EPOLL
-COMPAT=compat/compat-epoll.c
-else
-COMPAT=compat/compat-poll.c
-endif
-
-noinst_LTLIBRARIES += libcompat.la
-
-libcompat_la_SOURCES = compat/poll.h $(COMPAT)
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _COMMON_H
--- /dev/null
+AM_CPPFLAGS = -I$(top_srcdir)/include
+
+noinst_LTLIBRARIES = libcompat.la
+
+if COMPAT_EPOLL
+COMPAT=compat-epoll.c
+else
+COMPAT=compat-poll.c
+endif
+
+libcompat_la_SOURCES = poll.h fcntl.h endian.h mman.h clone.h \
+ socket.h compat-fcntl.c $(COMPAT)
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _COMPAT_CLONE_H
+#define _COMPAT_CLONE_H
+
+#ifdef __linux__
+
+#include <sched.h>
+
+static inline
+pid_t lttng_clone_files(int (*fn)(void *), void *child_stack, void *arg)
+{
+ return clone(fn, child_stack, CLONE_FILES | SIGCHLD, arg);
+}
+
+#elif defined(__FreeBSD__)
+
+#include <unistd.h>
+
+static inline
+pid_t lttng_clone_files(int (*fn)(void *), void *child_stack, void *arg)
+{
+ pid_t pid;
+
+ pid = rfork(RFPROC | RFTHREAD);
+ if (pid == 0) {
+ /* child */
+ int ret;
+
+ ret = fn(arg);
+ exit(ret);
+ } else if (pid > 0) {
+ /* parent */
+ /*
+ * Just return, the caller will wait for the child.
+ */
+ return pid;
+ } else {
+ /* Error */
+ return pid;
+ }
+}
+
+#else
+#error "Please add support for your OS."
+#endif /* __linux__ , __FreeBSD__ */
+
+#endif /* _COMPAT_CLONE_H */
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#define _GNU_SOURCE
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
ret = epoll_create1(flags);
if (ret < 0) {
/* At this point, every error is fatal */
- perror("epoll_create1");
+ PERROR("epoll_create1");
goto error;
}
/* This *must* be freed by using lttng_poll_free() */
events->events = zmalloc(size * sizeof(struct epoll_event));
if (events->events == NULL) {
- perror("zmalloc epoll set");
+ PERROR("zmalloc epoll set");
goto error_close;
}
return 0;
error_close:
- close(events->epfd);
+ ret = close(events->epfd);
+ if (ret) {
+ PERROR("close");
+ }
error:
return -1;
}
goto end;
case ENOSPC:
case EPERM:
- /* Print perror and goto end not failing. Show must go on. */
- perror("epoll_ctl ADD");
+ /* Print PERROR and goto end not failing. Show must go on. */
+ PERROR("epoll_ctl ADD");
goto end;
default:
- perror("epoll_ctl ADD fatal");
+ PERROR("epoll_ctl ADD fatal");
goto error;
}
}
new_size = 2 * events->events_size;
ptr = realloc(events->events, new_size * sizeof(struct epoll_event));
if (ptr == NULL) {
- perror("realloc epoll add");
+ PERROR("realloc epoll add");
goto error;
}
events->events = ptr;
switch (errno) {
case ENOENT:
case EPERM:
- /* Print perror and goto end not failing. Show must go on. */
- perror("epoll_ctl DEL");
+ /* Print PERROR and goto end not failing. Show must go on. */
+ PERROR("epoll_ctl DEL");
goto end;
default:
- perror("epoll_ctl DEL fatal");
+ PERROR("epoll_ctl DEL fatal");
goto error;
}
- perror("epoll_ctl del");
+ PERROR("epoll_ctl del");
goto error;
}
} while (ret == -1 && errno == EINTR);
if (ret < 0) {
/* At this point, every error is fatal */
- perror("epoll_wait");
+ PERROR("epoll_wait");
goto error;
}
ret = read(fd, buf, sizeof(buf));
if (ret < 0) {
- perror("read set max size");
+ PERROR("read set max size");
goto error;
}
DBG("epoll set max size is %d", poll_max_size);
error:
- close(fd);
+ ret = close(fd);
+ if (ret) {
+ PERROR("close");
+ }
}
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+#include <common/compat/fcntl.h>
+
+#ifdef __linux__
+
+int compat_sync_file_range(int fd, off64_t offset, off64_t nbytes,
+ unsigned int flags)
+{
+ return sync_file_range(fd, offset, nbytes, flags);
+}
+
+#endif /* __linux__ */
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/time.h>
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef _COMPAT_ENDIAN_H
+#define _COMPAT_ENDIAN_H
+
+#ifdef __linux__
+#include <endian.h>
+#elif defined(__FreeBSD__)
+#include <machine/endian.h>
+#else
+#error "Please add support for your OS."
+#endif
+
+#endif /* _COMPAT_ENDIAN_H */
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _COMPAT_FCNTL_H
+#define _COMPAT_FCNTL_H
+
+#include <fcntl.h>
+#include <sys/types.h>
+
+#ifdef __linux__
+
+extern int compat_sync_file_range(int fd, off64_t offset, off64_t nbytes,
+ unsigned int flags);
+#define lttng_sync_file_range(fd, offset, nbytes, flags) \
+ compat_sync_file_range(fd, offset, nbytes, flags)
+
+#elif defined(__FreeBSD__)
+
+typedef long int off64_t;
+typedef off64_t loff_t;
+
+#include <sys/errno.h>
+
+/*
+ * Possible flags under Linux. Simply nullify them and avoid wrapper.
+ */
+#define SYNC_FILE_RANGE_WAIT_AFTER 0
+#define SYNC_FILE_RANGE_WAIT_BEFORE 0
+#define SYNC_FILE_RANGE_WRITE 0
+
+/*
+ * Possible flags under Linux. Simply nullify them and avoid wrappers.
+ */
+#define SPLICE_F_MOVE 0
+#define SPLICE_F_NONBLOCK 0
+#define SPLICE_F_MORE 0
+#define SPLICE_F_GIFT 0
+
+#define POSIX_FADV_DONTNEED 0
+
+static inline int lttng_sync_file_range(int fd, off64_t offset,
+ off64_t nbytes, unsigned int flags)
+{
+ return -ENOSYS;
+}
+
+static inline ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out,
+ size_t len, unsigned int flags)
+{
+ return -ENOSYS;
+}
+
+static inline int posix_fadvise(int fd, off_t offset, off_t len, int advice)
+{
+ return -ENOSYS;
+}
+
+#else
+#error "Please add support for your OS."
+#endif /* __linux__ , __FreeBSD__ */
+
+#endif /* _COMPAT_FCNTL_H */
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _COMPAT_MMAN_H
+#define _COMPAT_MMAN_H
+
+#include <sys/mman.h>
+
+#ifdef __linux__
+
+#elif defined(__FreeBSD__)
+
+#define MAP_GROWSDOWN 0
+#define MAP_ANONYMOUS MAP_ANON
+
+#else
+#error "Please add support for your OS."
+#endif /* __linux__ , __FreeBSD__ */
+
+#endif /* _COMPAT_MMAN_H */
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_POLL_H
*/
#ifdef HAVE_EPOLL
#include <sys/epoll.h>
+#include <stdio.h>
/* See man epoll(7) for this define path */
#define COMPAT_EPOLL_PROC_PATH "/proc/sys/fs/epoll/max_user_watches"
*/
static inline void lttng_poll_clean(struct lttng_poll_event *events)
{
+ int ret;
+
if (events) {
- close(events->epfd);
+ ret = close(events->epfd);
+ if (ret) {
+ perror("close");
+ }
__lttng_poll_free((void *) events->events);
}
}
LPOLLRDBAND = POLLRDBAND,
LPOLLWRNORM = POLLWRNORM,
LPOLLWRBAND = POLLWRBAND,
+#if __linux__
LPOLLMSG = POLLMSG,
+ LPOLLRDHUP = POLLRDHUP,
+#elif defined(__FreeBSD__)
+ LPOLLMSG = 0,
+ LPOLLRDHUP = 0,
+#else
+#error "Please add support for your OS."
+#endif /* __linux__ */
LPOLLERR = POLLERR,
LPOLLHUP = POLLHUP | POLLNVAL,
- LPOLLRDHUP = POLLRDHUP,
/* Close on exec feature does not exist for poll(2) */
LTTNG_CLOEXEC = 0xdead,
};
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _COMPAT_SOCKET_H
+#define _COMPAT_SOCKET_H
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <common/macros.h>
+
+#ifdef __linux__
+
+#define LTTNG_SOCK_CREDS SCM_CREDENTIALS
+
+typedef struct ucred lttng_sock_cred;
+
+#define LTTNG_SOCK_SET_UID_CRED(c, u) LTTNG_REF(c)->uid = u
+#define LTTNG_SOCK_SET_GID_CRED(c, g) LTTNG_REF(c)->gid = g
+#define LTTNG_SOCK_SET_PID_CRED(c, p) LTTNG_REF(c)->pid = p
+
+#define LTTNG_SOCK_GET_UID_CRED(c) LTTNG_REF(c)->uid
+#define LTTNG_SOCK_GET_GID_CRED(c) LTTNG_REF(c)->gid
+#define LTTNG_SOCK_GET_PID_CRED(c) LTTNG_REF(c)->pid
+
+#elif defined(__FreeBSD__)
+
+struct lttng_sock_cred {
+ uid_t uid;
+ gid_t gid;
+};
+
+typedef struct lttng_sock_cred lttng_sock_cred;
+
+#define LTTNG_SOCK_GET_UID_CRED(c) LTTNG_REF(c)->uid
+#define LTTNG_SOCK_GET_GID_CRED(c) LTTNG_REF(c)->gid
+#define LTTNG_SOCK_GET_PID_CRED(c) -1
+
+#else
+#error "Please add support for your OS."
+#endif /* __linux__ , __FreeBSD__ */
+
+#endif /* _COMPAT_SOCKET_H */
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include <assert.h>
-#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <stdlib.h>
{
struct lttng_consumer_stream *stream;
+ rcu_read_lock();
stream = consumer_find_stream(key);
- if (stream)
+ if (stream) {
stream->key = -1;
+ /*
+ * We don't want the lookup to match, but we still need
+ * to iterate on this stream when iterating over the hash table. Just
+ * change the node key.
+ */
+ stream->node.key = -1;
+ }
+ rcu_read_unlock();
}
static struct lttng_consumer_channel *consumer_find_channel(int key)
{
struct lttng_consumer_channel *channel;
+ rcu_read_lock();
channel = consumer_find_channel(key);
- if (channel)
+ if (channel) {
channel->key = -1;
+ /*
+ * We don't want the lookup to match, but we still need
+ * to iterate on this channel when iterating over the hash table. Just
+ * change the node key.
+ */
+ channel->node.key = -1;
+ }
+ rcu_read_unlock();
+}
+
+static
+void consumer_free_stream(struct rcu_head *head)
+{
+ struct lttng_ht_node_ulong *node =
+ caa_container_of(head, struct lttng_ht_node_ulong, head);
+ struct lttng_consumer_stream *stream =
+ caa_container_of(node, struct lttng_consumer_stream, node);
+
+ free(stream);
}
/*
}
rcu_read_lock();
-
- /* Get stream node from hash table */
- lttng_ht_lookup(consumer_data.stream_ht,
- (void *)((unsigned long) stream->key), &iter);
- /* Remove stream node from hash table */
+ iter.iter.node = &stream->node.node;
ret = lttng_ht_del(consumer_data.stream_ht, &iter);
assert(!ret);
goto end;
}
if (stream->out_fd >= 0) {
- close(stream->out_fd);
+ ret = close(stream->out_fd);
+ if (ret) {
+ PERROR("close");
+ }
}
if (stream->wait_fd >= 0 && !stream->wait_fd_is_copy) {
- close(stream->wait_fd);
+ ret = close(stream->wait_fd);
+ if (ret) {
+ PERROR("close");
+ }
}
if (stream->shm_fd >= 0 && stream->wait_fd != stream->shm_fd) {
- close(stream->shm_fd);
+ ret = close(stream->shm_fd);
+ if (ret) {
+ PERROR("close");
+ }
}
if (!--stream->chan->refcount)
free_chan = stream->chan;
- free(stream);
+
+ call_rcu(&stream->node.head, consumer_free_stream);
end:
consumer_data.need_update = 1;
pthread_mutex_unlock(&consumer_data.lock);
consumer_del_channel(free_chan);
}
-static void consumer_del_stream_rcu(struct rcu_head *head)
-{
- struct lttng_ht_node_ulong *node =
- caa_container_of(head, struct lttng_ht_node_ulong, head);
- struct lttng_consumer_stream *stream =
- caa_container_of(node, struct lttng_consumer_stream, node);
-
- consumer_del_stream(stream);
-}
-
struct lttng_consumer_stream *consumer_allocate_stream(
int channel_key, int stream_key,
int shm_fd, int wait_fd,
int consumer_add_stream(struct lttng_consumer_stream *stream)
{
int ret = 0;
+ struct lttng_ht_node_ulong *node;
+ struct lttng_ht_iter iter;
pthread_mutex_lock(&consumer_data.lock);
/* Steal stream identifier, for UST */
consumer_steal_stream_key(stream->key);
rcu_read_lock();
+
+ lttng_ht_lookup(consumer_data.stream_ht,
+ (void *)((unsigned long) stream->key), &iter);
+ node = lttng_ht_iter_get_node_ulong(&iter);
+ if (node != NULL) {
+ rcu_read_unlock();
+ /* Stream already exist. Ignore the insertion */
+ goto end;
+ }
+
lttng_ht_add_unique_ulong(consumer_data.stream_ht, &stream->node);
rcu_read_unlock();
consumer_data.stream_count++;
end:
pthread_mutex_unlock(&consumer_data.lock);
+
return ret;
}
pthread_mutex_unlock(&consumer_data.lock);
}
+static
+void consumer_free_channel(struct rcu_head *head)
+{
+ struct lttng_ht_node_ulong *node =
+ caa_container_of(head, struct lttng_ht_node_ulong, head);
+ struct lttng_consumer_channel *channel =
+ caa_container_of(node, struct lttng_consumer_channel, node);
+
+ free(channel);
+}
+
/*
* Remove a channel from the global list protected by a mutex. This
* function is also responsible for freeing its data structures.
}
rcu_read_lock();
-
- lttng_ht_lookup(consumer_data.channel_ht,
- (void *)((unsigned long) channel->key), &iter);
+ iter.iter.node = &channel->node.node;
ret = lttng_ht_del(consumer_data.channel_ht, &iter);
assert(!ret);
-
rcu_read_unlock();
if (channel->mmap_base != NULL) {
}
}
if (channel->wait_fd >= 0 && !channel->wait_fd_is_copy) {
- close(channel->wait_fd);
+ ret = close(channel->wait_fd);
+ if (ret) {
+ PERROR("close");
+ }
}
if (channel->shm_fd >= 0 && channel->wait_fd != channel->shm_fd) {
- close(channel->shm_fd);
+ ret = close(channel->shm_fd);
+ if (ret) {
+ PERROR("close");
+ }
}
- free(channel);
+
+ call_rcu(&channel->node.head, consumer_free_channel);
end:
pthread_mutex_unlock(&consumer_data.lock);
}
-static void consumer_del_channel_rcu(struct rcu_head *head)
-{
- struct lttng_ht_node_ulong *node =
- caa_container_of(head, struct lttng_ht_node_ulong, head);
- struct lttng_consumer_channel *channel=
- caa_container_of(node, struct lttng_consumer_channel, node);
-
- consumer_del_channel(channel);
-}
-
struct lttng_consumer_channel *consumer_allocate_channel(
int channel_key,
int shm_fd, int wait_fd,
*/
int consumer_add_channel(struct lttng_consumer_channel *channel)
{
+ struct lttng_ht_node_ulong *node;
+ struct lttng_ht_iter iter;
+
pthread_mutex_lock(&consumer_data.lock);
/* Steal channel identifier, for UST */
consumer_steal_channel_key(channel->key);
rcu_read_lock();
+
+ lttng_ht_lookup(consumer_data.channel_ht,
+ (void *)((unsigned long) channel->key), &iter);
+ node = lttng_ht_iter_get_node_ulong(&iter);
+ if (node != NULL) {
+ /* Channel already exist. Ignore the insertion */
+ goto end;
+ }
+
lttng_ht_add_unique_ulong(consumer_data.channel_ht, &channel->node);
+
+end:
rcu_read_unlock();
pthread_mutex_unlock(&consumer_data.lock);
+
return 0;
}
struct lttng_consumer_stream *stream;
DBG("Updating poll fd array");
+ rcu_read_lock();
cds_lfht_for_each_entry(consumer_data.stream_ht->ht, &iter.iter, stream,
node.node) {
if (stream->state != LTTNG_CONSUMER_ACTIVE_STREAM) {
local_stream[i] = stream;
i++;
}
+ rcu_read_unlock();
/*
* Insert the consumer_poll_pipe at the end of the array and don't
{
int num_rdy;
+restart:
num_rdy = poll(consumer_sockpoll, 2, -1);
if (num_rdy == -1) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
perror("Poll error");
goto exit;
}
*/
void lttng_consumer_cleanup(void)
{
- int ret;
struct lttng_ht_iter iter;
struct lttng_ht_node_ulong *node;
*/
cds_lfht_for_each_entry(consumer_data.stream_ht->ht, &iter.iter, node,
node) {
- ret = lttng_ht_del(consumer_data.stream_ht, &iter);
- assert(!ret);
- call_rcu(&node->head, consumer_del_stream_rcu);
+ struct lttng_consumer_stream *stream =
+ caa_container_of(node, struct lttng_consumer_stream, node);
+ consumer_del_stream(stream);
}
cds_lfht_for_each_entry(consumer_data.channel_ht->ht, &iter.iter, node,
node) {
- ret = lttng_ht_del(consumer_data.channel_ht, &iter);
- assert(!ret);
- call_rcu(&node->head, consumer_del_channel_rcu);
+ struct lttng_consumer_channel *channel =
+ caa_container_of(node, struct lttng_consumer_channel, node);
+ consumer_del_channel(channel);
}
rcu_read_unlock();
if (orig_offset < stream->chan->max_sb_size) {
return;
}
- sync_file_range(outfd, orig_offset - stream->chan->max_sb_size,
+ lttng_sync_file_range(outfd, orig_offset - stream->chan->max_sb_size,
stream->chan->max_sb_size,
SYNC_FILE_RANGE_WAIT_BEFORE
| SYNC_FILE_RANGE_WRITE
*/
struct lttng_consumer_local_data *lttng_consumer_create(
enum lttng_consumer_type type,
- int (*buffer_ready)(struct lttng_consumer_stream *stream,
+ ssize_t (*buffer_ready)(struct lttng_consumer_stream *stream,
struct lttng_consumer_local_data *ctx),
int (*recv_channel)(struct lttng_consumer_channel *channel),
int (*recv_stream)(struct lttng_consumer_stream *stream),
int err;
err = close(ctx->consumer_should_quit[i]);
- assert(!err);
+ if (err) {
+ PERROR("close");
+ }
}
error_quit_pipe:
for (i = 0; i < 2; i++) {
int err;
err = close(ctx->consumer_poll_pipe[i]);
- assert(!err);
+ if (err) {
+ PERROR("close");
+ }
}
error_poll_pipe:
free(ctx);
*/
void lttng_consumer_destroy(struct lttng_consumer_local_data *ctx)
{
- close(ctx->consumer_error_socket);
- close(ctx->consumer_thread_pipe[0]);
- close(ctx->consumer_thread_pipe[1]);
- close(ctx->consumer_poll_pipe[0]);
- close(ctx->consumer_poll_pipe[1]);
- close(ctx->consumer_should_quit[0]);
- close(ctx->consumer_should_quit[1]);
+ int ret;
+
+ ret = close(ctx->consumer_error_socket);
+ if (ret) {
+ PERROR("close");
+ }
+ ret = close(ctx->consumer_thread_pipe[0]);
+ if (ret) {
+ PERROR("close");
+ }
+ ret = close(ctx->consumer_thread_pipe[1]);
+ if (ret) {
+ PERROR("close");
+ }
+ ret = close(ctx->consumer_poll_pipe[0]);
+ if (ret) {
+ PERROR("close");
+ }
+ ret = close(ctx->consumer_poll_pipe[1]);
+ if (ret) {
+ PERROR("close");
+ }
+ ret = close(ctx->consumer_should_quit[0]);
+ if (ret) {
+ PERROR("close");
+ }
+ ret = close(ctx->consumer_should_quit[1]);
+ if (ret) {
+ PERROR("close");
+ }
unlink(ctx->consumer_command_sock_path);
free(ctx);
}
*
* Returns the number of bytes written
*/
-int lttng_consumer_on_read_subbuffer_mmap(
+ssize_t lttng_consumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len)
{
ERR("Unknown consumer_data type");
assert(0);
}
+
+ return 0;
}
/*
*
* Returns the number of bytes spliced.
*/
-int lttng_consumer_on_read_subbuffer_splice(
+ssize_t lttng_consumer_on_read_subbuffer_splice(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len)
{
}
pthread_mutex_unlock(&consumer_data.lock);
+ /* No FDs and consumer_quit, consumer_cleanup the thread */
+ if (nb_fd == 0 && consumer_quit == 1) {
+ goto end;
+ }
/* poll on the array of fds */
+ restart:
DBG("polling on %d fd", nb_fd + 1);
num_rdy = poll(pollfd, nb_fd + 1, consumer_poll_timeout);
DBG("poll num_rdy : %d", num_rdy);
if (num_rdy == -1) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
perror("Poll error");
lttng_consumer_send_error(ctx, CONSUMERD_POLL_ERROR);
goto end;
goto end;
}
- /* No FDs and consumer_quit, consumer_cleanup the thread */
- if (nb_fd == 0 && consumer_quit == 1) {
- goto end;
- }
-
/*
* If the consumer_poll_pipe triggered poll go
* directly to the beginning of the loop to update the
/* Take care of high priority channels first. */
for (i = 0; i < nb_fd; i++) {
if (pollfd[i].revents & POLLPRI) {
+ ssize_t len;
+
DBG("Urgent read on fd %d", pollfd[i].fd);
high_prio = 1;
- ret = ctx->on_buffer_ready(local_stream[i], ctx);
+ len = ctx->on_buffer_ready(local_stream[i], ctx);
/* it's ok to have an unavailable sub-buffer */
- if (ret == EAGAIN) {
- ret = 0;
+ if (len < 0 && len != -EAGAIN) {
+ goto end;
+ } else if (len > 0) {
+ local_stream[i]->data_read = 1;
}
- } else if (pollfd[i].revents & POLLERR) {
- ERR("Error returned in polling fd %d.", pollfd[i].fd);
- rcu_read_lock();
- consumer_del_stream_rcu(&local_stream[i]->node.head);
- rcu_read_unlock();
- num_hup++;
- } else if (pollfd[i].revents & POLLNVAL) {
- ERR("Polling fd %d tells fd is not open.", pollfd[i].fd);
- rcu_read_lock();
- consumer_del_stream_rcu(&local_stream[i]->node.head);
- rcu_read_unlock();
- num_hup++;
- } else if ((pollfd[i].revents & POLLHUP) &&
- !(pollfd[i].revents & POLLIN)) {
- if (consumer_data.type == LTTNG_CONSUMER32_UST
- || consumer_data.type == LTTNG_CONSUMER64_UST) {
- DBG("Polling fd %d tells it has hung up. Attempting flush and read.",
- pollfd[i].fd);
- if (!local_stream[i]->hangup_flush_done) {
- lttng_ustconsumer_on_stream_hangup(local_stream[i]);
- /* read after flush */
- do {
- ret = ctx->on_buffer_ready(local_stream[i], ctx);
- } while (ret == EAGAIN);
- }
- } else {
- DBG("Polling fd %d tells it has hung up.", pollfd[i].fd);
- }
- rcu_read_lock();
- consumer_del_stream_rcu(&local_stream[i]->node.head);
- rcu_read_unlock();
- num_hup++;
}
}
- /* If every buffer FD has hung up, we end the read loop here */
- if (nb_fd > 0 && num_hup == nb_fd) {
- DBG("every buffer FD has hung up\n");
- if (consumer_quit == 1) {
- goto end;
- }
+ /*
+ * If we read high prio channel in this loop, try again
+ * for more high prio data.
+ */
+ if (high_prio) {
continue;
}
/* Take care of low priority channels. */
- if (high_prio == 0) {
- for (i = 0; i < nb_fd; i++) {
- if (pollfd[i].revents & POLLIN) {
- DBG("Normal read on fd %d", pollfd[i].fd);
- ret = ctx->on_buffer_ready(local_stream[i], ctx);
- /* it's ok to have an unavailable subbuffer */
- if (ret == EAGAIN) {
- ret = 0;
- }
+ for (i = 0; i < nb_fd; i++) {
+ if ((pollfd[i].revents & POLLIN) ||
+ local_stream[i]->hangup_flush_done) {
+ ssize_t len;
+
+ DBG("Normal read on fd %d", pollfd[i].fd);
+ len = ctx->on_buffer_ready(local_stream[i], ctx);
+ /* it's ok to have an unavailable sub-buffer */
+ if (len < 0 && len != -EAGAIN) {
+ goto end;
+ } else if (len > 0) {
+ local_stream[i]->data_read = 1;
+ }
+ }
+ }
+
+ /* Handle hangup and errors */
+ for (i = 0; i < nb_fd; i++) {
+ if (!local_stream[i]->hangup_flush_done
+ && (pollfd[i].revents & (POLLHUP | POLLERR | POLLNVAL))
+ && (consumer_data.type == LTTNG_CONSUMER32_UST
+ || consumer_data.type == LTTNG_CONSUMER64_UST)) {
+ DBG("fd %d is hup|err|nval. Attempting flush and read.",
+ pollfd[i].fd);
+ lttng_ustconsumer_on_stream_hangup(local_stream[i]);
+ /* Attempt read again, for the data we just flushed. */
+ local_stream[i]->data_read = 1;
+ }
+ /*
+ * If the poll flag is HUP/ERR/NVAL and we have
+ * read no data in this pass, we can remove the
+ * stream from its hash table.
+ */
+ if ((pollfd[i].revents & POLLHUP)) {
+ DBG("Polling fd %d tells it has hung up.", pollfd[i].fd);
+ if (!local_stream[i]->data_read) {
+ consumer_del_stream(local_stream[i]);
+ num_hup++;
+ }
+ } else if (pollfd[i].revents & POLLERR) {
+ ERR("Error returned in polling fd %d.", pollfd[i].fd);
+ if (!local_stream[i]->data_read) {
+ consumer_del_stream(local_stream[i]);
+ num_hup++;
+ }
+ } else if (pollfd[i].revents & POLLNVAL) {
+ ERR("Polling fd %d tells fd is not open.", pollfd[i].fd);
+ if (!local_stream[i]->data_read) {
+ consumer_del_stream(local_stream[i]);
+ num_hup++;
}
}
+ local_stream[i]->data_read = 0;
}
}
end:
return NULL;
}
-int lttng_consumer_read_subbuffer(struct lttng_consumer_stream *stream,
+ssize_t lttng_consumer_read_subbuffer(struct lttng_consumer_stream *stream,
struct lttng_consumer_local_data *ctx)
{
switch (consumer_data.type) {
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_CONSUMER_H
#include <lttng/lttng.h>
-#include "src/common/hashtable/hashtable.h"
+#include <common/hashtable/hashtable.h>
+#include <common/compat/fcntl.h>
/*
* When the receiving thread dies, we need to have a way to make the polling
/* For UST */
struct lttng_ust_lib_ring_buffer *buf;
int cpu;
+ int data_read;
int hangup_flush_done;
/* UID/GID of the user owning the session to which stream belongs */
uid_t uid;
* process.
*/
struct lttng_consumer_local_data {
- /* function to call when data is available on a buffer */
- int (*on_buffer_ready)(struct lttng_consumer_stream *stream,
+ /*
+ * Function to call when data is available on a buffer.
+ * Returns the number of bytes read, or negative error value.
+ */
+ ssize_t (*on_buffer_ready)(struct lttng_consumer_stream *stream,
struct lttng_consumer_local_data *ctx);
/*
* function to call when we receive a new channel, it receives a
extern struct lttng_consumer_local_data *lttng_consumer_create(
enum lttng_consumer_type type,
- int (*buffer_ready)(struct lttng_consumer_stream *stream,
+ ssize_t (*buffer_ready)(struct lttng_consumer_stream *stream,
struct lttng_consumer_local_data *ctx),
int (*recv_channel)(struct lttng_consumer_channel *channel),
int (*recv_stream)(struct lttng_consumer_stream *stream),
int (*update_stream)(int sessiond_key, uint32_t state));
extern void lttng_consumer_destroy(struct lttng_consumer_local_data *ctx);
-extern int lttng_consumer_on_read_subbuffer_mmap(
+extern ssize_t lttng_consumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len);
-extern int lttng_consumer_on_read_subbuffer_splice(
+extern ssize_t lttng_consumer_on_read_subbuffer_splice(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len);
extern int lttng_consumer_take_snapshot(struct lttng_consumer_local_data *ctx,
extern int lttng_consumer_recv_cmd(struct lttng_consumer_local_data *ctx,
int sock, struct pollfd *consumer_sockpoll);
-int lttng_consumer_read_subbuffer(struct lttng_consumer_stream *stream,
+ssize_t lttng_consumer_read_subbuffer(struct lttng_consumer_stream *stream,
struct lttng_consumer_local_data *ctx);
int lttng_consumer_on_recv_stream(struct lttng_consumer_stream *stream);
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _DEFAULTS_H
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
+ *
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _ERROR_H
#include <stdio.h>
#include <string.h>
+#ifndef _GNU_SOURCE
+#error "lttng-tools error.h needs _GNU_SOURCE"
+#endif
+
/* Stringify the expansion of a define */
#define XSTR(d) STR(d)
#define STR(s) #s
-extern int opt_quiet;
-extern int opt_verbose;
+extern int lttng_opt_quiet;
+extern int lttng_opt_verbose;
#define PRINT_ERR 0x1
#define PRINT_WARN 0x2
/*
* Macro for printing message depending on command line option and verbosity.
*/
-#define __lttng_print(type, fmt, args...) \
- do { \
- if (opt_quiet == 0) { \
- if (type == PRINT_MSG) { \
- fprintf(stdout, fmt, ## args); \
- } else if (((type & PRINT_DBG) && opt_verbose == 1) || \
- ((type & (PRINT_DBG | PRINT_DBG2)) && \
- opt_verbose == 2) || \
- ((type & (PRINT_DBG | PRINT_DBG2 | PRINT_DBG3)) && \
- opt_verbose == 3)) { \
- fprintf(stderr, fmt, ## args); \
- } else if (type & (PRINT_ERR | PRINT_WARN | PRINT_BUG)) { \
- fprintf(stderr, fmt, ## args); \
- } \
- } \
+#define __lttng_print(type, fmt, args...) \
+ do { \
+ if (lttng_opt_quiet == 0 && type == PRINT_MSG) { \
+ fprintf(stdout, fmt, ## args); \
+ } else if (lttng_opt_quiet == 0 && \
+ (((type & PRINT_DBG) && lttng_opt_verbose == 1) || \
+ ((type & (PRINT_DBG | PRINT_DBG2)) && \
+ lttng_opt_verbose == 2) || \
+ ((type & (PRINT_DBG | PRINT_DBG2 | PRINT_DBG3)) && \
+ lttng_opt_verbose == 3))) { \
+ fprintf(stderr, fmt, ## args); \
+ } else if (lttng_opt_quiet == 0 && (type & (PRINT_WARN))) { \
+ fprintf(stderr, fmt, ## args); \
+ } else if (type & (PRINT_ERR | PRINT_BUG)) { \
+ fprintf(stderr, fmt, ## args); \
+ } \
} while (0);
#define MSG(fmt, args...) \
" [in %s() at " __FILE__ ":" XSTR(__LINE__) "]\n", ## args, __func__)
#define _PERROR(fmt, args...) \
- __lttng_print(PRINT_ERR, "perror " fmt "\n", ## args)
+ __lttng_print(PRINT_ERR, "PERROR: " fmt \
+ " [in %s() at " __FILE__ ":" XSTR(__LINE__) "]\n", ## args, __func__)
+
+#if !defined(__linux__) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE))
+/*
+ * Version using XSI strerror_r.
+ */
+#define PERROR(call, args...) \
+ do { \
+ char buf[200]; \
+ strerror_r(errno, buf, sizeof(buf)); \
+ _PERROR(call ": %s", ## args, buf); \
+ } while(0);
+#else
+/*
+ * Version using GNU strerror_r, for linux with appropriate defines.
+ */
#define PERROR(call, args...) \
- do { \
+ do { \
char *buf; \
char tmp[200]; \
buf = strerror_r(errno, tmp, sizeof(tmp)); \
_PERROR(call ": %s", ## args, buf); \
} while(0);
+#endif
#endif /* _ERROR_H */
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
ret = cds_lfht_destroy(ht->ht, NULL);
assert(!ret);
+ free(ht);
}
/*
assert(node_ptr == &node->node);
}
+/*
+ * Add replace unsigned long node to hashtable.
+ */
+struct lttng_ht_node_ulong *lttng_ht_add_replace_ulong(struct lttng_ht *ht,
+ struct lttng_ht_node_ulong *node)
+{
+ struct cds_lfht_node *node_ptr;
+ assert(ht);
+ assert(ht->ht);
+ assert(node);
+
+ node_ptr = cds_lfht_add_replace(ht->ht,
+ ht->hash_fct((void *) node->key, HASH_SEED), ht->match_fct,
+ (void *) node->key, &node->node);
+ if (!node_ptr) {
+ return NULL;
+ } else {
+ return caa_container_of(node_ptr, struct lttng_ht_node_ulong, node);
+ }
+ assert(node_ptr == &node->node);
+}
+
/*
* Delete node from hashtable.
*/
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_HT_H
struct lttng_ht_node_str *node);
extern void lttng_ht_add_unique_ulong(struct lttng_ht *ht,
struct lttng_ht_node_ulong *node);
+extern struct lttng_ht_node_ulong *lttng_ht_add_replace_ulong(
+ struct lttng_ht *ht, struct lttng_ht_node_ulong *node);
extern int lttng_ht_del(struct lttng_ht *ht, struct lttng_ht_iter *iter);
#include <sys/mman.h>
#include "rculfhash-internal.h"
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
/* reserve inaccessible memory space without allocation any memory */
static void *memory_map(size_t length)
{
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
*/
#include <assert.h>
-#include <endian.h> /* attempt to define endianness */
#include <stdint.h> /* defines uint32_t etc */
#include <stdio.h> /* defines printf for tests */
#include <string.h>
#include <urcu/compiler.h>
#include "utils.h"
+#include <common/compat/endian.h> /* attempt to define endianness */
/*
* My best guess at if you are big-endian or little-endian. This may
/*
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_HT_UTILS_H
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include <assert.h>
-#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
+#include <sys/stat.h>
#include <common/common.h>
#include <common/kernel-ctl/kernel-ctl.h>
#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/compat/fcntl.h>
#include "kernel-consumer.h"
*
* Returns the number of bytes written
*/
-int lttng_kconsumer_on_read_subbuffer_mmap(
+ssize_t lttng_kconsumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len)
{
unsigned long mmap_offset;
- long ret = 0;
+ ssize_t ret = 0;
off_t orig_offset = stream->out_fd_offset;
int fd = stream->wait_fd;
int outfd = stream->out_fd;
/* get the offset inside the fd to mmap */
ret = kernctl_get_mmap_read_offset(fd, &mmap_offset);
if (ret != 0) {
- ret = -errno;
+ errno = -ret;
perror("kernctl_get_mmap_read_offset");
goto end;
}
if (ret >= len) {
len = 0;
} else if (ret < 0) {
- ret = -errno;
+ errno = -ret;
perror("Error in file write");
goto end;
}
/* This won't block, but will start writeout asynchronously */
- sync_file_range(outfd, stream->out_fd_offset, ret,
+ lttng_sync_file_range(outfd, stream->out_fd_offset, ret,
SYNC_FILE_RANGE_WRITE);
stream->out_fd_offset += ret;
}
*
* Returns the number of bytes spliced.
*/
-int lttng_kconsumer_on_read_subbuffer_splice(
+ssize_t lttng_kconsumer_on_read_subbuffer_splice(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len)
{
- long ret = 0;
+ ssize_t ret = 0;
loff_t offset = 0;
off_t orig_offset = stream->out_fd_offset;
int fd = stream->wait_fd;
(unsigned long)offset, fd);
ret = splice(fd, &offset, ctx->consumer_thread_pipe[1], NULL, len,
SPLICE_F_MOVE | SPLICE_F_MORE);
- DBG("splice chan to pipe ret %ld", ret);
+ DBG("splice chan to pipe ret %zd", ret);
if (ret < 0) {
- ret = errno;
+ errno = -ret;
perror("Error in relay splice");
goto splice_error;
}
ret = splice(ctx->consumer_thread_pipe[0], NULL, outfd, NULL, ret,
SPLICE_F_MOVE | SPLICE_F_MORE);
- DBG("splice pipe to file %ld", ret);
+ DBG("splice pipe to file %zd", ret);
if (ret < 0) {
- ret = errno;
+ errno = -ret;
perror("Error in file splice");
goto splice_error;
}
len -= ret;
/* This won't block, but will start writeout asynchronously */
- sync_file_range(outfd, stream->out_fd_offset, ret,
+ lttng_sync_file_range(outfd, stream->out_fd_offset, ret,
SYNC_FILE_RANGE_WRITE);
stream->out_fd_offset += ret;
}
ret = kernctl_snapshot(infd);
if (ret != 0) {
- ret = errno;
+ errno = -ret;
perror("Getting sub-buffer snapshot.");
}
ret = kernctl_snapshot_get_produced(infd, pos);
if (ret != 0) {
- ret = errno;
+ errno = -ret;
perror("kernctl_snapshot_get_produced");
}
/*
* Consume data on a file descriptor and write it on a trace file.
*/
-int lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
+ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
struct lttng_consumer_local_data *ctx)
{
unsigned long len;
int err;
- long ret = 0;
+ ssize_t ret = 0;
int infd = stream->wait_fd;
DBG("In read_subbuffer (infd : %d)", infd);
/* Get the next subbuffer */
err = kernctl_get_next_subbuf(infd);
if (err != 0) {
- ret = errno;
/*
* This is a debug message even for single-threaded consumer,
* because poll() have more relaxed criterions than get subbuf,
/* read the whole subbuffer */
err = kernctl_get_padded_subbuf_size(infd, &len);
if (err != 0) {
- ret = errno;
+ errno = -ret;
perror("Getting sub-buffer len failed.");
goto end;
}
/* read the used subbuffer size */
err = kernctl_get_padded_subbuf_size(infd, &len);
if (err != 0) {
- ret = errno;
+ errno = -ret;
perror("Getting sub-buffer len failed.");
goto end;
}
err = kernctl_put_next_subbuf(infd);
if (err != 0) {
- ret = errno;
+ errno = -ret;
if (errno == EFAULT) {
perror("Error in unreserving sub buffer\n");
} else if (errno == EIO) {
ret = kernctl_get_mmap_len(stream->wait_fd, &mmap_len);
if (ret != 0) {
- ret = errno;
+ errno = -ret;
perror("kernctl_get_mmap_len");
goto error_close_fd;
}
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_KCONSUMER_H
/*
* Mmap the ring buffer, read it and write the data to the tracefile.
*
- * Returns the number of bytes written.
+ * Returns the number of bytes written, or negative value on error.
*/
-extern int lttng_kconsumer_on_read_subbuffer_mmap(
+extern ssize_t lttng_kconsumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len);
/*
* Splice the data from the ring buffer to the tracefile.
*
- * Returns the number of bytes spliced.
+ * Returns the number of bytes spliced, or negative error value on
+ * error.
*/
-extern int lttng_kconsumer_on_read_subbuffer_splice(
+extern ssize_t lttng_kconsumer_on_read_subbuffer_splice(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len);
int sock, struct pollfd *consumer_sockpoll);
-int lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
+ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
struct lttng_consumer_local_data *ctx);
int lttng_kconsumer_on_recv_stream(struct lttng_consumer_stream *stream);
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <sys/ioctl.h>
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_KERNEL_CTL_H
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTT_KERNEL_IOCTL_H
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
* David Goulet <david.goulet@polymtl.ca>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_KERNEL_H
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _MACROS_H
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
-#include <sys/mman.h>
+#include <sys/signal.h>
#include <common/error.h>
+#include <common/compat/mman.h>
+#include <common/compat/clone.h>
#include "runas.h"
#define MAP_STACK 0
#endif
+#ifdef __FreeBSD__
+/* FreeBSD MAP_STACK always return -ENOMEM */
+#define LTTNG_MAP_STACK 0
+#else
+#define LTTNG_MAP_STACK MAP_STACK
+#endif
+
+#ifndef MAP_GROWSDOWN
+#define MAP_GROWSDOWN 0
+#endif
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
struct run_as_data {
int (*cmd)(void *data);
void *data;
if (data->gid != getegid()) {
ret = setegid(data->gid);
if (ret < 0) {
- perror("setegid");
+ PERROR("setegid");
return EXIT_FAILURE;
}
}
if (data->uid != geteuid()) {
ret = seteuid(data->uid);
if (ret < 0) {
- perror("seteuid");
+ PERROR("seteuid");
return EXIT_FAILURE;
}
}
writelen = write(data->retval_pipe, &sendret.c[index],
writeleft);
if (writelen < 0) {
- perror("write");
+ PERROR("write");
return EXIT_FAILURE;
}
writeleft -= writelen;
}
static
-int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid)
+int run_as_clone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid)
{
struct run_as_data run_as_data;
int ret = 0;
ret = pipe(retval_pipe);
if (ret < 0) {
- perror("pipe");
+ PERROR("pipe");
+ retval.i = ret;
goto end;
}
run_as_data.data = data;
run_as_data.retval_pipe = retval_pipe[1]; /* write end */
child_stack = mmap(NULL, RUNAS_CHILD_STACK_SIZE,
PROT_WRITE | PROT_READ,
- MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS | MAP_STACK,
+ MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS | LTTNG_MAP_STACK,
-1, 0);
if (child_stack == MAP_FAILED) {
- perror("mmap");
- ret = -ENOMEM;
+ PERROR("mmap");
+ retval.i = -ENOMEM;
goto close_pipe;
}
/*
* Pointing to the middle of the stack to support architectures
* where the stack grows up (HPPA).
*/
- pid = clone(child_run_as, child_stack + (RUNAS_CHILD_STACK_SIZE / 2),
- CLONE_FILES | SIGCHLD,
- &run_as_data, NULL);
+ pid = lttng_clone_files(child_run_as, child_stack + (RUNAS_CHILD_STACK_SIZE / 2),
+ &run_as_data);
if (pid < 0) {
- perror("clone");
- ret = pid;
+ PERROR("clone");
+ retval.i = pid;
goto unmap_stack;
}
/* receive return value */
do {
readlen = read(retval_pipe[0], &retval.c[index], readleft);
if (readlen < 0) {
- perror("read");
+ PERROR("read");
ret = -1;
break;
}
*/
pid = waitpid(pid, &status, 0);
if (pid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- perror("wait");
- ret = -1;
+ PERROR("wait");
+ retval.i = -1;
}
unmap_stack:
ret = munmap(child_stack, RUNAS_CHILD_STACK_SIZE);
if (ret < 0) {
- perror("munmap");
+ PERROR("munmap");
+ retval.i = ret;
}
close_pipe:
- close(retval_pipe[0]);
- close(retval_pipe[1]);
+ ret = close(retval_pipe[0]);
+ if (ret) {
+ PERROR("close");
+ }
+ ret = close(retval_pipe[1]);
+ if (ret) {
+ PERROR("close");
+ }
end:
return retval.i;
}
+/*
+ * To be used on setups where gdb has issues debugging programs using
+ * clone/rfork. Note that this is for debuging ONLY, and should not be
+ * considered secure.
+ */
+static
+int run_as_noclone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid)
+{
+ return cmd(data);
+}
+
+static
+int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid)
+{
+ if (!getenv("LTTNG_DEBUG_NOCLONE")) {
+ DBG("Using run_as_clone");
+ return run_as_clone(cmd, data, uid, gid);
+ } else {
+ DBG("Using run_as_noclone");
+ return run_as_noclone(cmd, data, uid, gid);
+ }
+}
+
int run_as_mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid)
{
struct run_as_mkdir_data data;
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only verion 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, version 2 only,
+ * as published by the Free Software Foundation.
*
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <unistd.h>
* Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <common/defaults.h>
+#include <common/error.h>
#include "sessiond-comm.h"
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_VERSION) ] = "Kernel tracer version is not compatible",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_EVENT_EXIST) ] = "Kernel event already exists",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_SESS_FAIL) ] = "Kernel create session failed",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_EXIST) ] = "Kernel channel already exists",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_FAIL) ] = "Kernel create channel failed",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_NOT_FOUND) ] = "Kernel channel not found",
[ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_CHAN_DISABLE_FAIL) ] = "Disable kernel channel failed",
[ LTTCOMM_ERR_INDEX(LTTCOMM_UST_EVENT_NOT_FOUND)] = "UST event not found",
[ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CONTEXT_EXIST)] = "UST context already exist",
[ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CONTEXT_INVAL)] = "UST invalid context",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_NEED_ROOT_SESSIOND) ] = "Tracing the kernel requires a root lttng-sessiond daemon and \"tracing\" group user membership",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_TRACE_ALREADY_STARTED) ] = "Tracing already started",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_TRACE_ALREADY_STOPPED) ] = "Tracing already stopped",
+
[ LTTCOMM_ERR_INDEX(CONSUMERD_COMMAND_SOCK_READY) ] = "consumerd command socket ready",
[ LTTCOMM_ERR_INDEX(CONSUMERD_SUCCESS_RECV_FD) ] = "consumerd success on receiving fds",
[ LTTCOMM_ERR_INDEX(CONSUMERD_ERROR_RECV_FD) ] = "consumerd error on receiving fds",
[ LTTCOMM_ERR_INDEX(CONSUMERD_SPLICE_ENOMEM) ] = "consumerd splice ENOMEM",
[ LTTCOMM_ERR_INDEX(CONSUMERD_SPLICE_ESPIPE) ] = "consumerd splice ESPIPE",
[ LTTCOMM_ERR_INDEX(LTTCOMM_NO_EVENT) ] = "Event not found",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_INVALID) ] = "Invalid parameter",
};
/*
int lttcomm_connect_unix_sock(const char *pathname)
{
struct sockaddr_un sun;
- int fd;
- int ret;
+ int fd, ret, closeret;
fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
- perror("socket");
+ PERROR("socket");
ret = fd;
goto error;
}
return fd;
error_connect:
- close(fd);
+ closeret = close(fd);
+ if (closeret) {
+ PERROR("close");
+ }
error:
return ret;
}
/* Blocking call */
new_fd = accept(sock, (struct sockaddr *) &sun, &len);
if (new_fd < 0) {
- perror("accept");
+ PERROR("accept");
}
return new_fd;
/* Create server socket */
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
- perror("socket");
+ PERROR("socket");
goto error;
}
(void) unlink(pathname);
ret = bind(fd, (struct sockaddr *) &sun, sizeof(sun));
if (ret < 0) {
- perror("bind");
+ PERROR("bind");
goto error;
}
ret = listen(sock, LTTNG_SESSIOND_COMM_MAX_LISTEN);
if (ret < 0) {
- perror("listen");
+ PERROR("listen");
}
return ret;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
- ret = recvmsg(sock, &msg, MSG_WAITALL);
+ do {
+ ret = recvmsg(sock, &msg, MSG_WAITALL);
+ } while (ret < 0 && errno == EINTR);
if (ret < 0) {
- perror("recvmsg");
+ PERROR("recvmsg");
}
return ret;
ret = sendmsg(sock, &msg, 0);
if (ret < 0) {
- perror("sendmsg");
+ /*
+ * Only warn about EPIPE when quiet mode is deactivated.
+ * We consider EPIPE as expected.
+ */
+ if (errno != EPIPE || !lttng_opt_quiet) {
+ PERROR("sendmsg");
+ }
}
return ret;
*/
int lttcomm_close_unix_sock(int sock)
{
- int ret;
+ int ret, closeret;
/* Shutdown receptions and transmissions */
ret = shutdown(sock, SHUT_RDWR);
if (ret < 0) {
- perror("shutdown");
+ PERROR("shutdown");
}
- close(sock);
+ closeret = close(sock);
+ if (closeret) {
+ PERROR("close");
+ }
return ret;
}
msg.msg_iov = iov;
msg.msg_iovlen = 1;
- ret = sendmsg(sock, &msg, 0);
+ do {
+ ret = sendmsg(sock, &msg, 0);
+ } while (ret < 0 && errno == EINTR);
if (ret < 0) {
- perror("sendmsg");
+ /*
+ * Only warn about EPIPE when quiet mode is deactivated.
+ * We consider EPIPE as expected.
+ */
+ if (errno != EPIPE || !lttng_opt_quiet) {
+ PERROR("sendmsg");
+ }
}
return ret;
}
msg.msg_control = recv_fd;
msg.msg_controllen = sizeof(recv_fd);
- ret = recvmsg(sock, &msg, 0);
+ do {
+ ret = recvmsg(sock, &msg, 0);
+ } while (ret < 0 && errno == EINTR);
if (ret < 0) {
- perror("recvmsg fds");
+ PERROR("recvmsg fds");
goto end;
}
if (ret != 1) {
}
if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
- cmsg->cmsg_len, CMSG_LEN(sizeof_fds));
+ (size_t) cmsg->cmsg_len, (size_t) CMSG_LEN(sizeof_fds));
ret = -1;
goto end;
}
ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t len)
{
struct msghdr msg;
- struct cmsghdr *cmptr;
struct iovec iov[1];
ssize_t ret = -1;
- struct ucred *creds;
- size_t sizeof_cred = sizeof(struct ucred);
+#ifdef __linux__
+ struct cmsghdr *cmptr;
+ size_t sizeof_cred = sizeof(lttng_sock_cred);
char anc_buf[CMSG_SPACE(sizeof_cred)];
+ lttng_sock_cred *creds;
+#endif /* __linux__ */
memset(&msg, 0, sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
+#ifdef __linux__
msg.msg_control = (caddr_t) anc_buf;
msg.msg_controllen = CMSG_LEN(sizeof_cred);
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_level = SOL_SOCKET;
- cmptr->cmsg_type = SCM_CREDENTIALS;
+ cmptr->cmsg_type = LTTNG_SOCK_CREDS;
cmptr->cmsg_len = CMSG_LEN(sizeof_cred);
- creds = (struct ucred *) CMSG_DATA(cmptr);
+ creds = (lttng_sock_cred*) CMSG_DATA(cmptr);
- creds->uid = geteuid();
- creds->gid = getegid();
- creds->pid = getpid();
+ LTTNG_SOCK_SET_UID_CRED(creds, geteuid());
+ LTTNG_SOCK_SET_GID_CRED(creds, getegid());
+ LTTNG_SOCK_SET_PID_CRED(creds, getpid());
+#endif /* __linux__ */
- ret = sendmsg(sock, &msg, 0);
+ do {
+ ret = sendmsg(sock, &msg, 0);
+ } while (ret < 0 && errno == EINTR);
if (ret < 0) {
- perror("sendmsg");
+ /*
+ * Only warn about EPIPE when quiet mode is deactivated.
+ * We consider EPIPE as expected.
+ */
+ if (errno != EPIPE || !lttng_opt_quiet) {
+ PERROR("sendmsg");
+ }
}
-
return ret;
}
* Returns the size of received data, or negative error value.
*/
ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
- struct ucred *creds)
+ lttng_sock_cred *creds)
{
struct msghdr msg;
- struct cmsghdr *cmptr;
struct iovec iov[1];
ssize_t ret;
- size_t sizeof_cred = sizeof(struct ucred);
+#ifdef __linux__
+ struct cmsghdr *cmptr;
+ size_t sizeof_cred = sizeof(lttng_sock_cred);
char anc_buf[CMSG_SPACE(sizeof_cred)];
+#endif /* __linux__ */
memset(&msg, 0, sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
+#ifdef __linux__
msg.msg_control = anc_buf;
msg.msg_controllen = sizeof(anc_buf);
+#endif /* __linux__ */
- ret = recvmsg(sock, &msg, 0);
+ do {
+ ret = recvmsg(sock, &msg, 0);
+ } while (ret < 0 && errno == EINTR);
if (ret < 0) {
- perror("recvmsg fds");
+ PERROR("recvmsg fds");
goto end;
}
+#ifdef __linux__
if (msg.msg_flags & MSG_CTRUNC) {
fprintf(stderr, "Error: Control message truncated.\n");
ret = -1;
}
if (cmptr->cmsg_level != SOL_SOCKET ||
- cmptr->cmsg_type != SCM_CREDENTIALS) {
+ cmptr->cmsg_type != LTTNG_SOCK_CREDS) {
fprintf(stderr, "Didn't received any credentials\n");
ret = -1;
goto end;
if (cmptr->cmsg_len != CMSG_LEN(sizeof_cred)) {
fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
- cmptr->cmsg_len, CMSG_LEN(sizeof_cred));
+ (size_t) cmptr->cmsg_len, (size_t) CMSG_LEN(sizeof_cred));
ret = -1;
goto end;
}
memcpy(creds, CMSG_DATA(cmptr), sizeof_cred);
+#elif defined(__FreeBSD__)
+ {
+ int peer_ret;
+
+ peer_ret = getpeereid(sock, &creds->uid, &creds->gid);
+ if (peer_ret != 0) {
+ return peer_ret;
+ }
+ }
+#else
+#error "Please implement credential support for your OS."
+#endif /* __linux__ */
end:
return ret;
/*
* Set socket option to use credentials passing.
*/
+#ifdef __linux__
int lttcomm_setsockopt_creds_unix_sock(int sock)
{
int ret, on = 1;
/* Set socket for credentials retrieval */
ret = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
if (ret < 0) {
- perror("setsockopt creds unix sock");
+ PERROR("setsockopt creds unix sock");
}
-
return ret;
}
+#elif defined(__FreeBSD__)
+int lttcomm_setsockopt_creds_unix_sock(int sock)
+{
+ return 0;
+}
+#else
+#error "Please implement credential support for your OS."
+#endif /* __linux__ */
* Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
#define _GNU_SOURCE
#include <limits.h>
#include <lttng/lttng.h>
-#include <sys/socket.h>
+#include <common/compat/socket.h>
/* Queue size of listen(2) */
#define LTTNG_SESSIOND_COMM_MAX_LISTEN 64
* lttcomm error code.
*/
enum lttcomm_return_code {
- LTTCOMM_OK = 1000, /* Ok */
+ LTTCOMM_OK = 10, /* Ok */
LTTCOMM_ERR, /* Unknown Error */
LTTCOMM_UND, /* Undefine command */
LTTCOMM_NOT_IMPLEMENTED, /* Command not implemented */
LTTCOMM_KERN_VERSION, /* Kernel tracer version is not compatible */
LTTCOMM_KERN_EVENT_EXIST, /* Kernel event already exists */
LTTCOMM_KERN_SESS_FAIL, /* Kernel create session failed */
+ LTTCOMM_KERN_CHAN_EXIST, /* Kernel channel already exists */
LTTCOMM_KERN_CHAN_FAIL, /* Kernel create channel failed */
LTTCOMM_KERN_CHAN_NOT_FOUND, /* Kernel channel not found */
LTTCOMM_KERN_CHAN_DISABLE_FAIL, /* Kernel disable channel failed */
LTTCOMM_UST_EVENT_NOT_FOUND, /* UST event not found */
LTTCOMM_UST_CONTEXT_EXIST, /* UST context exist */
LTTCOMM_UST_CONTEXT_INVAL, /* UST context invalid */
+ LTTCOMM_NEED_ROOT_SESSIOND, /* root sessiond is needed */
+ LTTCOMM_TRACE_ALREADY_STARTED, /* Tracing already started */
+ LTTCOMM_TRACE_ALREADY_STOPPED, /* Tracing already stopped */
CONSUMERD_COMMAND_SOCK_READY, /* when consumerd command socket ready */
CONSUMERD_SUCCESS_RECV_FD, /* success on receiving fds */
CONSUMERD_SPLICE_EINVAL, /* EINVAL from splice(2) */
CONSUMERD_SPLICE_ENOMEM, /* ENOMEM from splice(2) */
CONSUMERD_SPLICE_ESPIPE, /* ESPIPE from splice(2) */
+ LTTCOMM_INVALID, /* Invalid parameter */
+
/* MUST be last element */
LTTCOMM_NR, /* Last element */
};
extern ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t len);
extern ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
- struct ucred *creds);
+ lttng_sock_cred *creds);
extern const char *lttcomm_get_readable_code(enum lttcomm_return_code code);
extern int lttcomm_setsockopt_creds_unix_sock(int sock);
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
#include <assert.h>
-#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <lttng/ust-ctl.h>
#include <common/common.h>
#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/compat/fcntl.h>
#include "ust-consumer.h"
/*
* Mmap the ring buffer, read it and write the data to the tracefile.
*
- * Returns the number of bytes written
+ * Returns the number of bytes written, else negative value on error.
*/
-int lttng_ustconsumer_on_read_subbuffer_mmap(
+ssize_t lttng_ustconsumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len)
{
ret = ustctl_get_mmap_read_offset(stream->chan->handle,
stream->buf, &mmap_offset);
if (ret != 0) {
- ret = -errno;
- perror("ustctl_get_mmap_read_offset");
+ errno = -ret;
+ PERROR("ustctl_get_mmap_read_offset");
goto end;
}
while (len > 0) {
if (ret >= len) {
len = 0;
} else if (ret < 0) {
- ret = -errno;
- perror("Error in file write");
+ errno = -ret;
+ PERROR("Error in file write");
goto end;
}
/* This won't block, but will start writeout asynchronously */
- sync_file_range(outfd, stream->out_fd_offset, ret,
+ lttng_sync_file_range(outfd, stream->out_fd_offset, ret,
SYNC_FILE_RANGE_WRITE);
stream->out_fd_offset += ret;
}
*
* Returns the number of bytes spliced.
*/
-int lttng_ustconsumer_on_read_subbuffer_splice(
+ssize_t lttng_ustconsumer_on_read_subbuffer_splice(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len)
{
ret = ustctl_snapshot(stream->chan->handle, stream->buf);
if (ret != 0) {
- ret = errno;
- perror("Getting sub-buffer snapshot.");
+ errno = -ret;
+ PERROR("Getting sub-buffer snapshot.");
}
return ret;
ret = ustctl_snapshot_get_produced(stream->chan->handle,
stream->buf, pos);
if (ret != 0) {
- ret = errno;
- perror("kernctl_snapshot_get_produced");
+ errno = -ret;
+ PERROR("kernctl_snapshot_get_produced");
}
return ret;
/* signal the poll thread */
ret = write(ctx->consumer_poll_pipe[1], "4", 1);
if (ret < 0) {
- perror("write consumer poll");
+ PERROR("write consumer poll");
}
end_nosignal:
return 0;
if (!stream->hangup_flush_done) {
do {
readlen = read(stream->wait_fd, &dummy, 1);
- } while (readlen == -1 && errno == -EINTR);
+ } while (readlen == -1 && errno == EINTR);
if (readlen == -1) {
ret = readlen;
goto end;
stream->uid, stream->gid);
if (ret < 0) {
ERR("Opening %s", stream->path_name);
- perror("open");
+ PERROR("open");
goto error;
}
stream->out_fd = ret;
* Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
* Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
*
* 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
- * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LTTNG_USTCONSUMER_H
/*
* Mmap the ring buffer, read it and write the data to the tracefile.
*
- * Returns the number of bytes written.
+ * Returns the number of bytes written, else negative value on error.
*/
-extern int lttng_ustconsumer_on_read_subbuffer_mmap(
+extern ssize_t lttng_ustconsumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len);
/* Not implemented */
-extern int lttng_ustconsumer_on_read_subbuffer_splice(
+extern ssize_t lttng_ustconsumer_on_read_subbuffer_splice(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len);
#else /* HAVE_LIBLTTNG_UST_CTL */
static inline
-int lttng_ustconsumer_on_read_subbuffer_mmap(
+ssize_t lttng_ustconsumer_on_read_subbuffer_mmap(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *stream, unsigned long len)
{
}
static inline
-int lttng_ustconsumer_on_read_subbuffer_splice(
+ssize_t lttng_ustconsumer_on_read_subbuffer_splice(
struct lttng_consumer_local_data *ctx,
struct lttng_consumer_stream *uststream, unsigned long len)
{
*
* Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; only
- * version 2.1 of the License.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define _GNU_SOURCE
static char *tracing_group;
static int connected;
+/* Global */
+
+/*
+ * Those two variables are used by error.h to silent or control the verbosity of
+ * error message. They are global to the library so application linking with it
+ * are able to compile correctly and also control verbosity of the library.
+ *
+ * Note that it is *not* possible to silent ERR() and PERROR() macros.
+ */
+int lttng_opt_quiet;
+int lttng_opt_verbose;
+
/*
* Copy string from src to dst and enforce null terminated byte.
*/
/* Get GID of group 'tracing' */
grp_tracing = getgrnam(grp_name);
- if (grp_tracing == NULL) {
- /* NULL means not found also. getgrnam(3) */
- if (errno != 0) {
- perror("getgrnam");
- }
+ if (!grp_tracing) {
+ /* If grp_tracing is NULL, the group does not exist. */
goto end;
}
SUBDIRS = .
-AM_CFLAGS=-g -Wall -lurcu -lurcu-cds
+AM_CFLAGS = -g -Wall
+AM_LDFLAGS = -lurcu -lurcu-cds
EXTRA_DIST = runall.sh utils.sh lttng/runall.sh lttng/run-kernel-tests.sh
#include "../utils.h"
+int lttng_opt_quiet;
+
int main(int argc, char **argv)
{
struct lttng_handle *handle = NULL;
#include "../utils.h"
+int lttng_opt_quiet;
+
int main(int argc, char **argv)
{
struct lttng_handle *handle = NULL;
#include "../utils.h"
+int lttng_opt_quiet;
+
int main(int argc, char **argv)
{
struct lttng_handle *handle = NULL;
#include "../utils.h"
+int lttng_opt_quiet;
+
int main(int argc, char **argv)
{
struct lttng_handle *handle = NULL;
#define RANDOM_STRING_LEN 11
/* For lttngerr.h */
-int opt_quiet = 1;
-int opt_verbose = 0;
+int lttng_opt_quiet = 1;
+int lttng_opt_verbose;
static const char alphanum[] =
"0123456789"
PRINT_OK();
printf("Validating kernel session: ");
- assert(kern->fd == 0);
- assert(kern->metadata_stream_fd == 0);
+ assert(kern->fd == -1);
+ assert(kern->metadata_stream_fd == -1);
assert(kern->consumer_fds_sent == 0);
assert(kern->channel_count == 0);
assert(kern->stream_count_global == 0);
assert(kern->metadata == NULL);
- assert(kern->consumer_fd == 0);
+ assert(kern->consumer_fd == -1);
PRINT_OK();
/* Init list in order to avoid sefaults from cds_list_del */
PRINT_OK();
printf("Validating kernel session metadata: ");
- assert(kern->metadata->fd == 0);
+ assert(kern->metadata->fd == -1);
assert(strlen(kern->metadata->pathname));
assert(kern->metadata->conf != NULL);
assert(kern->metadata->conf->attr.overwrite
PRINT_OK();
printf("Validating kernel channel: ");
- assert(chan->fd == 0);
+ assert(chan->fd == -1);
assert(chan->enabled == 1);
assert(strcmp(PATH1, chan->pathname) == 0);
assert(chan->stream_count == 0);
PRINT_OK();
printf("Validating kernel event: ");
- assert(event->fd == 0);
+ assert(event->fd == -1);
assert(event->enabled == 1);
assert(event->ctx == NULL);
assert(event->event->instrumentation == LTTNG_KERNEL_TRACEPOINT);
PRINT_OK();
printf("Validating kernel stream: ");
- assert(stream->fd == 0);
+ assert(stream->fd == -1);
assert(stream->pathname == NULL);
assert(stream->state == 0);
PRINT_OK();
static struct ltt_session_list *session_list;
/* For lttngerr.h */
-int opt_quiet = 1;
-int opt_verbose = 0;
+int lttng_opt_quiet = 1;
+int lttng_opt_verbose = 0;
static const char alphanum[] =
"0123456789"
#define RANDOM_STRING_LEN 11
/* For lttngerr.h */
-int opt_quiet = 1;
-int opt_verbose = 0;
+int lttng_opt_quiet = 1;
+int lttng_opt_verbose;
static const char alphanum[] =
"0123456789"
AM_CFLAGS = -I. -O2
-AM_LDFLAGS = -llttng-ust -ldl
+AM_LDFLAGS = -llttng-ust
+
+if LTTNG_TOOLS_BUILD_WITH_LIBDL
+AM_LDFLAGS += -ldl
+endif
+if LTTNG_TOOLS_BUILD_WITH_LIBC_DL
+AM_LDFLAGS += -lc
+endif
noinst_PROGRAMS = gen-nevents
gen_nevents_SOURCES = gen-nevents.c tp.c ust_gen_nevents.h
AM_CFLAGS = -I. -O2
-AM_LDFLAGS = -llttng-ust -ldl
+AM_LDFLAGS = -llttng-ust
+
+if LTTNG_TOOLS_BUILD_WITH_LIBDL
+AM_LDFLAGS += -ldl
+endif
+if LTTNG_TOOLS_BUILD_WITH_LIBC_DL
+AM_LDFLAGS += -lc
+endif
noinst_PROGRAMS = gen-events-time
gen_events_time_SOURCES = gen-events-time.c tp.c ust_gen_event.h
./$CURDIR/$TEST_BIN_NAME 1000 >/dev/null 2>&1 &
done
-echo -n "Validating registered apps: "
+echo -n "Validating registered apps in 3 seconds..."
+
+sleep 3
listing=$($TESTDIR/../src/bin/lttng/$LTTNG_BIN list -u)
reg_app_count=$(echo -n $listing | sed "s/$TEST_BIN_NAME/$TEST_BIN_NAME\n/g" | grep "$TEST_BIN_NAME" | wc -l)
start_tracing $SESSION_NAME
echo "Sleeping $TEST_WAIT_SEC seconds for tracing to start everywhere"
+echo "Warning: this arbitrary time can make the test fail on slower system"
sleep $TEST_WAIT_SEC
stop_tracing $SESSION_NAME