tests/hello-many/hello-many
tests/hello.cxx/hello
tests/same_line_tracepoint/same_line_tracepoint
-tests/ust-basic-tracing/ust-basic-tracing
-tests/ust-multi-test/ust-multi-test
-tests/trace_event/trace_event_test
-tests/tracepoint/benchmark/tracepoint_benchmark
-tests/tracepoint/tracepoint_test
tests/snprintf/test_snprintf
tests/ust-elf/ust-elf
tests/ust-elf/test_ust_elf
+++ /dev/null
-AM_CPPFLAGS = -I$(top_srcdir)/include
-
-noinst_PROGRAMS = trace_event_test
-trace_event_test_SOURCES = trace_event_test.c trace_event_test.h
-trace_event_test_LDADD = $(top_builddir)/libust/libust.la \
- $(top_builddir)/libust-initializer.o -lpthread -lrt
-
-CFLAGS_trace_event_test.o = -I$(src) $(AM_CFLAGS)
-dist_noinst_SCRIPTS = run
+++ /dev/null
-#!/bin/sh
-
-# Run with nothing
-
-UST_AUTOCOLLECT=1 UST_AUTOPROBE=1 UST_TRACE=1 LD_LIBRARY_PATH=../../libust/.libs:../../../liburcu $1 .libs/trace_event_test
+++ /dev/null
-/*
- * Copyright (C) 2010 Nils Carlson <nils.carlson@ericsson.com>
- * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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
- */
-
-#include <stdio.h>
-#include <ust/clock.h>
-
-#define TRACEPOINT_CREATE_PROBES
-#include "trace_event_test.h"
-
-int main(int argc, char * argv[])
-{
- unsigned long time, i;
-
- for (i = 0; i < 10; i++) {
- time = trace_clock_read64();
- tracepoint(test, time, i);
- }
- return 0;
-}
+++ /dev/null
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM trace_event_test
-
-#if !defined(_TRACEPOINT_EVENT_TEST_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACEPOINT_EVENT_TEST_H
-
-/*
- * Copyright (C) 2010 Nils Carlson <nils.carlson@ericsson.com>
- * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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
- */
-
-#include <ust/tracepoint.h>
-
-TRACEPOINT_EVENT(test,
-
- TP_PROTO(unsigned long time, unsigned long count),
-
- TP_VARS(time, count),
-
- TP_FIELDS(
- tp_field(unsigned long, time, time)
- tp_field(unsigned long, count, count)
- )
-);
-
-#endif /* _TRACEPOINT_EVENT_TEST_H */
-
-/* This part must be outside protection */
-#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace_event_test
-#include <ust/tracepoint_event.h>
+++ /dev/null
-SUBDIRS = benchmark
-
-AM_CPPFLAGS = -I$(top_srcdir)/include
-
-#noinst_PROGRAMS = tracepoint_test
-#tracepoint_test_SOURCES = tracepoint_test.c tracepoint_test.h
-#tracepoint_test_LDADD = $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
-
-#FIXME: this test is broken:
-#ust/tests/tracepoint/tracepoint_test.c:64: undefined reference to
-#`register_trace_ust_event_msg'
-#CFLAGS_tracepoint_test.o = -I$(src) $(AM_CFLAGS)
-
-dist_noinst_SCRIPTS = run
+++ /dev/null
-AM_CPPFLAGS = -I$(top_srcdir)/include
-
-noinst_PROGRAMS = tracepoint_benchmark
-tracepoint_benchmark_SOURCES = tracepoint_benchmark.c tracepoint_benchmark.h
-tracepoint_benchmark_LDADD = $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o -lpthread
-
-CFLAGS_tracepoint_benchmark.o = -I$(src) -g $(AM_CFLAGS)
+++ /dev/null
-#!/bin/sh
-
-# Copyright (C) 2010 David Goulet <david.goulet@polymtl.ca>
-# Copyright (C) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-#
-# 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; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# 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
-
-# SystemTAP benchmark
-
-REPORT=/tmp/testreport
-
-rm $REPORT
-
-echo "Userspace tracing scalability test report" |tee >> $REPORT
-
-for nr_threads in 1 2 4 8; do
- echo "" | tee >> $REPORT
- echo Number of threads: $nr_threads | tee >> $REPORT
- echo "* Baseline" | tee >> $REPORT
-
- killall stapio
- sleep 3
-
- sync
- /usr/bin/time -o /tmp/testlog ./.libs/tracepoint_benchmark ${nr_threads}
- cat /tmp/testlog >> $REPORT
-
- echo "* Flight recorder" | tee >> $REPORT
- #For flight recorder
- #stap testutrace.stp -F
-
- #Writing to disk
- stap testutrace.stp -o /tmp/stapconsole-$nr_threads &
-
- sleep 2
- sync
- /usr/bin/time -o /tmp/testlog ./.libs/tracepoint_benchmark ${nr_threads}
- cat /tmp/testlog >> $REPORT
-done
-
-cat /tmp/testreport
+++ /dev/null
-#!/bin/sh
-
-# Copyright (C) 2010 David Goulet <david.goulet@polymtl.ca>
-# Copyright (C) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-#
-# 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; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# 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
-
-# UST scalability test
-
-REPORT=/tmp/testreport
-
-rm $REPORT
-
-echo "Userspace tracing scalability test report" |tee >> $REPORT
-
-for nr_threads in 1 2 4 8; do
- echo "" | tee >> $REPORT
- echo Number of threads: $nr_threads | tee >> $REPORT
- echo "* Baseline" | tee >> $REPORT
-
- sync
- /usr/bin/time -o /tmp/testlog ./.libs/tracepoint_benchmark ${nr_threads}
- cat /tmp/testlog >> $REPORT
-
- #flight recorder, don't record trace to disk.
- export UST_AUTOCOLLECT=0
- export UST_OVERWRITE=1
- export UST_SUBBUF_NUM=16
- #default buffer size is 4k
-
- #Collect traces to disk
- #export UST_AUTOCOLLECT=1
- #export UST_OVERWRITE=0
- #export UST_SUBBUF_NUM=16
- #default buffer size is 4k
-
- echo "* Flight recorder" | tee >> $REPORT
- sync
- /usr/bin/time -o /tmp/testlog usttrace ./.libs/tracepoint_benchmark ${nr_threads}
- cat /tmp/testlog >> $REPORT
-done
-
-cat /tmp/testreport
+++ /dev/null
-probe process("./.libs/tracepoint_benchmark").function("single_trace") {
- printf("%d : %s\n", gettimeofday_ns(), $$parms);
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2010 David Goulet <david.goulet@polymtl.ca>
- * Copyright (C) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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
- */
-
-/*
- * This test is aimed at testing tracepoint *with* ust_marker :
- *
- * 1) tracepoint named : "ust_event"
- * -) Probe 1 registered and recording the value 42
- */
-
-#include <stdio.h>
-
-#define TRACEPOINT_CREATE_PROBES
-#include "tracepoint_benchmark.h"
-
-/* Yes, this is now internal. */
-#include "../../../libust/type-serializer.h"
-
-#define NR_EVENTS 10000000
-
-void tp_probe(void *data, unsigned int p1);
-
-DEFINE_UST_MARKER_TP(event, ust_event, tp_probe, "p1 %u");
-
-/*
- * Probe 1 --> ust_event
- */
-void tp_probe(void *data, unsigned int p1)
-{
- struct ust_marker *marker;
-
- marker = &GET_UST_MARKER(event);
- ltt_specialized_trace(marker, data, &p1, sizeof(p1), sizeof(p1));
-}
-
-static void __attribute__((constructor)) init()
-{
- __register_tracepoint(ust_event, tp_probe, NULL);
-}
-
-void single_trace(unsigned int v)
-{
- tracepoint(ust_event, v);
-}
-
-void do_trace(void)
-{
- long i;
-
- for (i = 0; i < NR_EVENTS; i++)
- single_trace(42);
-}
-
-void *thr1(void *arg)
-{
- do_trace();
- return ((void*)1);
-}
-
-int main(int argc, char **argv)
-{
- int err, i;
- void *tret;
- pthread_t *tid;
- int nr_threads;
-
- if (argc > 1)
- nr_threads = atoi(argv[1]);
- else
- nr_threads = 1;
- printf("Starting test for %d threads\n", nr_threads);
-
- tid = malloc(sizeof(*tid) * nr_threads);
-
- for (i = 0; i < nr_threads; i++) {
- err = pthread_create(&tid[i], NULL, thr1, NULL);
- if (err != 0)
- exit(1);
- }
-
- for (i = 0; i < nr_threads; i++) {
- err = pthread_join(tid[i], &tret);
- if (err != 0)
- exit(1);
- }
- free(tid);
- return 0;
-}
+++ /dev/null
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM tracepoint_benchmark
-
-#if !defined(_TRACE_TRACEPOINT_BENCHMARK_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_TRACEPOINT_BENCHMARK_H
-
-/*
- * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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
- */
-
-#include <ust/tracepoint.h>
-
-TRACEPOINT_EVENT(ust_event,
- TP_PROTO(unsigned int v),
- TP_VARS(v),
- TP_FIELDS());
-
-#endif /* _TRACE_TRACEPOINT_BENCHMARK_H */
-
-#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
-#undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_FILE tracepoint_benchmark
-
-/* This part must be outside protection */
-#include <ust/tracepoint_event.h>
+++ /dev/null
-#!/bin/bash
-
-TESTDIR=$(dirname $0)/..
-
-if [ ! -x "$TESTDIR/tracepoint/tracepoint_test" ]; then
- echo "tracepoint_test executable is not present"
- exit 1
-fi
-
-source $TESTDIR/test_functions.sh
-source $TESTDIR/tap.sh
-
-starttest "Testing Tracepoints"
-plan_tests 6
-USTTRACE="$TESTDIR/../usttrace"
-
-okx $USTTRACE -L $TESTDIR/tracepoint/tracepoint_test
-trace_loc=$($USTTRACE -W)
-trace_matches -N "probe1" -n "5" "probe = 13" $trace_loc
-trace_matches -N "probe2" -n "5" "probe = 42" $trace_loc
-trace_matches -N "probe3" -n "1" "probe = \"probe3\"" $trace_loc
-trace_matches -N "probe4" -n "100" "probe4 = 42" $trace_loc
-check_trace_logs "$trace_loc"
+++ /dev/null
-/* Copyright (C) 2010 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; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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
- */
-
-/*
- * This test is aimed at testing tracepoint *with* ust_marker :
- *
- * 1) tracepoint named : "ust_event"
- * -) Probe 1 registered and recording the value 13 (x5)
- * -) Probe 2 registered and recording the value 42 (x5)
- * -) Probe 3 registered and recording the payload of the struct message
- * but using a *different* tracepoint (event_msg)
- *
- * 2) tracepoint named : "ust_event2"
- * -) Probe 4 registered and recording the value 42 (x100)
- */
-
-#include <stdio.h>
-#include <ust/marker.h>
-#include "tracepoint_test.h"
-
-DEFINE_TRACEPOINT(ust_event);
-DEFINE_TRACEPOINT(ust_event2);
-
-static struct message msg_probe3 = {
- .payload = "probe3",
-};
-
-/*
- * Probe 4 --> ust_event2
- * Will record 100 times the value 42
- */
-void tp_probe4(void *data, unsigned int p4)
-{
- int i;
- for (i = 0; i < 100; i++) {
- ust_marker_tp(event2, ust_event2, tp_probe4, "probe4 %u", p4);
- }
-}
-
-/*
- * Probe 3 --> ust_event *and* event_msg (from inside)
- * Will record the payload of msg_prob3 struct
- * from the data pointer of the probe
- */
-void tp_probe3(void *data, unsigned int p3)
-{
- struct message *msg;
- msg = (struct message*) data;
- ust_marker_tp(event_msg, ust_event_msg,
- tp_probe3, "probe %s", msg->payload);
-}
-
-/*
- * Probe 2 --> ust_event
- * Will record 5 times the number 13
- */
-void tp_probe2(void *data, unsigned int p2)
-{
- int i;
- for (i = 0; i < 5; i++) {
- ust_marker_tp(event, ust_event, tp_probe2, "probe %u", 13);
- }
-}
-
-/*
- * Probe 1 --> ust_event
- * Will record 5 times the unsigned int v = 42
- */
-void tp_probe(void *data, unsigned int p1)
-{
- int i;
- for (i = 0; i < 5; i++) {
- ust_marker_tp(event, ust_event, tp_probe, "probe %u", p1);
- }
-}
-
-static void __attribute__((constructor)) init()
-{
- register_tracepoint(ust_event, tp_probe, NULL);
- register_tracepoint(ust_event, tp_probe2, NULL);
- register_tracepoint(ust_event, tp_probe3, &msg_probe3);
- register_tracepoint(ust_event2, tp_probe4, NULL);
-}
-
-int main(int argc, char **argv) {
- unsigned int v = 42;
- /* Tracepoint 1 : ust_event */
- tracepoint(ust_event, v);
- /* Tracepoint 2 : ust_event2 */
- tracepoint(ust_event2, v);
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright 2010 - David Goulet <david.goulet@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <ust/tracepoint.h>
-
-DECLARE_TRACEPOINT(ust_event, TP_PROTO(unsigned int v), TP_VARS(v));
-DECLARE_TRACEPOINT(ust_event2, TP_PROTO(unsigned int v), TP_VARS(v));
-
-struct message {
- char *payload;
-};
+++ /dev/null
-AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/libust
-
-noinst_PROGRAMS = ust-basic-tracing
-ust_basic_tracing_SOURCES = ust-basic-tracing.c
-ust_basic_tracing_LDADD = $(top_builddir)/liblttng-ust-comm/liblttng-ust-comm.la \
- $(top_builddir)/libringbuffer/libringbuffer.la \
- $(top_builddir)/snprintf/libustsnprintf.la
+++ /dev/null
-/*
- * ust-basic-tracing.c - Basic single-session, single-channel, single-process UST tracing
- *
- * Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * 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; version 2 of the License only.
- *
- * 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 _LARGEFILE64_SOURCE
-#define _GNU_SOURCE
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <urcu/futex.h>
-#include <urcu/uatomic.h>
-
-#include <ust-comm.h>
-#include <lttng/ust-error.h>
-#include "../../libringbuffer/backend.h"
-#include "../../libringbuffer/frontend.h"
-#include "../../liblttng-ust/compat.h" /* For ENODATA */
-
-#define MAX_NR_STREAMS 64
-#define MAX_NR_EVENTS 128
-
-static int session_handle;
-static struct lttng_ust_object_data metadata_stream_data;
-static struct lttng_ust_object_data metadata_data;
-static struct lttng_ust_object_data channel_data;
-static struct lttng_ust_object_data stream_data[MAX_NR_STREAMS];
-static int event_handle[MAX_NR_EVENTS];
-static int context_handle;
-
-static int apps_socket = -1;
-static char apps_sock_path[PATH_MAX];
-static char local_apps_wait_shm_path[PATH_MAX];
-
-static volatile int quit_program;
-
-static void handle_signals(int signo)
-{
- quit_program = 1;
-}
-
-static
-int open_streams(int sock, int channel_handle, struct lttng_ust_object_data *stream_datas,
- int nr_check)
-{
- int ret, k = 0;
-
- for (;;) {
- struct ustcomm_ust_msg lum;
- struct ustcomm_ust_reply lur;
-
- memset(&lum, 0, sizeof(lum));
- lum.handle = channel_handle;
- lum.cmd = LTTNG_UST_STREAM;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (!ret) {
- assert(k < nr_check);
- stream_datas[k].handle = lur.ret_val;
- printf("received stream handle %u\n",
- stream_datas[k].handle);
- if (lur.ret_code == LTTNG_UST_OK) {
- ssize_t len;
-
- stream_datas[k].memory_map_size = lur.u.stream.memory_map_size;
- /* get shm fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- stream_datas[k].shm_fd = len;
- /* get wait fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- stream_datas[k].wait_fd = len;
- }
- k++;
- }
- if (ret == -LTTNG_UST_ERR_NOENT)
- break;
- if (ret)
- return ret;
- }
- return 0;
-}
-
-static
-int close_streams(int sock, struct lttng_ust_object_data *stream_datas, int nr_check)
-{
- int ret, k;
-
- for (k = 0; k < nr_check; k++) {
- struct ustcomm_ust_msg lum;
- struct ustcomm_ust_reply lur;
-
- if (!stream_datas[k].handle)
- continue;
- memset(&lum, 0, sizeof(lum));
- lum.handle = stream_datas[k].handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret) {
- printf("Error closing stream\n");
- return ret;
- }
- if (stream_datas[k].shm_fd >= 0) {
- ret = close(stream_datas[k].shm_fd);
- if (ret) {
- printf("Error closing stream shm_fd\n");
- return ret;
- }
- }
- if (stream_datas[k].wait_fd >= 0) {
- ret = close(stream_datas[k].wait_fd);
- if (ret) {
- printf("Error closing stream wait_fd\n");
- return ret;
- }
- }
- }
- return 0;
-}
-
-static
-struct lttng_ust_shm_handle *map_channel(struct lttng_ust_object_data *chan_data,
- struct lttng_ust_object_data *stream_datas, int nr_check)
-{
- struct lttng_ust_shm_handle *handle;
- struct channel *chan;
- int k, ret;
-
- /* map metadata channel */
- handle = channel_handle_create(chan_data->shm_fd,
- chan_data->wait_fd,
- chan_data->memory_map_size);
- if (!handle) {
- printf("create handle error\n");
- return NULL;
- }
- chan_data->shm_fd = -1;
- chan_data->wait_fd = -1;
- chan = shmp(handle, handle->chan);
-
- for (k = 0; k < nr_check; k++) {
- struct lttng_ust_object_data *stream_data = &stream_datas[k];
-
- if (!stream_data->handle)
- break;
- /* map stream */
- ret = channel_handle_add_stream(handle,
- stream_data->shm_fd,
- stream_data->wait_fd,
- stream_data->memory_map_size);
- if (ret) {
- printf("add stream error\n");
- goto error_destroy;
- }
- stream_data->shm_fd = -1;
- stream_data->wait_fd = -1;
- }
- return handle;
-
-error_destroy:
- channel_destroy(chan, handle, 1);
- return NULL;
-}
-
-static
-void unmap_channel(struct lttng_ust_shm_handle *handle)
-{
- struct channel *chan;
-
- chan = shmp(handle, handle->chan);
- /* unmap channel */
- channel_destroy(chan, handle, 1);
-}
-
-static
-int consume_stream(struct lttng_ust_shm_handle *handle, int cpu, char *outfile)
-{
- struct channel *chan;
- struct lttng_ust_lib_ring_buffer *buf;
- int outfd, ret;
- int *shm_fd, *wait_fd;
- uint64_t *memory_map_size;
-
- chan = shmp(handle, handle->chan);
-
- /* open stream */
- buf = channel_get_ring_buffer(&chan->backend.config,
- chan, cpu, handle, &shm_fd, &wait_fd, &memory_map_size);
- if (!buf)
- return -ENOENT;
- ret = lib_ring_buffer_open_read(buf, handle, 1);
- if (ret) {
- return -1;
- }
-
- /* copy */
- outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
- if (outfd < 0) {
- perror("open output");
- return -1;
- }
-
- printf("Waiting for buffer data for %s\n", outfile);
- for (;;) {
- unsigned long read_size;
- unsigned long copy_size;
- char *ptr;
-
- ret = lib_ring_buffer_get_next_subbuf(buf, handle);
- printf("get next ret %d\n", ret);
- if (ret == -ENODATA)
- break;
- if (ret == -EAGAIN) {
- sleep(1);
- continue;
- }
- if (ret) {
- printf("Error %d in lib_ring_buffer_get_next_subbuf\n", ret);
- return -1;
- }
- read_size = lib_ring_buffer_get_read_data_size(
- &chan->backend.config, buf, handle);
- read_size = LTTNG_UST_PAGE_ALIGN(read_size);
- ptr = lib_ring_buffer_read_offset_address(
- &buf->backend, 0, handle);
- printf("WRITE: copy %lu bytes\n", read_size);
- copy_size = write(outfd, ptr, read_size);
- if (copy_size < read_size) {
- printf("write issue: copied %lu, expected %lu\n", copy_size, read_size);
- }
- lib_ring_buffer_put_next_subbuf(buf, handle);
- }
-
- ret = close(outfd);
- if (ret) {
- perror("close");
- return -1;
- }
-
- /* close stream */
- lib_ring_buffer_release_read(buf, handle, 1);
- return 0;
-}
-
-static
-int consume_buffers(const char *outputpath)
-{
- int k, ret;
- mode_t old_umask;
- char pathname[PATH_MAX];
- struct lttng_ust_shm_handle *handle;
-
- snprintf(pathname, PATH_MAX - 1, "%s", outputpath);
- old_umask = umask(0);
- ret = mkdir(pathname, S_IRWXU | S_IRWXG);
- if (ret && errno != EEXIST) {
- perror("mkdir");
- umask(old_umask);
- return -1;
- }
- umask(old_umask);
-
- /* copy metadata */
- handle = map_channel(&metadata_data,
- &metadata_stream_data, 1);
- if (!handle)
- return -1;
- snprintf(pathname, PATH_MAX - 1,
- "%s/metadata", outputpath);
- ret = consume_stream(handle, -1, pathname);
- if (ret && ret != -ENOENT) {
- printf("Error in consume_stream\n");
- return ret;
- }
- unmap_channel(handle);
-
- /* copy binary data */
- handle = map_channel(&channel_data,
- stream_data, MAX_NR_STREAMS);
- if (!handle)
- return -1;
- for (k = 0; k < MAX_NR_STREAMS; k++) {
- snprintf(pathname, PATH_MAX - 1,
- "%s/data_%u", outputpath, k);
- ret = consume_stream(handle, k, pathname);
- if (ret && ret != -ENOENT) {
- printf("Error in consume_stream\n");
- return ret;
- }
- }
- unmap_channel(handle);
-
- return 0;
-}
-
-static
-int send_app_msgs(int sock, const char *outputpath,
- unsigned int nr_events, const char **event_names)
-{
- struct ustcomm_ust_msg lum;
- struct ustcomm_ust_reply lur;
- int ret, k;
-
- /* Create session */
- memset(&lum, 0, sizeof(lum));
- lum.handle = LTTNG_UST_ROOT_HANDLE;
- lum.cmd = LTTNG_UST_SESSION;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- session_handle = lur.ret_val;
- printf("received session handle %u\n", session_handle);
-
- /* Create metadata channel */
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle;
- lum.cmd = LTTNG_UST_METADATA;
- lum.u.channel.overwrite = 0;
- lum.u.channel.subbuf_size = 32768;
- lum.u.channel.num_subbuf = 4;
- lum.u.channel.switch_timer_interval = 0;
- lum.u.channel.read_timer_interval = 0;
- lum.u.channel.output = LTTNG_UST_MMAP;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- metadata_data.handle = lur.ret_val;
- printf("received metadata handle %u\n", metadata_data.handle);
- if (lur.ret_code == LTTNG_UST_OK) {
- ssize_t len;
-
- metadata_data.memory_map_size = lur.u.channel.memory_map_size;
- /* get shm fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- metadata_data.shm_fd = len;
- /* get wait fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- metadata_data.wait_fd = len;
- }
-
- ret = open_streams(sock, metadata_data.handle,
- &metadata_stream_data, 1);
- if (ret) {
- printf("Error in open_streams\n");
- return ret;
- }
-
- /* Create data channel */
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle;
- lum.cmd = LTTNG_UST_CHANNEL;
- //lum.u.channel.overwrite = 0;
- lum.u.channel.overwrite = 1;
- lum.u.channel.subbuf_size = 32768;
- lum.u.channel.num_subbuf = 8;
- //lum.u.channel.num_subbuf = 4;
- //lum.u.channel.num_subbuf = 2;
- lum.u.channel.switch_timer_interval = 0;
- lum.u.channel.read_timer_interval = 0;
- lum.u.channel.output = LTTNG_UST_MMAP;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- channel_data.handle = lur.ret_val;
- printf("received channel handle %u\n", channel_data.handle);
- if (lur.ret_code == LTTNG_UST_OK) {
- ssize_t len;
-
- channel_data.memory_map_size = lur.u.channel.memory_map_size;
- /* get shm fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- channel_data.shm_fd = len;
- /* get wait fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- channel_data.wait_fd = len;
- }
-
- /* Create events */
- for (k = 0; k < nr_events; k++) {
- memset(&lum, 0, sizeof(lum));
- lum.handle = channel_data.handle;
- lum.cmd = LTTNG_UST_EVENT;
- strncpy(lum.u.event.name, event_names[k],
- LTTNG_UST_SYM_NAME_LEN);
- lum.u.event.instrumentation = LTTNG_UST_TRACEPOINT;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- event_handle[k] = lur.ret_val;
- printf("received event handle %u\n", event_handle[k]);
- }
-
- /* Attach vtid context */
- memset(&lum, 0, sizeof(lum));
- lum.handle = channel_data.handle;
- lum.cmd = LTTNG_UST_CONTEXT;
- lum.u.context.ctx = LTTNG_UST_CONTEXT_VTID;
- //lum.u.context.ctx = LTTNG_UST_CONTEXT_PTHREAD_ID;
- //lum.u.context.ctx = LTTNG_UST_CONTEXT_VPID;
- //lum.u.context.ctx = LTTNG_UST_CONTEXT_PROCNAME;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- context_handle = lur.ret_val;
- printf("received context handle %u\n", context_handle);
-
- /* Get references to channel streams */
- ret = open_streams(sock, channel_data.handle,
- stream_data, MAX_NR_STREAMS);
- if (ret) {
- printf("Error in open_streams\n");
- return ret;
- }
-
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle;
- lum.cmd = LTTNG_UST_SESSION_START;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- printf("Session handle %u started.\n", session_handle);
-
- /* Tell application registration is done */
- memset(&lum, 0, sizeof(lum));
- lum.handle = LTTNG_UST_ROOT_HANDLE;
- lum.cmd = LTTNG_UST_REGISTER_DONE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- printf("Registration done acknowledged.\n");
-
- sleep(4);
-
- ret = consume_buffers(outputpath);
- if (ret) {
- printf("Error in consume_buffers\n");
- return ret;
- }
-
- /* Release data channel */
- /* Release streams */
- ret = close_streams(sock, stream_data,
- MAX_NR_STREAMS);
- if (ret)
- return ret;
-
- /* Release context */
- memset(&lum, 0, sizeof(lum));
- lum.handle = context_handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
-
- /* Release events */
- for (k = 0; k < nr_events; k++) {
- memset(&lum, 0, sizeof(lum));
- lum.handle = event_handle[k];
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- }
- memset(&lum, 0, sizeof(lum));
- lum.handle = channel_data.handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- if (channel_data.shm_fd >= 0) {
- ret = close(channel_data.shm_fd);
- if (ret)
- return ret;
- }
- if (channel_data.wait_fd >= 0) {
- ret = close(channel_data.wait_fd);
- if (ret)
- return ret;
- }
-
- /* Release metadata channel */
- ret = close_streams(sock, &metadata_stream_data, 1);
- if (ret)
- return ret;
-
- memset(&lum, 0, sizeof(lum));
- lum.handle = metadata_data.handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- if (metadata_data.shm_fd >= 0) {
- ret = close(metadata_data.shm_fd);
- if (ret)
- return ret;
- }
- if (metadata_data.wait_fd >= 0) {
- ret = close(metadata_data.wait_fd);
- if (ret)
- return ret;
- }
-
- /* Release session */
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
-
- return 0;
-}
-
-/*
- * Using fork to set umask in the child process (not multi-thread safe). We
- * deal with the shm_open vs ftruncate race (happening when the sessiond owns
- * the shm and does not let everybody modify it, to ensure safety against
- * shm_unlink) by simply letting the mmap fail and retrying after a few
- * seconds. For global shm, everybody has rw access to it until the sessiond
- * starts.
- */
-static int get_wait_shm(char *shm_path, size_t mmap_size, int global)
-{
- int wait_shm_fd, ret;
- mode_t mode;
-
- /* Default permissions */
- mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
-
- /* Change owner of the shm path */
- if (global) {
- ret = chown(shm_path, 0, 0);
- if (ret < 0) {
- if (errno != ENOENT) {
- perror("chown wait shm");
- goto error;
- }
- }
-
- /*
- * If global session daemon, any application can register so the shm
- * needs to be set in read-only mode for others.
- */
- mode |= S_IROTH;
- } else {
- ret = chown(shm_path, getuid(), getgid());
- if (ret < 0) {
- if (errno != ENOENT) {
- perror("chown wait shm");
- goto error;
- }
- }
- }
-
- /*
- * Set permissions to the shm even if we did not create the shm.
- */
- ret = chmod(shm_path, mode);
- if (ret < 0) {
- if (errno != ENOENT) {
- perror("chmod wait shm");
- goto error;
- }
- }
-
- /*
- * We're alone in a child process, so we can modify the process-wide
- * umask.
- */
- umask(~mode);
-
- /*
- * Try creating shm (or get rw access). We don't do an exclusive open,
- * because we allow other processes to create+ftruncate it concurrently.
- */
- wait_shm_fd = shm_open(shm_path, O_RDWR | O_CREAT, mode);
- if (wait_shm_fd < 0) {
- perror("shm_open wait shm");
- goto error;
- }
-
- ret = ftruncate(wait_shm_fd, mmap_size);
- if (ret < 0) {
- perror("ftruncate wait shm");
- exit(EXIT_FAILURE);
- }
-
- ret = fchmod(wait_shm_fd, mode);
- if (ret < 0) {
- perror("fchmod");
- exit(EXIT_FAILURE);
- }
-
- printf("Got the wait shm fd %d\n", wait_shm_fd);
-
- return wait_shm_fd;
-
-error:
- printf("Failing to get the wait shm fd\n");
-
- return -1;
-}
-
-int update_futex(int fd, int active)
-{
- long page_size;
- char *wait_shm_mmap;
- int ret;
-
- page_size = sysconf(_SC_PAGE_SIZE);
- if (page_size <= 0) {
- if (!page_size) {
- errno = EINVAL;
- }
- perror("Error in sysconf(_SC_PAGE_SIZE)");
- goto error;
- }
- wait_shm_mmap = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (wait_shm_mmap == MAP_FAILED) {
- perror("mmap");
- goto error;
- }
-
- if (active) {
- uatomic_set((int32_t *) wait_shm_mmap, 1);
- if (futex_async((int32_t *) wait_shm_mmap, FUTEX_WAKE,
- INT_MAX, NULL, NULL, 0) < 0) {
- perror("futex_async");
- goto error;
- }
- } else {
- uatomic_set((int32_t *) wait_shm_mmap, 0);
- }
- ret = munmap(wait_shm_mmap, page_size);
- if (ret) {
- perror("Error unmapping wait shm");
- goto error;
- }
- return 0;
-error:
- return -1;
-}
-
-/*
- * Set open files limit to unlimited. This daemon can open a large number of
- * file descriptors in order to consumer multiple kernel traces.
- */
-static void set_ulimit(void)
-{
- int ret;
- struct rlimit lim;
-
- /*
- * If not root, we cannot increase our max open files. But our
- * scope is then limited to processes from a single user.
- */
- if (getuid() != 0)
- return;
- /* The kernel does not allowed an infinite limit for open files */
- lim.rlim_cur = 65535;
- lim.rlim_max = 65535;
-
- ret = setrlimit(RLIMIT_NOFILE, &lim);
- if (ret < 0) {
- perror("failed to set open files limit");
- }
-}
-
-/*
- * Usage:
- * ./ust-basic-tracing outputpath event_name1 event_name2 ....
- */
-int main(int argc, const char **argv)
-{
- const char *home_dir;
- char home_rundir[PATH_MAX];
- char *cmd = NULL;
- int ret, wait_shm_fd;
- struct sigaction act;
- mode_t old_umask = 0;
- const char *outputpath;
- const char **event_names;
- unsigned int nr_events;
- long page_size;
-
- if (argc < 2) {
- printf("Usage:\n");
- printf("%s outputpath event_name1 event_name2 ...\n",
- argv[0]);
- exit(-1);
- }
- outputpath = argv[1];
- event_names = &argv[2];
- nr_events = argc - 2;
-
- set_ulimit();
-
- /* Ignore sigpipe */
- memset(&act, 0, sizeof(act));
- ret = sigemptyset(&act.sa_mask);
- if (ret == -1) {
- perror("sigemptyset");
- return -1;
- }
-
- act.sa_handler = SIG_IGN;
- ret = sigaction(SIGPIPE, &act, NULL);
- if (ret == -1) {
- perror("sigaction");
- return -1;
- }
-
- /* Handle SIGTERM */
- act.sa_handler = handle_signals;
- ret = sigaction(SIGTERM, &act, NULL);
- if (ret == -1) {
- perror("sigaction");
- return -1;
- }
- /* Handle SIGINT */
- ret = sigaction(SIGINT, &act, NULL);
- if (ret == -1) {
- perror("sigaction");
- return -1;
- }
-
- page_size = sysconf(_SC_PAGE_SIZE);
- if (page_size <= 0) {
- if (!page_size) {
- errno = EINVAL;
- }
- perror("Error in sysconf(_SC_PAGE_SIZE)");
- return -1;
- }
-
- if (geteuid() == 0) {
- ret = mkdir(LTTNG_RUNDIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- if (ret && errno != EEXIST) {
- perror("mkdir");
- return -1;
- }
- wait_shm_fd = get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH,
- page_size, 1);
- if (wait_shm_fd < 0) {
- perror("global wait shm error");
- return -1;
- }
- strcpy(apps_sock_path, DEFAULT_GLOBAL_APPS_UNIX_SOCK);
- old_umask = umask(0);
- } else {
- home_dir = (const char *) getenv("HOME");
- if (!home_dir) {
- perror("getenv error");
- return -ENOENT;
- }
-
- snprintf(home_rundir, PATH_MAX,
- LTTNG_HOME_RUNDIR, home_dir);
-
- ret = mkdir(home_rundir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- if (ret && errno != EEXIST) {
- perror("mkdir");
- return -1;
- }
-
- snprintf(local_apps_wait_shm_path, PATH_MAX,
- DEFAULT_HOME_APPS_WAIT_SHM_PATH, getuid());
- wait_shm_fd = get_wait_shm(local_apps_wait_shm_path,
- page_size, 0);
- if (wait_shm_fd < 0) {
- perror("local wait shm error");
- return -1;
- }
- snprintf(apps_sock_path, PATH_MAX,
- DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
- }
-
- ret = ustcomm_create_unix_sock(apps_sock_path);
- if (ret < 0) {
- perror("create error");
- return ret;
- }
- apps_socket = ret;
-
- if (getuid() == 0) {
- /* File permission MUST be 666 */
- ret = chmod(apps_sock_path,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (ret < 0) {
- printf("Set file permissions failed: %s\n", apps_sock_path);
- perror("chmod");
- goto end;
- }
- umask(old_umask);
- }
- ret = ustcomm_listen_unix_sock(apps_socket);
- if (ret < 0) {
- perror("listen error");
- return ret;
- }
-
- /* wake up futexes */
- ret = update_futex(wait_shm_fd, 1);
- if (ret) {
- fprintf(stderr, "Error wakeup futex\n");
- return -1;
- }
-
- for (;;) {
- int sock;
- ssize_t len;
- struct {
- uint32_t major;
- uint32_t minor;
- pid_t pid;
- pid_t ppid;
- uid_t uid;
- gid_t gid;
- uint32_t bits_per_long;
- char name[16]; /* Process name */
- } reg_msg;
- char bufname[17];
-
- if (quit_program)
- break;
-
- printf("Accepting application registration\n");
- sock = ustcomm_accept_unix_sock(apps_socket);
- if (sock < 0) {
- perror("accept error");
- goto end;
- }
-
- /*
- * Basic recv here to handle the very simple data
- * that the libust send to register (reg_msg).
- */
- len = ustcomm_recv_unix_sock(sock, ®_msg, sizeof(reg_msg));
- if (len < 0 || len != sizeof(reg_msg)) {
- perror("ustcomm_recv_unix_sock");
- continue;
- }
- memcpy(bufname, reg_msg.name, 16);
- bufname[16] = '\0';
- printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
- bufname, reg_msg.pid, reg_msg.ppid, reg_msg.uid,
- reg_msg.gid, reg_msg.major, reg_msg.minor);
- ret = send_app_msgs(sock, outputpath, nr_events, event_names);
- if (ret) {
- printf("Error in send_app_msgs.\n");
- sleep(1);
- }
- close(sock);
- }
-
-end:
- printf("quitting.\n");
- /* Let applications know we are not responding anymore */
- ret = update_futex(wait_shm_fd, 0);
- if (ret) {
- fprintf(stderr, "Error wakeup futex\n");
- return -1;
- }
-
- if (geteuid()) {
- printf("Removing %s directory\n", home_rundir);
- ret = asprintf(&cmd, "rm -rf %s", home_rundir);
- if (ret < 0) {
- printf("asprintf failed. Something is really wrong!\n");
- return -1;
- }
-
- /* Remove lttng run directory */
- ret = system(cmd);
- if (ret < 0) {
- printf("Unable to clean %s\n", home_rundir);
- return -1;
- }
- }
-
-
- return 0;
-}
+++ /dev/null
-AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/libust
-
-noinst_PROGRAMS = ust-multi-test
-ust_multi_test_SOURCES = ust-multi-test.c
-ust_multi_test_LDADD = $(top_builddir)/liblttng-ust-comm/liblttng-ust-comm.la \
- $(top_builddir)/libringbuffer/libringbuffer.la \
- $(top_builddir)/snprintf/libustsnprintf.la
+++ /dev/null
-/*
- * ust-multi-test.c - single-proces, multi-session, multi-channel, multi-event UST tracing
- *
- * Copyright (C) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * 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; version 2 of the License only.
- *
- * 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 _LARGEFILE64_SOURCE
-#define _GNU_SOURCE
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <urcu/futex.h>
-#include <urcu/uatomic.h>
-
-#include <ust-comm.h>
-#include <lttng/ust-error.h>
-#include <../../libringbuffer/backend.h>
-#include <../../libringbuffer/frontend.h>
-#include "../../liblttng-ust/compat.h" /* For ENODATA */
-
-#define NR_SESSIONS 4
-#define NR_CHANNELS 1
-#define MAX_NR_STREAMS 64
-#define NR_EVENTS 3
-
-const char *evname[] = {
- "ust_tests_hello_tptest",
- "ust_tests_hello_tptest_sighandler",
- "ust_tests_hello_dontexist",
-};
-
-static int session_handle[NR_SESSIONS];
-static struct lttng_ust_object_data metadata_stream_data[NR_SESSIONS];
-static struct lttng_ust_object_data metadata_data[NR_SESSIONS];
-static struct lttng_ust_object_data channel_data[NR_SESSIONS][NR_CHANNELS];
-static struct lttng_ust_object_data stream_data[NR_SESSIONS][NR_CHANNELS][MAX_NR_STREAMS];
-static int event_handle[NR_SESSIONS][NR_CHANNELS][NR_EVENTS];
-
-static int apps_socket = -1;
-static char apps_sock_path[PATH_MAX];
-static char local_apps_wait_shm_path[PATH_MAX];
-
-static volatile int quit_program;
-
-static void handle_signals(int signo)
-{
- quit_program = 1;
-}
-
-static
-int open_streams(int sock, int channel_handle, struct lttng_ust_object_data *stream_datas,
- int nr_check)
-{
- int ret, k = 0;
-
- for (;;) {
- struct ustcomm_ust_msg lum;
- struct ustcomm_ust_reply lur;
-
- memset(&lum, 0, sizeof(lum));
- lum.handle = channel_handle;
- lum.cmd = LTTNG_UST_STREAM;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (!ret) {
- assert(k < nr_check);
- stream_datas[k].handle = lur.ret_val;
- printf("received stream handle %u\n",
- stream_datas[k].handle);
- if (lur.ret_code == LTTNG_UST_OK) {
- ssize_t len;
-
- stream_datas[k].memory_map_size = lur.u.stream.memory_map_size;
- /* get shm fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- stream_datas[k].shm_fd = len;
- /* get wait fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- stream_datas[k].wait_fd = len;
- }
- k++;
- }
- if (ret == -LTTNG_UST_ERR_NOENT)
- break;
- if (ret)
- return ret;
- }
- return 0;
-}
-
-static
-int close_streams(int sock, struct lttng_ust_object_data *stream_datas, int nr_check)
-{
- int ret, k;
-
- for (k = 0; k < nr_check; k++) {
- struct ustcomm_ust_msg lum;
- struct ustcomm_ust_reply lur;
-
- if (!stream_datas[k].handle)
- continue;
- memset(&lum, 0, sizeof(lum));
- lum.handle = stream_datas[k].handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret) {
- printf("Error closing stream\n");
- return ret;
- }
- if (stream_datas[k].shm_fd >= 0) {
- ret = close(stream_datas[k].shm_fd);
- if (ret) {
- printf("Error closing stream shm_fd\n");
- return ret;
- }
- }
- if (stream_datas[k].wait_fd >= 0) {
- ret = close(stream_datas[k].wait_fd);
- if (ret) {
- printf("Error closing stream wait_fd\n");
- return ret;
- }
- }
- }
- return 0;
-}
-
-static
-struct lttng_ust_shm_handle *map_channel(struct lttng_ust_object_data *chan_data,
- struct lttng_ust_object_data *stream_datas, int nr_check)
-{
- struct lttng_ust_shm_handle *handle;
- struct channel *chan;
- int k, ret;
-
- /* map metadata channel */
- handle = channel_handle_create(chan_data->shm_fd,
- chan_data->wait_fd,
- chan_data->memory_map_size);
- if (!handle) {
- printf("create handle error\n");
- return NULL;
- }
- chan_data->shm_fd = -1;
- chan_data->wait_fd = -1;
- chan = shmp(handle, handle->chan);
-
- for (k = 0; k < nr_check; k++) {
- struct lttng_ust_object_data *stream_data = &stream_datas[k];
-
- if (!stream_data->handle)
- break;
- /* map stream */
- ret = channel_handle_add_stream(handle,
- stream_data->shm_fd,
- stream_data->wait_fd,
- stream_data->memory_map_size);
- if (ret) {
- printf("add stream error\n");
- goto error_destroy;
- }
- stream_data->shm_fd = -1;
- stream_data->wait_fd = -1;
- }
- return handle;
-
-error_destroy:
- channel_destroy(chan, handle, 1);
- return NULL;
-}
-
-static
-void unmap_channel(struct lttng_ust_shm_handle *handle)
-{
- struct channel *chan;
-
- chan = shmp(handle, handle->chan);
- /* unmap channel */
- channel_destroy(chan, handle, 1);
-}
-
-static
-int consume_stream(struct lttng_ust_shm_handle *handle, int cpu, char *outfile)
-{
- struct channel *chan;
- struct lttng_ust_lib_ring_buffer *buf;
- int outfd, ret;
- int *shm_fd, *wait_fd;
- uint64_t *memory_map_size;
-
- chan = shmp(handle, handle->chan);
-
- /* open stream */
- buf = channel_get_ring_buffer(&chan->backend.config,
- chan, cpu, handle, &shm_fd, &wait_fd, &memory_map_size);
- if (!buf)
- return -ENOENT;
- ret = lib_ring_buffer_open_read(buf, handle, 1);
- if (ret) {
- return -1;
- }
-
- /* copy */
- outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
- if (outfd < 0) {
- perror("open output");
- return -1;
- }
-
- printf("Waiting for buffer data for %s\n", outfile);
- for (;;) {
- unsigned long read_size;
- unsigned long copy_size;
- char *ptr;
-
- ret = lib_ring_buffer_get_next_subbuf(buf, handle);
- printf("get next ret %d\n", ret);
- if (ret == -ENODATA)
- break;
- if (ret == -EAGAIN) {
- sleep(1);
- continue;
- }
- if (ret) {
- printf("Error %d in lib_ring_buffer_get_next_subbuf\n", ret);
- return -1;
- }
- read_size = lib_ring_buffer_get_read_data_size(
- &chan->backend.config, buf, handle);
- read_size = LTTNG_UST_PAGE_ALIGN(read_size);
- ptr = lib_ring_buffer_read_offset_address(
- &buf->backend, 0, handle);
- printf("WRITE: copy %lu bytes\n", read_size);
- copy_size = write(outfd, ptr, read_size);
- if (copy_size < read_size) {
- printf("write issue: copied %lu, expected %lu\n", copy_size, read_size);
- }
- lib_ring_buffer_put_next_subbuf(buf, handle);
- }
-
- ret = close(outfd);
- if (ret) {
- perror("close");
- return -1;
- }
-
- /* close stream */
- lib_ring_buffer_release_read(buf, handle, 1);
- return 0;
-}
-
-static
-int consume_buffers(void)
-{
- int i, j, k, ret;
- mode_t old_umask;
-
- for (i = 0; i < NR_SESSIONS; i++) {
- char pathname[PATH_MAX];
- struct lttng_ust_shm_handle *handle;
-
- snprintf(pathname, PATH_MAX - 1, "/tmp/testtrace%u", i);
- old_umask = umask(0);
- ret = mkdir(pathname, S_IRWXU | S_IRWXG);
- if (ret && errno != EEXIST) {
- perror("mkdir");
- umask(old_umask);
- return -1;
- }
- umask(old_umask);
-
- /* copy metadata */
- handle = map_channel(&metadata_data[i],
- &metadata_stream_data[i], 1);
- if (!handle)
- return -1;
- snprintf(pathname, PATH_MAX - 1,
- "/tmp/testtrace%u/metadata", i);
- ret = consume_stream(handle, -1, pathname);
- if (ret && ret != -ENOENT) {
- printf("Error in consume_stream\n");
- return ret;
- }
- unmap_channel(handle);
-
- /* copy binary data */
- for (j = 0; j < NR_CHANNELS; j++) {
- handle = map_channel(&channel_data[i][j],
- stream_data[i][j], MAX_NR_STREAMS);
- if (!handle)
- return -1;
- for (k = 0; k < MAX_NR_STREAMS; k++) {
- snprintf(pathname, PATH_MAX - 1,
- "/tmp/testtrace%u/data_%u", i, k);
- ret = consume_stream(handle, k, pathname);
- if (ret && ret != -ENOENT) {
- printf("Error in consume_stream\n");
- return ret;
- }
- }
- unmap_channel(handle);
- }
- }
-
- return 0;
-}
-
-int send_app_msgs(int sock)
-{
- struct ustcomm_ust_msg lum;
- struct ustcomm_ust_reply lur;
- int ret, i, j, k;
-
- for (i = 0; i < NR_SESSIONS; i++) {
- /* Create session */
- memset(&lum, 0, sizeof(lum));
- lum.handle = LTTNG_UST_ROOT_HANDLE;
- lum.cmd = LTTNG_UST_SESSION;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- session_handle[i] = lur.ret_val;
- printf("received session handle %u\n", session_handle[i]);
-
- /* Create metadata channel */
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle[i];
- lum.cmd = LTTNG_UST_METADATA;
- lum.u.channel.overwrite = 0;
- lum.u.channel.subbuf_size = 32768;
- lum.u.channel.num_subbuf = 4;
- lum.u.channel.switch_timer_interval = 0;
- lum.u.channel.read_timer_interval = 0;
- lum.u.channel.output = LTTNG_UST_MMAP;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- metadata_data[i].handle = lur.ret_val;
- printf("received metadata handle %u\n", metadata_data[i].handle);
- if (lur.ret_code == LTTNG_UST_OK) {
- ssize_t len;
-
- metadata_data[i].memory_map_size = lur.u.channel.memory_map_size;
- /* get shm fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- metadata_data[i].shm_fd = len;
- /* get wait fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- metadata_data[i].wait_fd = len;
- }
-
- ret = open_streams(sock, metadata_data[i].handle,
- &metadata_stream_data[i], 1);
- if (ret) {
- printf("Error in open_streams\n");
- return ret;
- }
-
- /* Create channels */
- for (j = 0; j < NR_CHANNELS; j++) {
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle[i];
- lum.cmd = LTTNG_UST_CHANNEL;
- //lum.u.channel.overwrite = 0;
- lum.u.channel.overwrite = 1;
- lum.u.channel.subbuf_size = 32768;
- lum.u.channel.num_subbuf = 8;
- //lum.u.channel.num_subbuf = 4;
- //lum.u.channel.num_subbuf = 2;
- lum.u.channel.switch_timer_interval = 0;
- lum.u.channel.read_timer_interval = 0;
- lum.u.channel.output = LTTNG_UST_MMAP;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- channel_data[i][j].handle = lur.ret_val;
- printf("received channel handle %u\n", channel_data[i][j].handle);
- if (lur.ret_code == LTTNG_UST_OK) {
- ssize_t len;
-
- channel_data[i][j].memory_map_size = lur.u.channel.memory_map_size;
- /* get shm fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- channel_data[i][j].shm_fd = len;
- /* get wait fd */
- len = ustcomm_recv_fd(sock);
- if (len < 0)
- return -EINVAL;
- channel_data[i][j].wait_fd = len;
- }
-
- /* Create events */
- for (k = 0; k < NR_EVENTS; k++) {
- memset(&lum, 0, sizeof(lum));
- lum.handle = channel_data[i][j].handle;
- lum.cmd = LTTNG_UST_EVENT;
- strncpy(lum.u.event.name, evname[k],
- LTTNG_UST_SYM_NAME_LEN);
- lum.u.event.instrumentation = LTTNG_UST_TRACEPOINT;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- event_handle[i][j][k] = lur.ret_val;
- printf("received event handle %u\n", event_handle[i][j][k]);
- }
-
- /* Get references to channel streams */
- ret = open_streams(sock, channel_data[i][j].handle,
- stream_data[i][j], MAX_NR_STREAMS);
- if (ret) {
- printf("Error in open_streams\n");
- return ret;
- }
- }
-
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle[i];
- lum.cmd = LTTNG_UST_SESSION_START;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- printf("Session handle %u started.\n", session_handle[i]);
- }
-
- /* Tell application registration is done */
- memset(&lum, 0, sizeof(lum));
- lum.handle = LTTNG_UST_ROOT_HANDLE;
- lum.cmd = LTTNG_UST_REGISTER_DONE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- printf("Registration done acknowledged.\n");
-
- sleep(4);
-
- ret = consume_buffers();
- if (ret) {
- printf("Error in consume_buffers\n");
- return ret;
- }
-
- for (i = 0; i < NR_SESSIONS; i++) {
- /* Release channels */
- for (j = 0; j < NR_CHANNELS; j++) {
- /* Release streams */
- ret = close_streams(sock, stream_data[i][j],
- MAX_NR_STREAMS);
- if (ret)
- return ret;
-
- /* Release events */
- for (k = 0; k < NR_EVENTS; k++) {
- memset(&lum, 0, sizeof(lum));
- lum.handle = event_handle[i][j][k];
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- }
- memset(&lum, 0, sizeof(lum));
- lum.handle = channel_data[i][j].handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- if (channel_data[i][j].shm_fd >= 0) {
- ret = close(channel_data[i][j].shm_fd);
- if (ret)
- return ret;
- }
- if (channel_data[i][j].wait_fd >= 0) {
- ret = close(channel_data[i][j].wait_fd);
- if (ret)
- return ret;
- }
- }
-
- /* Release metadata channel */
- ret = close_streams(sock, &metadata_stream_data[i], 1);
- if (ret)
- return ret;
-
- memset(&lum, 0, sizeof(lum));
- lum.handle = metadata_data[i].handle;
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- if (metadata_data[i].shm_fd >= 0) {
- ret = close(metadata_data[i].shm_fd);
- if (ret)
- return ret;
- }
- if (metadata_data[i].wait_fd >= 0) {
- ret = close(metadata_data[i].wait_fd);
- if (ret)
- return ret;
- }
-
- /* Release session */
- memset(&lum, 0, sizeof(lum));
- lum.handle = session_handle[i];
- lum.cmd = LTTNG_UST_RELEASE;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/*
- * Using fork to set umask in the child process (not multi-thread safe). We
- * deal with the shm_open vs ftruncate race (happening when the sessiond owns
- * the shm and does not let everybody modify it, to ensure safety against
- * shm_unlink) by simply letting the mmap fail and retrying after a few
- * seconds. For global shm, everybody has rw access to it until the sessiond
- * starts.
- */
-static int get_wait_shm(char *shm_path, size_t mmap_size, int global)
-{
- int wait_shm_fd, ret;
- mode_t mode;
-
- /* Default permissions */
- mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
-
- /* Change owner of the shm path */
- if (global) {
- ret = chown(shm_path, 0, 0);
- if (ret < 0) {
- if (errno != ENOENT) {
- perror("chown wait shm");
- goto error;
- }
- }
-
- /*
- * If global session daemon, any application can register so the shm
- * needs to be set in read-only mode for others.
- */
- mode |= S_IROTH;
- } else {
- ret = chown(shm_path, getuid(), getgid());
- if (ret < 0) {
- if (errno != ENOENT) {
- perror("chown wait shm");
- goto error;
- }
- }
- }
-
- /*
- * Set permissions to the shm even if we did not create the shm.
- */
- ret = chmod(shm_path, mode);
- if (ret < 0) {
- if (errno != ENOENT) {
- perror("chmod wait shm");
- goto error;
- }
- }
-
- /*
- * We're alone in a child process, so we can modify the process-wide
- * umask.
- */
- umask(~mode);
-
- /*
- * Try creating shm (or get rw access). We don't do an exclusive open,
- * because we allow other processes to create+ftruncate it concurrently.
- */
- wait_shm_fd = shm_open(shm_path, O_RDWR | O_CREAT, mode);
- if (wait_shm_fd < 0) {
- perror("shm_open wait shm");
- goto error;
- }
-
- ret = ftruncate(wait_shm_fd, mmap_size);
- if (ret < 0) {
- perror("ftruncate wait shm");
- exit(EXIT_FAILURE);
- }
-
- ret = fchmod(wait_shm_fd, mode);
- if (ret < 0) {
- perror("fchmod");
- exit(EXIT_FAILURE);
- }
-
- printf("Got the wait shm fd %d\n", wait_shm_fd);
-
- return wait_shm_fd;
-
-error:
- printf("Failing to get the wait shm fd\n");
-
- return -1;
-}
-
-int update_futex(int fd, int active)
-{
- long page_size;
- char *wait_shm_mmap;
- int ret;
-
- page_size = sysconf(_SC_PAGE_SIZE);
- if (page_size <= 0) {
- if (!page_size) {
- errno = EINVAL;
- }
- perror("Error in sysconf(_SC_PAGE_SIZE)");
- goto error;
- }
- wait_shm_mmap = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (wait_shm_mmap == MAP_FAILED) {
- perror("mmap");
- goto error;
- }
-
- if (active) {
- uatomic_set((int32_t *) wait_shm_mmap, 1);
- if (futex_async((int32_t *) wait_shm_mmap, FUTEX_WAKE,
- INT_MAX, NULL, NULL, 0) < 0) {
- perror("futex_async");
- goto error;
- }
- } else {
- uatomic_set((int32_t *) wait_shm_mmap, 0);
- }
- ret = munmap(wait_shm_mmap, page_size);
- if (ret) {
- perror("Error unmapping wait shm");
- goto error;
- }
- return 0;
-error:
- return -1;
-}
-
-/*
- * Set open files limit to unlimited. This daemon can open a large number of
- * file descriptors in order to consumer multiple kernel traces.
- */
-static void set_ulimit(void)
-{
- int ret;
- struct rlimit lim;
-
- /*
- * If not root, we cannot increase our max open files. But our
- * scope is then limited to processes from a single user.
- */
- if (getuid() != 0)
- return;
- /* The kernel does not allowed an infinite limit for open files */
- lim.rlim_cur = 65535;
- lim.rlim_max = 65535;
-
- ret = setrlimit(RLIMIT_NOFILE, &lim);
- if (ret < 0) {
- perror("failed to set open files limit");
- }
-}
-
-int main(int argc, char **argv)
-{
- const char *home_dir;
- char home_rundir[PATH_MAX];
- char *cmd = NULL;
- int ret, wait_shm_fd;
- struct sigaction act;
- mode_t old_umask = 0;
- long page_size;
-
- set_ulimit();
-
- /* Ignore sigpipe */
- memset(&act, 0, sizeof(act));
- ret = sigemptyset(&act.sa_mask);
- if (ret == -1) {
- perror("sigemptyset");
- return -1;
- }
-
- act.sa_handler = SIG_IGN;
- ret = sigaction(SIGPIPE, &act, NULL);
- if (ret == -1) {
- perror("sigaction");
- return -1;
- }
-
- /* Handle SIGTERM */
- act.sa_handler = handle_signals;
- ret = sigaction(SIGTERM, &act, NULL);
- if (ret == -1) {
- perror("sigaction");
- return -1;
- }
- /* Handle SIGINT */
- ret = sigaction(SIGINT, &act, NULL);
- if (ret == -1) {
- perror("sigaction");
- return -1;
- }
-
- page_size = sysconf(_SC_PAGE_SIZE);
- if (page_size <= 0) {
- if (!page_size) {
- errno = EINVAL;
- }
- perror("Error in sysconf(_SC_PAGE_SIZE)");
- return -1;
- }
-
- if (geteuid() == 0) {
- ret = mkdir(LTTNG_RUNDIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- if (ret && errno != EEXIST) {
- perror("mkdir");
- return -1;
- }
- wait_shm_fd = get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH,
- page_size, 1);
- if (wait_shm_fd < 0) {
- perror("global wait shm error");
- return -1;
- }
- strcpy(apps_sock_path, DEFAULT_GLOBAL_APPS_UNIX_SOCK);
- old_umask = umask(0);
- } else {
- home_dir = (const char *) getenv("HOME");
- if (!home_dir) {
- perror("getenv error");
- return -ENOENT;
- }
-
- snprintf(home_rundir, PATH_MAX,
- LTTNG_HOME_RUNDIR, home_dir);
-
- ret = mkdir(home_rundir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- if (ret && errno != EEXIST) {
- perror("mkdir");
- return -1;
- }
-
- snprintf(local_apps_wait_shm_path, PATH_MAX,
- DEFAULT_HOME_APPS_WAIT_SHM_PATH, getuid());
- wait_shm_fd = get_wait_shm(local_apps_wait_shm_path,
- page_size, 0);
- if (wait_shm_fd < 0) {
- perror("local wait shm error");
- return -1;
- }
- snprintf(apps_sock_path, PATH_MAX,
- DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
- }
-
- ret = ustcomm_create_unix_sock(apps_sock_path);
- if (ret < 0) {
- perror("create error");
- return ret;
- }
- apps_socket = ret;
-
- if (getuid() == 0) {
- /* File permission MUST be 666 */
- ret = chmod(apps_sock_path,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (ret < 0) {
- printf("Set file permissions failed: %s\n", apps_sock_path);
- perror("chmod");
- goto end;
- }
- umask(old_umask);
- }
- ret = ustcomm_listen_unix_sock(apps_socket);
- if (ret < 0) {
- perror("listen error");
- return ret;
- }
-
- /* wake up futexes */
- ret = update_futex(wait_shm_fd, 1);
- if (ret) {
- fprintf(stderr, "Error wakeup futex\n");
- return -1;
- }
-
- for (;;) {
- int sock;
- ssize_t len;
- struct {
- uint32_t major;
- uint32_t minor;
- pid_t pid;
- pid_t ppid;
- uid_t uid;
- gid_t gid;
- uint32_t bits_per_long;
- char name[16]; /* Process name */
- } reg_msg;
- char bufname[17];
-
- if (quit_program)
- break;
-
- printf("Accepting application registration\n");
- sock = ustcomm_accept_unix_sock(apps_socket);
- if (sock < 0) {
- perror("accept error");
- goto end;
- }
-
- /*
- * Basic recv here to handle the very simple data
- * that the libust send to register (reg_msg).
- */
- len = ustcomm_recv_unix_sock(sock, ®_msg, sizeof(reg_msg));
- if (len < 0 || len != sizeof(reg_msg)) {
- perror("ustcomm_recv_unix_sock");
- continue;
- }
- memcpy(bufname, reg_msg.name, 16);
- bufname[16] = '\0';
- printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
- bufname, reg_msg.pid, reg_msg.ppid, reg_msg.uid,
- reg_msg.gid, reg_msg.major, reg_msg.minor);
- ret = send_app_msgs(sock);
- if (ret) {
- printf("Error in send_app_msgs.\n");
- sleep(1);
- }
- close(sock);
- }
-
-end:
- printf("quitting.\n");
- /* Let applications know we are not responding anymore */
- ret = update_futex(wait_shm_fd, 0);
- if (ret) {
- fprintf(stderr, "Error wakeup futex\n");
- return -1;
- }
-
- if (geteuid()) {
- printf("Removing %s directory\n", home_rundir);
- ret = asprintf(&cmd, "rm -rf %s", home_rundir);
- if (ret < 0) {
- printf("asprintf failed. Something is really wrong!\n");
- return -1;
- }
-
- /* Remove lttng run directory */
- ret = system(cmd);
- if (ret < 0) {
- printf("Unable to clean %s\n", home_rundir);
- return -1;
- }
- }
-
- return 0;
-}
+++ /dev/null
-AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -Wsystem-headers
-
-noinst_PROGRAMS = ust-variant
-ust_variant_SOURCES = ust-variant.c
-ust_variant_LDADD = $(top_builddir)/liblttng-ust/liblttng-ust.la $(DL_LIBS)
-ust_variant_CFLAGS = -Werror=old-style-definition $(AM_CFLAGS)
+++ /dev/null
-/*
- * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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; version 2.1 of
- * the License.
- *
- * 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
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/* Internal UST API: ust-variant.h */
-#include <lttng/ust-variant.h>
-#include <lttng/ust-events.h>
-#include <helper.h>
-
-#define NR_ENTRIES 5
-
-static const struct lttng_enum_entry myentries[NR_ENTRIES] = {
- [0] = {
- .start = 0,
- .end = 0,
- .string = "_mystring",
- },
- [1] = {
- .start = 1,
- .end = 1,
- .string = "_myint32",
- },
- [2] = {
- .start = 2,
- .end = 2,
- .string = "_myuint16",
- },
- [3] = {
- .start = 3,
- .end = 3,
- .string = "_mychar",
- },
- [4] = {
- .start = 4,
- .end = 4,
- .string = "_mylonglong",
- },
-};
-
-static const struct lttng_enum_desc myenum_desc = {
- .name = "myenum",
- .entries = myentries,
- .nr_entries = LTTNG_ARRAY_SIZE(myentries),
-};
-
-const struct lttng_event_field myvarfields[NR_ENTRIES] = {
- [0] = {
- .name = "mystring",
- .type = {
- .atype = atype_string,
- .u.basic.string.encoding = lttng_encode_UTF8,
- },
- .nowrite = 0,
- },
- [1] = {
- .name = "myint32",
- .type = __type_integer(int32_t, BYTE_ORDER, 10, none),
- .nowrite = 0,
- },
- [2] = {
- .name = "myuint16",
- .type = __type_integer(uint16_t, BYTE_ORDER, 10, none),
- .nowrite = 0,
- },
- [3] = {
- .name = "mychar",
- .type = __type_integer(char, BYTE_ORDER, 10, none),
- .nowrite = 0,
- },
- [4] = {
- .name = "mylonglong",
- .type = __type_integer(long long, BYTE_ORDER, 10, none),
- .nowrite = 0,
- },
-};
-
-static const struct lttng_event_field *get_field(const struct lttng_ust_type_variant *variant,
- int64_t value)
-{
- if (value >= NR_ENTRIES || value < 0)
- return NULL;
- return &myvarfields[value];
-}
-
-static int get_choices(const struct lttng_ust_type_variant *variant,
- size_t *nr_choices, const struct lttng_event_field **choices)
-{
- *nr_choices = NR_ENTRIES;
- *choices = myvarfields;
- return 0;
-}
-
-static const struct lttng_event_field myfields[];
-
-static const struct lttng_ust_type_variant myvariant = {
- .tag = &myfields[0],
- .get_field = get_field,
- .get_choices = get_choices,
- .free_priv = NULL,
- .priv = NULL,
-};
-
-/* dummy event */
-
-static void __event_probe__myprobe___myevent(void * __tp_data)
-{
-}
-
-static const struct lttng_event_field myfields[] = {
- [0] = {
- .name = "mytag",
- .type.atype = atype_enum_nestable,
- .type.u.enum_nestable.desc = &myenum_desc,
- .type.u.enum_nestable.container_type =
- __LTTNG_COMPOUND_LITERAL(struct lttng_type,
- __type_integer(char, BYTE_ORDER, 10, none)),
- .nowrite = 0,
- },
- [1] = {
- .name = "myfield",
- .type = {
- .atype = atype_variant_nestable,
- .u.variant_nestable = &myvariant,
- },
- .nowrite = 0,
- },
-};
-
-static const struct lttng_event_desc myevent_desc = {
- .name = "myprobe:myevent",
- .probe_callback = (void (*)(void)) &__event_probe__myprobe___myevent,
- .ctx = NULL,
- .fields = myfields,
- .nr_fields = LTTNG_ARRAY_SIZE(myfields),
- .loglevel = NULL,
- .signature = "mysig",
- .u = {
- .ext = {
- .model_emf_uri = NULL,
- },
- },
-};
-
-static const struct lttng_event_desc *event_desc_array[] = {
- [0] = &myevent_desc,
-};
-
-/* Dummy probe. */
-
-static struct lttng_probe_desc __probe_desc___myprobe = {
- .provider = "myprobe",
- .event_desc = event_desc_array,
- .nr_events = LTTNG_ARRAY_SIZE(event_desc_array),
- .head = { NULL, NULL },
- .lazy_init_head = { NULL, NULL },
- .lazy = 0,
- .major = LTTNG_UST_PROVIDER_MAJOR,
- .minor = LTTNG_UST_PROVIDER_MINOR,
-};
-
-int main(int argc, char **argv)
-{
- int ret;
-
- ret = lttng_probe_register(&__probe_desc___myprobe);
- if (ret)
- abort();
- sleep(5);
- lttng_probe_unregister(&__probe_desc___myprobe);
-
- return 0;
-}