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]]),
.IP "LTTNG_CONSUMERD64_LIBDIR"
Allow to 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
#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 {
*/
#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>
*/
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");
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;
}
/*
* 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;
}
*/
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;
}
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();
*/
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;
}
/*
*/
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;
}
/*
exit(EXIT_FAILURE);
}
+#ifndef __FreeBSD__
ret = fchmod(wait_shm_fd, mode);
if (ret < 0) {
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
DBG("Got the wait shm fd %d", wait_shm_fd);
#include <sys/wait.h>
#include <unistd.h>
#include <config.h>
+#include <ctype.h>
#include <lttng/lttng.h>
#include <common/error.h>
libcommon_la_SOURCES = runas.c runas.h common.h
+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/fcntl.h compat/splice.h compat/endian.h \
+ compat/socket.h compat/compat-fcntl.c $(COMPAT)
+
# Consumer library
noinst_LTLIBRARIES += libconsumer.la
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/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)
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _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 */
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#define _GNU_SOURCE
+#include <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__ */
--- /dev/null
+/*
+ * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#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 as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _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 as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _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 */
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 as published by the Free
+ * Software Foundation; only version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _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 */
#define _GNU_SOURCE
#include <assert.h>
-#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <stdlib.h>
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
ERR("Unknown consumer_data type");
assert(0);
}
+
+ return 0;
}
/*
#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
__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 { \
char *buf; \
buf = strerror_r(errno, tmp, sizeof(tmp)); \
_PERROR(call ": %s", ## args, buf); \
} while(0);
+#endif
#endif /* _ERROR_H */
#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)
{
*/
#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
#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"
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;
}
}
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;
}
#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 RUNAS_CHILD_STACK_SIZE 10485760
-#ifndef MAP_STACK
-#define MAP_STACK 0
+#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 {
}
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;
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");
* 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");
retval.i = pid;
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;
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
}
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);
if (ret < 0) {
* 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);
if (ret < 0) {
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;
if (ret < 0) {
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__ */
#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
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);
#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"
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;
}
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
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