X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=f45097b030116fc9a17958d74803adcdc8a8d867;hb=3167741775bf8edf1c6085a2ac79bb1ed4a3f401;hp=5a2aacdf32d6513348465bdedf0cbfc398b372be;hpb=735bef4705cc42f25d26f25be09ba98f1efb8511;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 5a2aacdf..f45097b0 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -20,7 +20,8 @@ */ #define _LGPL_SOURCE -#define _GNU_SOURCE +#include +#include #include #include #include @@ -38,9 +39,11 @@ #include #include #include -#include +#include "futex.h" #include +#include +#include #include #include #include @@ -59,6 +62,7 @@ #include "clock.h" #include "../libringbuffer/getcpu.h" #include "getenv.h" +#include "ust-events-internal.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) @@ -263,6 +267,8 @@ struct sock_info { /* Keep track of lazy state dump not performed yet. */ int statedump_pending; int initial_statedump_done; + /* Keep procname for statedump */ + char procname[LTTNG_UST_ABI_PROCNAME_LEN]; }; /* Socket from app (connect) to session daemon (listen) for communication */ @@ -283,6 +289,7 @@ struct sock_info global_apps = { .statedump_pending = 0, .initial_statedump_done = 0, + .procname[0] = '\0' }; /* TODO: allow global_apps_sock_path override */ @@ -300,6 +307,7 @@ struct sock_info local_apps = { .statedump_pending = 0, .initial_statedump_done = 0, + .procname[0] = '\0' }; static int wait_poll_fallback; @@ -314,6 +322,8 @@ static const char *cmd_name_mapping[] = { [ LTTNG_UST_REGISTER_DONE ] = "Registration Done", [ LTTNG_UST_TRACEPOINT_FIELD_LIST ] = "Create Tracepoint Field List", + [ LTTNG_UST_EVENT_NOTIFIER_GROUP_CREATE ] = "Create event notifier group", + /* Session FD commands */ [ LTTNG_UST_CHANNEL ] = "Create Channel", [ LTTNG_UST_SESSION_START ] = "Start Session", @@ -338,6 +348,16 @@ static const char *cmd_name_mapping[] = { /* Event FD commands */ [ LTTNG_UST_FILTER ] = "Create Filter", [ LTTNG_UST_EXCLUSION ] = "Add exclusions to event", + + /* Event notifier group commands */ + [ LTTNG_UST_EVENT_NOTIFIER_CREATE ] = "Create event notifier", + + /* Session and event notifier group commands */ + [ LTTNG_UST_COUNTER ] = "Create Counter", + + /* Counter commands */ + [ LTTNG_UST_COUNTER_GLOBAL ] = "Create Counter Global", + [ LTTNG_UST_COUNTER_CPU ] = "Create Counter CPU", }; static const char *str_timeout; @@ -353,6 +373,14 @@ 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); +LTTNG_HIDDEN +extern void lttng_counter_client_percpu_32_modular_init(void); +LTTNG_HIDDEN +extern void lttng_counter_client_percpu_32_modular_exit(void); +LTTNG_HIDDEN +extern void lttng_counter_client_percpu_64_modular_init(void); +LTTNG_HIDDEN +extern void lttng_counter_client_percpu_64_modular_exit(void); static char *get_map_shm(struct sock_info *sock_info); @@ -406,18 +434,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(); @@ -428,6 +455,7 @@ void lttng_ust_fixup_tls(void) lttng_fixup_cgroup_ns_tls(); lttng_fixup_ipc_ns_tls(); lttng_fixup_net_ns_tls(); + lttng_fixup_time_ns_tls(); lttng_fixup_uts_ns_tls(); } @@ -438,6 +466,15 @@ int lttng_get_notify_socket(void *owner) return info->notify_socket; } + +LTTNG_HIDDEN +char* lttng_ust_sockinfo_get_procname(void *owner) +{ + struct sock_info *info = owner; + + return info->procname; +} + static void print_cmd(int cmd, int handle) { @@ -467,6 +504,7 @@ int setup_global_apps(void) } global_apps.allowed = 1; + lttng_pthread_getname_np(global_apps.procname, LTTNG_UST_ABI_PROCNAME_LEN); error: return ret; } @@ -511,6 +549,8 @@ int setup_local_apps(void) ret = -EIO; goto end; } + + lttng_pthread_getname_np(local_apps.procname, LTTNG_UST_ABI_PROCNAME_LEN); end: return ret; } @@ -719,6 +759,123 @@ void handle_pending_statedump(struct sock_info *sock_info) } } +static inline +const char *bytecode_type_str(uint32_t cmd) +{ + switch (cmd) { + case LTTNG_UST_CAPTURE: + return "capture"; + case LTTNG_UST_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_node_type type; + const struct lttng_ust_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_FILTER: + type = LTTNG_UST_BYTECODE_NODE_TYPE_FILTER; + data_size = lum->u.filter.data_size; + data_size_max = FILTER_BYTECODE_MAX_LEN; + reloc_offset = lum->u.filter.reloc_offset; + seqnum = lum->u.filter.seqnum; + break; + case LTTNG_UST_CAPTURE: + type = LTTNG_UST_BYTECODE_NODE_TYPE_CAPTURE; + data_size = lum->u.capture.data_size; + data_size_max = 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 = 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) @@ -756,76 +913,12 @@ int handle_message(struct sock_info *sock_info, else ret = lttng_ust_objd_unref(lum->handle, 1); break; + case LTTNG_UST_CAPTURE: 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; + ret = handle_bytecode_recv(sock_info, sock, lum); + if (ret) goto error; - } - - 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; - goto error; - } - - bytecode = zmalloc(sizeof(*bytecode) + lum->u.filter.data_size); - if (!bytecode) { - ret = -ENOMEM; - goto error; - } - len = ustcomm_recv_unix_sock(sock, bytecode->bc.data, - lum->u.filter.data_size); - switch (len) { - case 0: /* orderly shutdown */ - ret = 0; - free(bytecode); - goto error; - default: - if (len == lum->u.filter.data_size) { - DBG("filter 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); - goto error; - } - ret = len; - free(bytecode); - goto error; - } else { - DBG("incorrect filter data message size: %zd", len); - ret = -EINVAL; - free(bytecode); - 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) { - ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) bytecode, - &args, sock_info); - if (ret) { - free(bytecode); - } - /* don't free bytecode if everything went fine. */ - } else { - ret = -ENOSYS; - free(bytecode); - } break; - } case LTTNG_UST_EXCLUSION: { /* Receive exclusion names */ @@ -874,17 +967,60 @@ int handle_message(struct sock_info *sock_info, goto error; } } - if (ops->cmd) { + if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) node, + (unsigned long) &node, &args, sock_info); - if (ret) { - free(node); + else + ret = -ENOSYS; + free(node); + break; + } + case LTTNG_UST_EVENT_NOTIFIER_GROUP_CREATE: + { + int event_notifier_notif_fd, close_ret; + + len = ustcomm_recv_event_notifier_notif_fd_from_sessiond(sock, + &event_notifier_notif_fd); + switch (len) { + case 0: /* orderly shutdown */ + ret = 0; + goto error; + case 1: + break; + default: + 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 fd message size: %zd", + len); + ret = -EINVAL; + goto error; } - /* Don't free exclusion data if everything went fine. */ - } else { + } + args.event_notifier_handle.event_notifier_notif_fd = + event_notifier_notif_fd; + if (ops->cmd) + ret = ops->cmd(lum->handle, lum->cmd, + (unsigned long) &lum->u, + &args, sock_info); + 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; } @@ -927,10 +1063,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: { + int close_ret; + /* Receive shm_fd, wakeup_fd */ ret = ustcomm_recv_stream_from_sessiond(sock, NULL, @@ -946,6 +1095,22 @@ 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: @@ -1006,6 +1171,142 @@ int handle_message(struct sock_info *sock_info, ret = -ENOSYS; } break; + case LTTNG_UST_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_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_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_EVENT_NOTIFIER_CREATE: + { + /* Receive struct lttng_ust_event_notifier */ + struct lttng_ust_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, @@ -1155,7 +1456,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; @@ -1413,7 +1714,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: @@ -1831,6 +2132,8 @@ void __attribute__((constructor)) lttng_ust_init(void) lttng_ring_buffer_client_overwrite_rt_init(); lttng_ring_buffer_client_discard_init(); lttng_ring_buffer_client_discard_rt_init(); + lttng_counter_client_percpu_32_modular_init(); + lttng_counter_client_percpu_64_modular_init(); lttng_perf_counter_init(); /* * Invoke ust malloc wrapper init before starting other threads. @@ -1976,6 +2279,8 @@ void lttng_ust_cleanup(int exiting) lttng_ring_buffer_client_overwrite_rt_exit(); lttng_ring_buffer_client_overwrite_exit(); lttng_ring_buffer_metadata_client_exit(); + lttng_counter_client_percpu_32_modular_exit(); + lttng_counter_client_percpu_64_modular_exit(); lttng_ust_statedump_destroy(); exit_tracepoint(); if (!exiting) { @@ -2047,9 +2352,26 @@ void ust_context_ns_reset(void) lttng_context_mnt_ns_reset(); lttng_context_net_ns_reset(); lttng_context_user_ns_reset(); + lttng_context_time_ns_reset(); lttng_context_uts_ns_reset(); } +static +void ust_context_vuids_reset(void) +{ + lttng_context_vuid_reset(); + lttng_context_veuid_reset(); + lttng_context_vsuid_reset(); +} + +static +void ust_context_vgids_reset(void) +{ + lttng_context_vgid_reset(); + lttng_context_vegid_reset(); + lttng_context_vsgid_reset(); +} + /* * We exclude the worker threads across fork and clone (except * CLONE_VM), because these system calls only keep the forking thread @@ -2083,7 +2405,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(); } @@ -2111,7 +2433,7 @@ void 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); } @@ -2133,9 +2455,11 @@ void ust_after_fork_child(sigset_t *restore_sigset) lttng_context_vtid_reset(); lttng_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); @@ -2145,11 +2469,55 @@ void ust_after_fork_child(sigset_t *restore_sigset) void ust_after_setns(void) { ust_context_ns_reset(); + ust_context_vuids_reset(); + ust_context_vgids_reset(); } void ust_after_unshare(void) { ust_context_ns_reset(); + ust_context_vuids_reset(); + ust_context_vgids_reset(); +} + +void ust_after_setuid(void) +{ + ust_context_vuids_reset(); +} + +void ust_after_seteuid(void) +{ + ust_context_vuids_reset(); +} + +void ust_after_setreuid(void) +{ + ust_context_vuids_reset(); +} + +void ust_after_setresuid(void) +{ + ust_context_vuids_reset(); +} + +void ust_after_setgid(void) +{ + ust_context_vgids_reset(); +} + +void ust_after_setegid(void) +{ + ust_context_vgids_reset(); +} + +void ust_after_setregid(void) +{ + ust_context_vgids_reset(); +} + +void ust_after_setresgid(void) +{ + ust_context_vgids_reset(); } void lttng_ust_sockinfo_session_enabled(void *owner)