X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=77d8e3fcb3564de19100b0a50c080ecba5ba2ad4;hb=16b36e5502b612f3c99e34bf8f5e794029ca3263;hp=202ff1829c6b4746b8629c44df5fb411e9659079;hpb=321f235159b13a8a032d23fd60b9c3532790647e;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 202ff182..77d8e3fc 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,7 @@ struct sock_info { char wait_shm_path[PATH_MAX]; char *wait_shm_mmap; + struct lttng_session *session_enabled; }; /* Socket from app (connect) to session daemon (listen) for communication */ @@ -122,6 +124,8 @@ struct sock_info global_apps = { .notify_socket = -1, .wait_shm_path = "/" LTTNG_UST_WAIT_FILENAME, + + .session_enabled = NULL, }; /* TODO: allow global_apps_sock_path override */ @@ -135,6 +139,8 @@ struct sock_info local_apps = { .socket = -1, .notify_socket = -1, + + .session_enabled = NULL, }; static int wait_poll_fallback; @@ -172,10 +178,12 @@ static const char *cmd_name_mapping[] = { /* Event FD commands */ [ LTTNG_UST_FILTER ] = "Create Filter", + [ LTTNG_UST_EXCLUSION ] = "Add exclusions to event", }; static const char *str_timeout; static int got_timeout_env; +static void *ust_baddr_handle; extern void lttng_ring_buffer_client_overwrite_init(void); extern void lttng_ring_buffer_client_overwrite_rt_init(void); @@ -234,6 +242,39 @@ void print_cmd(int cmd, int handle) lttng_ust_obj_get_name(handle), handle); } +static +void *lttng_ust_baddr_handle(void) +{ + if (!ust_baddr_handle) { + ust_baddr_handle = dlopen( + "liblttng-ust-baddr.so.0", RTLD_NOW | RTLD_GLOBAL); + if (ust_baddr_handle == NULL) + ERR("%s", dlerror()); + } + return ust_baddr_handle; +} + +static +int lttng_ust_baddr_statedump(struct lttng_session *session) +{ + static + int (*lttng_ust_baddr_init_fn)(struct lttng_session *); + + if (!lttng_ust_baddr_init_fn) { + void *baddr_handle = lttng_ust_baddr_handle(); + if (baddr_handle) { + lttng_ust_baddr_init_fn = dlsym(baddr_handle, + "lttng_ust_baddr_statedump"); + if (lttng_ust_baddr_init_fn == NULL) + ERR("%s", dlerror()); + } + if (!lttng_ust_baddr_init_fn) + return -1; + } + + return lttng_ust_baddr_init_fn(session); +} + static int setup_local_apps(void) { @@ -487,6 +528,68 @@ int handle_message(struct sock_info *sock_info, } break; } + case LTTNG_UST_EXCLUSION: + { + /* Receive exclusion names */ + struct lttng_ust_excluder_node *node; + unsigned int count; + + 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); + switch (len) { + case 0: /* orderly shutdown */ + ret = 0; + free(node); + goto error; + 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 == -ECONNRESET) { + ERR("%s remote end closed connection", sock_info->name); + ret = len; + free(node); + goto error; + } + ret = len; + free(node); + goto end; + } else { + DBG("Incorrect exclusion data message size: %zd", len); + ret = -EINVAL; + free(node); + goto end; + } + } + if (ops->cmd) { + ret = ops->cmd(lum->handle, lum->cmd, + (unsigned long) node, + &args, sock_info); + if (ret) { + free(node); + } + /* Don't free exclusion data if everything went fine. */ + } else { + ret = -ENOSYS; + free(node); + } + break; + } case LTTNG_UST_CHANNEL: { void *chan_data; @@ -705,6 +808,30 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) */ wait_shm_fd = shm_open(sock_info->wait_shm_path, O_RDONLY, 0); if (wait_shm_fd >= 0) { + int32_t tmp_read; + ssize_t len; + size_t bytes_read = 0; + + /* + * Try to read the fd. If unable to do so, try opening + * it in write mode. + */ + do { + len = read(wait_shm_fd, + &((char *) &tmp_read)[bytes_read], + sizeof(tmp_read) - bytes_read); + if (len > 0) { + bytes_read += len; + } + } while ((len < 0 && errno == EINTR) + || (len > 0 && bytes_read < sizeof(tmp_read))); + if (bytes_read != sizeof(tmp_read)) { + ret = close(wait_shm_fd); + if (ret) { + ERR("close wait_shm_fd"); + } + goto open_write; + } goto end; } else if (wait_shm_fd < 0 && errno != ENOENT) { /* @@ -715,9 +842,11 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) ERR("Error opening shm %s", sock_info->wait_shm_path); goto end; } + +open_write: /* - * If the open failed because the file did not exist, try - * creating it ourself. + * If the open failed because the file did not exist, or because + * the file was not truncated yet, try creating it ourself. */ URCU_TLS(lttng_ust_nest_count)++; pid = fork(); @@ -1117,6 +1246,13 @@ restart: ret = handle_message(sock_info, sock, &lum); if (ret) { ERR("Error handling message for %s socket", sock_info->name); + } else { + struct lttng_session *session = + sock_info->session_enabled; + if (session) { + sock_info->session_enabled = NULL; + lttng_ust_baddr_statedump(session); + } } continue; default: @@ -1353,6 +1489,12 @@ void __attribute__((destructor)) lttng_ust_exit(void) * cleanup the threads if there are stalled in a syscall. */ lttng_ust_cleanup(1); + + if (ust_baddr_handle) { + int ret = dlclose(ust_baddr_handle); + if (ret) + ERR("%s", dlerror()); + } } /* @@ -1430,3 +1572,10 @@ void ust_after_fork_child(sigset_t *restore_sigset) ust_after_fork_common(restore_sigset); lttng_ust_init(); } + +void lttng_ust_sockinfo_session_enabled(void *owner, + struct lttng_session *session_enabled) +{ + struct sock_info *sock_info = owner; + sock_info->session_enabled = session_enabled; +}