X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=c0a7311fa66e7797c62c8a207a429e28ad190dcf;hb=6ba6fd60507f8e045bdc4f1be14e9d99c6a15f7f;hp=3847c9767d97d9d7e99f8ecf98208877f17ac917;hpb=cefef7a70a723c31ab6a0746c7611f145337dabe;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 3847c976..c0a7311f 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -1,26 +1,11 @@ /* - * lttng-ust-comm.c + * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (C) 2011 David Goulet * Copyright (C) 2011 Mathieu Desnoyers - * - * 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 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 */ #define _LGPL_SOURCE -#define _GNU_SOURCE #include #include #include @@ -40,19 +25,24 @@ #include #include #include -#include +#include "futex.h" #include +#include +#include #include #include -#include +#include #include #include +#include +#include +#include #include #include #include #include -#include +#include #include "tracepoint-internal.h" #include "lttng-tracer-core.h" #include "compat.h" @@ -61,9 +51,11 @@ #include "clock.h" #include "../libringbuffer/getcpu.h" #include "getenv.h" - -/* Concatenate lttng ust shared library name with its major version number. */ -#define LTTNG_UST_LIB_SO_NAME "liblttng-ust.so." __ust_stringify(CONFIG_LTTNG_UST_LIBRARY_VERSION_MAJOR) +#include "ust-events-internal.h" +#include "context-internal.h" +#include "ust-compat.h" +#include "lttng-counter-client.h" +#include "lttng-rb-clients.h" /* * Has lttng ust comm constructor been called ? @@ -266,7 +258,7 @@ struct sock_info { int statedump_pending; int initial_statedump_done; /* Keep procname for statedump */ - char procname[LTTNG_UST_PROCNAME_LEN]; + char procname[LTTNG_UST_ABI_PROCNAME_LEN]; }; /* Socket from app (connect) to session daemon (listen) for communication */ @@ -311,55 +303,56 @@ struct sock_info local_apps = { static int wait_poll_fallback; static const char *cmd_name_mapping[] = { - [ LTTNG_UST_RELEASE ] = "Release", - [ LTTNG_UST_SESSION ] = "Create Session", - [ LTTNG_UST_TRACER_VERSION ] = "Get Tracer Version", + [ LTTNG_UST_ABI_RELEASE ] = "Release", + [ LTTNG_UST_ABI_SESSION ] = "Create Session", + [ LTTNG_UST_ABI_TRACER_VERSION ] = "Get Tracer Version", - [ LTTNG_UST_TRACEPOINT_LIST ] = "Create Tracepoint List", - [ LTTNG_UST_WAIT_QUIESCENT ] = "Wait for Quiescent State", - [ LTTNG_UST_REGISTER_DONE ] = "Registration Done", - [ LTTNG_UST_TRACEPOINT_FIELD_LIST ] = "Create Tracepoint Field List", + [ LTTNG_UST_ABI_TRACEPOINT_LIST ] = "Create Tracepoint List", + [ LTTNG_UST_ABI_WAIT_QUIESCENT ] = "Wait for Quiescent State", + [ LTTNG_UST_ABI_REGISTER_DONE ] = "Registration Done", + [ LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST ] = "Create Tracepoint Field List", + + [ LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE ] = "Create event notifier group", /* Session FD commands */ - [ LTTNG_UST_CHANNEL ] = "Create Channel", - [ LTTNG_UST_SESSION_START ] = "Start Session", - [ LTTNG_UST_SESSION_STOP ] = "Stop Session", + [ LTTNG_UST_ABI_CHANNEL ] = "Create Channel", + [ LTTNG_UST_ABI_SESSION_START ] = "Start Session", + [ LTTNG_UST_ABI_SESSION_STOP ] = "Stop Session", /* Channel FD commands */ - [ LTTNG_UST_STREAM ] = "Create Stream", - [ LTTNG_UST_EVENT ] = "Create Event", + [ LTTNG_UST_ABI_STREAM ] = "Create Stream", + [ LTTNG_UST_ABI_EVENT ] = "Create Event", /* Event and Channel FD commands */ - [ LTTNG_UST_CONTEXT ] = "Create Context", - [ LTTNG_UST_FLUSH_BUFFER ] = "Flush Buffer", + [ LTTNG_UST_ABI_CONTEXT ] = "Create Context", + [ LTTNG_UST_ABI_FLUSH_BUFFER ] = "Flush Buffer", /* Event, Channel and Session commands */ - [ LTTNG_UST_ENABLE ] = "Enable", - [ LTTNG_UST_DISABLE ] = "Disable", + [ LTTNG_UST_ABI_ENABLE ] = "Enable", + [ LTTNG_UST_ABI_DISABLE ] = "Disable", /* Tracepoint list commands */ - [ LTTNG_UST_TRACEPOINT_LIST_GET ] = "List Next Tracepoint", - [ LTTNG_UST_TRACEPOINT_FIELD_LIST_GET ] = "List Next Tracepoint Field", + [ LTTNG_UST_ABI_TRACEPOINT_LIST_GET ] = "List Next Tracepoint", + [ LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET ] = "List Next Tracepoint Field", /* Event FD commands */ - [ LTTNG_UST_FILTER ] = "Create Filter", - [ LTTNG_UST_EXCLUSION ] = "Add exclusions to event", + [ LTTNG_UST_ABI_FILTER ] = "Create Filter", + [ LTTNG_UST_ABI_EXCLUSION ] = "Add exclusions to event", + + /* Event notifier group commands */ + [ LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE ] = "Create event notifier", + + /* Session and event notifier group commands */ + [ LTTNG_UST_ABI_COUNTER ] = "Create Counter", + + /* Counter commands */ + [ LTTNG_UST_ABI_COUNTER_GLOBAL ] = "Create Counter Global", + [ LTTNG_UST_ABI_COUNTER_CPU ] = "Create Counter CPU", }; static const char *str_timeout; static int got_timeout_env; -extern void lttng_ring_buffer_client_overwrite_init(void); -extern void lttng_ring_buffer_client_overwrite_rt_init(void); -extern void lttng_ring_buffer_client_discard_init(void); -extern void lttng_ring_buffer_client_discard_rt_init(void); -extern void lttng_ring_buffer_metadata_client_init(void); -extern void lttng_ring_buffer_client_overwrite_exit(void); -extern void lttng_ring_buffer_client_overwrite_rt_exit(void); -extern void lttng_ring_buffer_client_discard_exit(void); -extern void lttng_ring_buffer_client_discard_rt_exit(void); -extern void lttng_ring_buffer_metadata_client_exit(void); - static char *get_map_shm(struct sock_info *sock_info); ssize_t lttng_ust_read(int fd, void *buf, size_t len) @@ -389,11 +382,11 @@ const char *get_lttng_home_dir(void) { const char *val; - val = (const char *) lttng_getenv("LTTNG_HOME"); + val = (const char *) lttng_ust_getenv("LTTNG_HOME"); if (val != NULL) { return val; } - return (const char *) lttng_getenv("HOME"); + return (const char *) lttng_ust_getenv("HOME"); } /* @@ -412,18 +405,17 @@ void lttng_fixup_ust_mutex_nest_tls(void) } /* - * Fixup urcu bp TLS. + * Fixup lttng-ust urcu TLS. */ static -void lttng_fixup_urcu_bp_tls(void) +void lttng_fixup_lttng_ust_urcu_tls(void) { - rcu_read_lock(); - rcu_read_unlock(); + (void) lttng_ust_urcu_read_ongoing(); } void lttng_ust_fixup_tls(void) { - lttng_fixup_urcu_bp_tls(); + lttng_fixup_lttng_ust_urcu_tls(); lttng_fixup_ringbuffer_tls(); lttng_fixup_vtid_tls(); lttng_fixup_nest_count_tls(); @@ -436,6 +428,31 @@ void lttng_ust_fixup_tls(void) lttng_fixup_net_ns_tls(); lttng_fixup_time_ns_tls(); lttng_fixup_uts_ns_tls(); + lttng_ust_fixup_ring_buffer_client_discard_tls(); + lttng_ust_fixup_ring_buffer_client_discard_rt_tls(); + lttng_ust_fixup_ring_buffer_client_overwrite_tls(); + lttng_ust_fixup_ring_buffer_client_overwrite_rt_tls(); +} + +/* + * LTTng-UST uses Global Dynamic model TLS variables rather than IE + * model because many versions of glibc don't preallocate a pool large + * enough for TLS variables IE model defined in other shared libraries, + * and causes issues when using LTTng-UST for Java tracing. + * + * Because of this use of Global Dynamic TLS variables, users wishing to + * trace from signal handlers need to explicitly trigger the lazy + * allocation of those variables for each thread before using them. + * This can be triggered by calling lttng_ust_init_thread(). + */ +void lttng_ust_init_thread(void) +{ + /* + * Because those TLS variables are global dynamic, we need to + * ensure those are initialized before a signal handler nesting over + * this thread attempts to use them. + */ + lttng_ust_fixup_tls(); } int lttng_get_notify_socket(void *owner) @@ -446,7 +463,6 @@ int lttng_get_notify_socket(void *owner) } -LTTNG_HIDDEN char* lttng_ust_sockinfo_get_procname(void *owner) { struct sock_info *info = owner; @@ -483,7 +499,7 @@ int setup_global_apps(void) } global_apps.allowed = 1; - lttng_ust_getprocname(global_apps.procname); + lttng_pthread_getname_np(global_apps.procname, LTTNG_UST_ABI_PROCNAME_LEN); error: return ret; } @@ -529,7 +545,7 @@ int setup_local_apps(void) goto end; } - lttng_ust_getprocname(local_apps.procname); + lttng_pthread_getname_np(local_apps.procname, LTTNG_UST_ABI_PROCNAME_LEN); end: return ret; } @@ -544,7 +560,7 @@ long get_timeout(void) long constructor_delay_ms = LTTNG_UST_DEFAULT_CONSTRUCTOR_TIMEOUT_MS; if (!got_timeout_env) { - str_timeout = lttng_getenv("LTTNG_UST_REGISTER_TIMEOUT"); + str_timeout = lttng_ust_getenv("LTTNG_UST_REGISTER_TIMEOUT"); got_timeout_env = 1; } if (str_timeout) @@ -611,7 +627,7 @@ static void get_allow_blocking(void) { const char *str_allow_blocking = - lttng_getenv("LTTNG_UST_ALLOW_BLOCKING"); + lttng_ust_getenv("LTTNG_UST_ALLOW_BLOCKING"); if (str_allow_blocking) { DBG("%s environment variable is set", @@ -626,11 +642,11 @@ int register_to_sessiond(int socket, enum ustctl_socket_type type) return ustcomm_send_reg_msg(socket, type, CAA_BITS_PER_LONG, - lttng_alignof(uint8_t) * CHAR_BIT, - lttng_alignof(uint16_t) * CHAR_BIT, - lttng_alignof(uint32_t) * CHAR_BIT, - lttng_alignof(uint64_t) * CHAR_BIT, - lttng_alignof(unsigned long) * CHAR_BIT); + lttng_ust_rb_alignof(uint8_t) * CHAR_BIT, + lttng_ust_rb_alignof(uint16_t) * CHAR_BIT, + lttng_ust_rb_alignof(uint32_t) * CHAR_BIT, + lttng_ust_rb_alignof(uint64_t) * CHAR_BIT, + lttng_ust_rb_alignof(unsigned long) * CHAR_BIT); } static @@ -738,15 +754,132 @@ void handle_pending_statedump(struct sock_info *sock_info) } } +static inline +const char *bytecode_type_str(uint32_t cmd) +{ + switch (cmd) { + case LTTNG_UST_ABI_CAPTURE: + return "capture"; + case LTTNG_UST_ABI_FILTER: + return "filter"; + default: + abort(); + } +} + +static +int handle_bytecode_recv(struct sock_info *sock_info, + int sock, struct ustcomm_ust_msg *lum) +{ + struct lttng_ust_bytecode_node *bytecode = NULL; + enum lttng_ust_bytecode_type type; + const struct lttng_ust_abi_objd_ops *ops; + uint32_t data_size, data_size_max, reloc_offset; + uint64_t seqnum; + ssize_t len; + int ret = 0; + + switch (lum->cmd) { + case LTTNG_UST_ABI_FILTER: + type = LTTNG_UST_BYTECODE_TYPE_FILTER; + data_size = lum->u.filter.data_size; + data_size_max = LTTNG_UST_ABI_FILTER_BYTECODE_MAX_LEN; + reloc_offset = lum->u.filter.reloc_offset; + seqnum = lum->u.filter.seqnum; + break; + case LTTNG_UST_ABI_CAPTURE: + type = LTTNG_UST_BYTECODE_TYPE_CAPTURE; + data_size = lum->u.capture.data_size; + data_size_max = LTTNG_UST_ABI_CAPTURE_BYTECODE_MAX_LEN; + reloc_offset = lum->u.capture.reloc_offset; + seqnum = lum->u.capture.seqnum; + break; + default: + abort(); + } + + if (data_size > data_size_max) { + ERR("Bytecode %s data size is too large: %u bytes", + bytecode_type_str(lum->cmd), data_size); + ret = -EINVAL; + goto end; + } + + if (reloc_offset > data_size) { + ERR("Bytecode %s reloc offset %u is not within data", + bytecode_type_str(lum->cmd), reloc_offset); + ret = -EINVAL; + goto end; + } + + /* Allocate the structure AND the `data[]` field. */ + bytecode = zmalloc(sizeof(*bytecode) + data_size); + if (!bytecode) { + ret = -ENOMEM; + goto end; + } + + bytecode->bc.len = data_size; + bytecode->bc.reloc_offset = reloc_offset; + bytecode->bc.seqnum = seqnum; + bytecode->type = type; + + len = ustcomm_recv_unix_sock(sock, bytecode->bc.data, bytecode->bc.len); + switch (len) { + case 0: /* orderly shutdown */ + ret = 0; + goto end; + default: + if (len == bytecode->bc.len) { + DBG("Bytecode %s data received", + bytecode_type_str(lum->cmd)); + break; + } else if (len < 0) { + DBG("Receive failed from lttng-sessiond with errno %d", + (int) -len); + if (len == -ECONNRESET) { + ERR("%s remote end closed connection", + sock_info->name); + ret = len; + goto end; + } + ret = len; + goto end; + } else { + DBG("Incorrect %s bytecode data message size: %zd", + bytecode_type_str(lum->cmd), len); + ret = -EINVAL; + goto end; + } + } + + ops = lttng_ust_abi_objd_ops(lum->handle); + if (!ops) { + ret = -ENOENT; + goto end; + } + + if (ops->cmd) + ret = ops->cmd(lum->handle, lum->cmd, + (unsigned long) &bytecode, + NULL, sock_info); + else + ret = -ENOSYS; + +end: + free(bytecode); + return ret; +} + static int handle_message(struct sock_info *sock_info, int sock, struct ustcomm_ust_msg *lum) { int ret = 0; - const struct lttng_ust_objd_ops *ops; + const struct lttng_ust_abi_objd_ops *ops; struct ustcomm_ust_reply lur; - union ust_args args; - char ctxstr[LTTNG_UST_SYM_NAME_LEN]; /* App context string. */ + union lttng_ust_abi_args args; + char ctxstr[LTTNG_UST_ABI_SYM_NAME_LEN]; /* App context string. */ ssize_t len; memset(&lur, 0, sizeof(lur)); @@ -756,158 +889,137 @@ int handle_message(struct sock_info *sock_info, goto error; } - ops = objd_ops(lum->handle); + ops = lttng_ust_abi_objd_ops(lum->handle); if (!ops) { ret = -ENOENT; goto error; } switch (lum->cmd) { - case LTTNG_UST_REGISTER_DONE: - if (lum->handle == LTTNG_UST_ROOT_HANDLE) + case LTTNG_UST_ABI_REGISTER_DONE: + if (lum->handle == LTTNG_UST_ABI_ROOT_HANDLE) ret = handle_register_done(sock_info); else ret = -EINVAL; break; - case LTTNG_UST_RELEASE: - if (lum->handle == LTTNG_UST_ROOT_HANDLE) + case LTTNG_UST_ABI_RELEASE: + if (lum->handle == LTTNG_UST_ABI_ROOT_HANDLE) ret = -EPERM; else - ret = lttng_ust_objd_unref(lum->handle, 1); + ret = lttng_ust_abi_objd_unref(lum->handle, 1); break; - case LTTNG_UST_FILTER: - { - /* Receive filter data */ - struct lttng_ust_filter_bytecode_node *bytecode; - - if (lum->u.filter.data_size > FILTER_BYTECODE_MAX_LEN) { - ERR("Filter data size is too large: %u bytes", - lum->u.filter.data_size); - ret = -EINVAL; + case LTTNG_UST_ABI_CAPTURE: + case LTTNG_UST_ABI_FILTER: + ret = handle_bytecode_recv(sock_info, sock, lum); + if (ret) goto error; - } + break; + case LTTNG_UST_ABI_EXCLUSION: + { + /* Receive exclusion names */ + struct lttng_ust_excluder_node *node; + unsigned int count; - if (lum->u.filter.reloc_offset > lum->u.filter.data_size) { - ERR("Filter reloc offset %u is not within data", - lum->u.filter.reloc_offset); - ret = -EINVAL; + count = lum->u.exclusion.count; + if (count == 0) { + /* There are no names to read */ + ret = 0; goto error; } - - bytecode = zmalloc(sizeof(*bytecode) + lum->u.filter.data_size); - if (!bytecode) { + node = zmalloc(sizeof(*node) + + count * LTTNG_UST_ABI_SYM_NAME_LEN); + if (!node) { ret = -ENOMEM; goto error; } - len = ustcomm_recv_unix_sock(sock, bytecode->bc.data, - lum->u.filter.data_size); + node->excluder.count = count; + len = ustcomm_recv_unix_sock(sock, node->excluder.names, + count * LTTNG_UST_ABI_SYM_NAME_LEN); switch (len) { case 0: /* orderly shutdown */ ret = 0; - free(bytecode); + free(node); goto error; default: - if (len == lum->u.filter.data_size) { - DBG("filter data received"); + if (len == count * LTTNG_UST_ABI_SYM_NAME_LEN) { + DBG("Exclusion data received"); break; } else if (len < 0) { DBG("Receive failed from lttng-sessiond with errno %d", (int) -len); if (len == -ECONNRESET) { ERR("%s remote end closed connection", sock_info->name); ret = len; - free(bytecode); + free(node); goto error; } ret = len; - free(bytecode); + free(node); goto error; } else { - DBG("incorrect filter data message size: %zd", len); + DBG("Incorrect exclusion data message size: %zd", len); ret = -EINVAL; - free(bytecode); + free(node); goto error; } } - bytecode->bc.len = lum->u.filter.data_size; - bytecode->bc.reloc_offset = lum->u.filter.reloc_offset; - bytecode->bc.seqnum = lum->u.filter.seqnum; - if (ops->cmd) { + if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) bytecode, + (unsigned long) &node, &args, sock_info); - if (ret) { - free(bytecode); - } - /* don't free bytecode if everything went fine. */ - } else { + else ret = -ENOSYS; - free(bytecode); - } + free(node); break; } - case LTTNG_UST_EXCLUSION: + case LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE: { - /* Receive exclusion names */ - struct lttng_ust_excluder_node *node; - unsigned int count; + int event_notifier_notif_fd, close_ret; - count = lum->u.exclusion.count; - if (count == 0) { - /* There are no names to read */ - ret = 0; - goto error; - } - node = zmalloc(sizeof(*node) + - count * LTTNG_UST_SYM_NAME_LEN); - if (!node) { - ret = -ENOMEM; - goto error; - } - node->excluder.count = count; - len = ustcomm_recv_unix_sock(sock, node->excluder.names, - count * LTTNG_UST_SYM_NAME_LEN); + len = ustcomm_recv_event_notifier_notif_fd_from_sessiond(sock, + &event_notifier_notif_fd); switch (len) { case 0: /* orderly shutdown */ ret = 0; - free(node); goto error; + case 1: + break; default: - if (len == count * LTTNG_UST_SYM_NAME_LEN) { - DBG("Exclusion data received"); - break; - } else if (len < 0) { - DBG("Receive failed from lttng-sessiond with errno %d", (int) -len); + if (len < 0) { + DBG("Receive failed from lttng-sessiond with errno %d", + (int) -len); if (len == -ECONNRESET) { - ERR("%s remote end closed connection", sock_info->name); + ERR("%s remote end closed connection", + sock_info->name); ret = len; - free(node); goto error; } ret = len; - free(node); goto error; } else { - DBG("Incorrect exclusion data message size: %zd", len); + DBG("Incorrect event notifier fd message size: %zd", + len); ret = -EINVAL; - free(node); goto error; } } - if (ops->cmd) { + args.event_notifier_handle.event_notifier_notif_fd = + event_notifier_notif_fd; + if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) node, + (unsigned long) &lum->u, &args, sock_info); - if (ret) { - free(node); - } - /* Don't free exclusion data if everything went fine. */ - } else { + else ret = -ENOSYS; - free(node); + if (args.event_notifier_handle.event_notifier_notif_fd >= 0) { + lttng_ust_lock_fd_tracker(); + close_ret = close(args.event_notifier_handle.event_notifier_notif_fd); + lttng_ust_unlock_fd_tracker(); + if (close_ret) + PERROR("close"); } break; } - case LTTNG_UST_CHANNEL: + case LTTNG_UST_ABI_CHANNEL: { void *chan_data; int wakeup_fd; @@ -946,10 +1058,23 @@ int handle_message(struct sock_info *sock_info, &args, sock_info); else ret = -ENOSYS; + if (args.channel.wakeup_fd >= 0) { + int close_ret; + + lttng_ust_lock_fd_tracker(); + close_ret = close(args.channel.wakeup_fd); + lttng_ust_unlock_fd_tracker(); + args.channel.wakeup_fd = -1; + if (close_ret) + PERROR("close"); + } + free(args.channel.chan_data); break; } - case LTTNG_UST_STREAM: + case LTTNG_UST_ABI_STREAM: { + int close_ret; + /* Receive shm_fd, wakeup_fd */ ret = ustcomm_recv_stream_from_sessiond(sock, NULL, @@ -965,18 +1090,34 @@ int handle_message(struct sock_info *sock_info, &args, sock_info); else ret = -ENOSYS; + if (args.stream.shm_fd >= 0) { + lttng_ust_lock_fd_tracker(); + close_ret = close(args.stream.shm_fd); + lttng_ust_unlock_fd_tracker(); + args.stream.shm_fd = -1; + if (close_ret) + PERROR("close"); + } + if (args.stream.wakeup_fd >= 0) { + lttng_ust_lock_fd_tracker(); + close_ret = close(args.stream.wakeup_fd); + lttng_ust_unlock_fd_tracker(); + args.stream.wakeup_fd = -1; + if (close_ret) + PERROR("close"); + } break; } - case LTTNG_UST_CONTEXT: + case LTTNG_UST_ABI_CONTEXT: switch (lum->u.context.ctx) { - case LTTNG_UST_CONTEXT_APP_CONTEXT: + case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT: { char *p; size_t ctxlen, recvlen; ctxlen = strlen("$app.") + lum->u.context.u.app_ctx.provider_name_len - 1 + strlen(":") + lum->u.context.u.app_ctx.ctx_name_len; - if (ctxlen >= LTTNG_UST_SYM_NAME_LEN) { + if (ctxlen >= LTTNG_UST_ABI_SYM_NAME_LEN) { ERR("Application context string length size is too large: %zu bytes", ctxlen); ret = -EINVAL; @@ -1025,6 +1166,142 @@ int handle_message(struct sock_info *sock_info, ret = -ENOSYS; } break; + case LTTNG_UST_ABI_COUNTER: + { + void *counter_data; + + len = ustcomm_recv_counter_from_sessiond(sock, + &counter_data, lum->u.counter.len); + switch (len) { + case 0: /* orderly shutdown */ + ret = 0; + goto error; + default: + if (len == lum->u.counter.len) { + DBG("counter data received"); + break; + } else if (len < 0) { + DBG("Receive failed from lttng-sessiond with errno %d", (int) -len); + if (len == -ECONNRESET) { + ERR("%s remote end closed connection", sock_info->name); + ret = len; + goto error; + } + ret = len; + goto error; + } else { + DBG("incorrect counter data message size: %zd", len); + ret = -EINVAL; + goto error; + } + } + args.counter.counter_data = counter_data; + if (ops->cmd) + ret = ops->cmd(lum->handle, lum->cmd, + (unsigned long) &lum->u, + &args, sock_info); + else + ret = -ENOSYS; + free(args.counter.counter_data); + break; + } + case LTTNG_UST_ABI_COUNTER_GLOBAL: + { + /* Receive shm_fd */ + ret = ustcomm_recv_counter_shm_from_sessiond(sock, + &args.counter_shm.shm_fd); + if (ret) { + goto error; + } + + if (ops->cmd) + ret = ops->cmd(lum->handle, lum->cmd, + (unsigned long) &lum->u, + &args, sock_info); + else + ret = -ENOSYS; + if (args.counter_shm.shm_fd >= 0) { + int close_ret; + + lttng_ust_lock_fd_tracker(); + close_ret = close(args.counter_shm.shm_fd); + lttng_ust_unlock_fd_tracker(); + args.counter_shm.shm_fd = -1; + if (close_ret) + PERROR("close"); + } + break; + } + case LTTNG_UST_ABI_COUNTER_CPU: + { + /* Receive shm_fd */ + ret = ustcomm_recv_counter_shm_from_sessiond(sock, + &args.counter_shm.shm_fd); + if (ret) { + goto error; + } + + if (ops->cmd) + ret = ops->cmd(lum->handle, lum->cmd, + (unsigned long) &lum->u, + &args, sock_info); + else + ret = -ENOSYS; + if (args.counter_shm.shm_fd >= 0) { + int close_ret; + + lttng_ust_lock_fd_tracker(); + close_ret = close(args.counter_shm.shm_fd); + lttng_ust_unlock_fd_tracker(); + args.counter_shm.shm_fd = -1; + if (close_ret) + PERROR("close"); + } + break; + } + case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE: + { + /* Receive struct lttng_ust_event_notifier */ + struct lttng_ust_abi_event_notifier event_notifier; + + if (sizeof(event_notifier) != lum->u.event_notifier.len) { + DBG("incorrect event notifier data message size: %u", lum->u.event_notifier.len); + ret = -EINVAL; + goto error; + } + len = ustcomm_recv_unix_sock(sock, &event_notifier, sizeof(event_notifier)); + switch (len) { + case 0: /* orderly shutdown */ + ret = 0; + goto error; + default: + if (len == sizeof(event_notifier)) { + DBG("event notifier data received"); + break; + } else if (len < 0) { + DBG("Receive failed from lttng-sessiond with errno %d", (int) -len); + if (len == -ECONNRESET) { + ERR("%s remote end closed connection", sock_info->name); + ret = len; + goto error; + } + ret = len; + goto error; + } else { + DBG("incorrect event notifier data message size: %zd", len); + ret = -EINVAL; + goto error; + } + } + if (ops->cmd) + ret = ops->cmd(lum->handle, lum->cmd, + (unsigned long) &event_notifier, + &args, sock_info); + else + ret = -ENOSYS; + break; + } + default: if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, @@ -1075,10 +1352,10 @@ int handle_message(struct sock_info *sock_info, } if (ret >= 0) { switch (lum->cmd) { - case LTTNG_UST_TRACER_VERSION: + case LTTNG_UST_ABI_TRACER_VERSION: lur.u.version = lum->u.version; break; - case LTTNG_UST_TRACEPOINT_LIST_GET: + case LTTNG_UST_ABI_TRACEPOINT_LIST_GET: memcpy(&lur.u.tracepoint, &lum->u.tracepoint, sizeof(lur.u.tracepoint)); break; } @@ -1111,7 +1388,7 @@ int handle_message(struct sock_info *sock_info, */ if (lur.ret_code == LTTNG_UST_OK) { switch (lum->cmd) { - case LTTNG_UST_TRACEPOINT_FIELD_LIST_GET: + case LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET: len = ustcomm_send_unix_sock(sock, &args.field_list.entry, sizeof(args.field_list.entry)); @@ -1138,7 +1415,7 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) int ret; if (sock_info->root_handle != -1) { - ret = lttng_ust_objd_unref(sock_info->root_handle, 1); + ret = lttng_ust_abi_objd_unref(sock_info->root_handle, 1); if (ret) { ERR("Error unref root handle"); } @@ -1174,7 +1451,7 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) if (sock_info->wait_shm_mmap) { long page_size; - page_size = sysconf(_SC_PAGE_SIZE); + page_size = LTTNG_UST_PAGE_SIZE; if (page_size <= 0) { if (!page_size) { errno = EINVAL; @@ -1432,7 +1709,7 @@ void wait_for_sessiond(struct sock_info *sock_info) if (uatomic_read((int32_t *) sock_info->wait_shm_mmap)) goto end_wait; - while (futex_async((int32_t *) sock_info->wait_shm_mmap, + while (lttng_ust_futex_async((int32_t *) sock_info->wait_shm_mmap, FUTEX_WAIT, 0, NULL, NULL, 0)) { switch (errno) { case EWOULDBLOCK: @@ -1449,7 +1726,7 @@ void wait_for_sessiond(struct sock_info *sock_info) "Please upgrade your kernel " "(fix is commit 9ea71503a8ed9184d2d0b8ccc4d269d05f7940ae in Linux kernel " "mainline). LTTng-UST will use polling mode fallback."); - if (ust_debug()) + if (ust_err_debug_enabled()) PERROR("futex"); goto end_wait; } @@ -1766,7 +2043,7 @@ end: goto quit; } /* Cleanup socket handles before trying to reconnect */ - lttng_ust_objd_table_owner_cleanup(sock_info); + lttng_ust_abi_objd_table_owner_cleanup(sock_info); ust_unlock(); goto restart; /* try to reconnect */ @@ -1783,7 +2060,7 @@ quit: * Weak symbol to call when the ust malloc wrapper is not loaded. */ __attribute__((weak)) -void lttng_ust_malloc_wrapper_init(void) +void lttng_ust_libc_wrapper_malloc_init(void) { } @@ -1791,7 +2068,11 @@ void lttng_ust_malloc_wrapper_init(void) * sessiond monitoring thread: monitor presence of global and per-user * sessiond by polling the application common named pipe. */ -void __attribute__((constructor)) lttng_ust_init(void) +static +void lttng_ust_init(void) + __attribute__((constructor)); +static +void lttng_ust_init(void) { struct timespec constructor_timeout; sigset_t sig_all_blocked, orig_parent_mask; @@ -1819,7 +2100,7 @@ void __attribute__((constructor)) lttng_ust_init(void) * liblttng-ust.so to increment the dynamic loader's internal refcount for * this library so it never becomes zero, thus never gets unloaded from the * address space of the process. Since we are already running in the - * constructor of the LTTNG_UST_LIB_SO_NAME library, calling dlopen will + * constructor of the LTTNG_UST_LIB_SONAME library, calling dlopen will * simply increment the refcount and no additionnal work is needed by the * dynamic loader as the shared library is already loaded in the address * space. As a safe guard, we use the RTLD_NODELETE flag to prevent @@ -1827,9 +2108,9 @@ void __attribute__((constructor)) lttng_ust_init(void) * never happen). Do the return value check but discard the handle at the * end of the function as it's not needed. */ - handle = dlopen(LTTNG_UST_LIB_SO_NAME, RTLD_LAZY | RTLD_NODELETE); + handle = dlopen(LTTNG_UST_LIB_SONAME, RTLD_LAZY | RTLD_NODELETE); if (!handle) { - ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SO_NAME); + ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SONAME); } /* @@ -1838,23 +2119,20 @@ void __attribute__((constructor)) lttng_ust_init(void) * sessiond (otherwise leading to errors when trying to create * sessiond before the init functions are completed). */ - init_usterr(); - lttng_ust_getenv_init(); /* Needs init_usterr() to be completed. */ - init_tracepoint(); + ust_err_init(); + lttng_ust_getenv_init(); /* Needs ust_err_init() to be completed. */ + lttng_ust_tp_init(); lttng_ust_init_fd_tracker(); lttng_ust_clock_init(); lttng_ust_getcpu_init(); lttng_ust_statedump_init(); - lttng_ring_buffer_metadata_client_init(); - lttng_ring_buffer_client_overwrite_init(); - lttng_ring_buffer_client_overwrite_rt_init(); - lttng_ring_buffer_client_discard_init(); - lttng_ring_buffer_client_discard_rt_init(); + lttng_ust_ring_buffer_clients_init(); + lttng_ust_counter_clients_init(); lttng_perf_counter_init(); /* * Invoke ust malloc wrapper init before starting other threads. */ - lttng_ust_malloc_wrapper_init(); + lttng_ust_libc_wrapper_malloc_init(); timeout_mode = get_constructor_timeout(&constructor_timeout); @@ -1988,15 +2266,12 @@ void lttng_ust_cleanup(int exiting) * point. */ lttng_ust_abi_exit(); - lttng_ust_events_exit(); + lttng_ust_abi_events_exit(); lttng_perf_counter_exit(); - lttng_ring_buffer_client_discard_rt_exit(); - lttng_ring_buffer_client_discard_exit(); - lttng_ring_buffer_client_overwrite_rt_exit(); - lttng_ring_buffer_client_overwrite_exit(); - lttng_ring_buffer_metadata_client_exit(); + lttng_ust_ring_buffer_clients_exit(); + lttng_ust_counter_clients_exit(); lttng_ust_statedump_destroy(); - exit_tracepoint(); + lttng_ust_tp_exit(); if (!exiting) { /* Reinitialize values for fork */ sem_count = sem_count_initial_value; @@ -2005,7 +2280,11 @@ void lttng_ust_cleanup(int exiting) } } -void __attribute__((destructor)) lttng_ust_exit(void) +static +void lttng_ust_exit(void) + __attribute__((destructor)); +static +void lttng_ust_exit(void) { int ret; @@ -2093,7 +2372,7 @@ void ust_context_vgids_reset(void) * in the middle of an tracepoint or ust tracing state modification. * Holding this mutex protects these structures across fork and clone. */ -void ust_before_fork(sigset_t *save_sigset) +void lttng_ust_before_fork(sigset_t *save_sigset) { /* * Disable signals. This is to avoid that the child intervenes @@ -2119,7 +2398,7 @@ void ust_before_fork(sigset_t *save_sigset) pthread_mutex_lock(&ust_fork_mutex); ust_lock_nocheck(); - urcu_bp_before_fork(); + lttng_ust_urcu_before_fork(); lttng_ust_lock_fd_tracker(); lttng_perf_lock(); } @@ -2142,12 +2421,12 @@ static void ust_after_fork_common(sigset_t *restore_sigset) } } -void ust_after_fork_parent(sigset_t *restore_sigset) +void lttng_ust_after_fork_parent(sigset_t *restore_sigset) { if (URCU_TLS(lttng_ust_nest_count)) return; DBG("process %d", getpid()); - urcu_bp_after_fork_parent(); + lttng_ust_urcu_after_fork_parent(); /* Release mutexes and reenable signals */ ust_after_fork_common(restore_sigset); } @@ -2161,75 +2440,75 @@ void ust_after_fork_parent(sigset_t *restore_sigset) * This is meant for forks() that have tracing in the child between the * fork and following exec call (if there is any). */ -void ust_after_fork_child(sigset_t *restore_sigset) +void lttng_ust_after_fork_child(sigset_t *restore_sigset) { if (URCU_TLS(lttng_ust_nest_count)) return; lttng_context_vpid_reset(); lttng_context_vtid_reset(); - lttng_context_procname_reset(); + lttng_ust_context_procname_reset(); ust_context_ns_reset(); ust_context_vuids_reset(); ust_context_vgids_reset(); DBG("process %d", getpid()); /* Release urcu mutexes */ - urcu_bp_after_fork_child(); + lttng_ust_urcu_after_fork_child(); lttng_ust_cleanup(0); /* Release mutexes and reenable signals */ ust_after_fork_common(restore_sigset); lttng_ust_init(); } -void ust_after_setns(void) +void lttng_ust_after_setns(void) { ust_context_ns_reset(); ust_context_vuids_reset(); ust_context_vgids_reset(); } -void ust_after_unshare(void) +void lttng_ust_after_unshare(void) { ust_context_ns_reset(); ust_context_vuids_reset(); ust_context_vgids_reset(); } -void ust_after_setuid(void) +void lttng_ust_after_setuid(void) { ust_context_vuids_reset(); } -void ust_after_seteuid(void) +void lttng_ust_after_seteuid(void) { ust_context_vuids_reset(); } -void ust_after_setreuid(void) +void lttng_ust_after_setreuid(void) { ust_context_vuids_reset(); } -void ust_after_setresuid(void) +void lttng_ust_after_setresuid(void) { ust_context_vuids_reset(); } -void ust_after_setgid(void) +void lttng_ust_after_setgid(void) { ust_context_vgids_reset(); } -void ust_after_setegid(void) +void lttng_ust_after_setegid(void) { ust_context_vgids_reset(); } -void ust_after_setregid(void) +void lttng_ust_after_setregid(void) { ust_context_vgids_reset(); } -void ust_after_setresgid(void) +void lttng_ust_after_setresgid(void) { ust_context_vgids_reset(); }