X-Git-Url: http://git.liburcu.org/?p=lttng-ust.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ust%2Flttng-ust-comm.c;fp=src%2Flib%2Flttng-ust%2Flttng-ust-comm.c;h=229e457a428ff9fa1c3781700b3f5f8eec4f532c;hp=ccf2a9b816e00920f92850a927bbdf6205c944b6;hb=c0f6fb054d2f16518d047a6adf7e8aa81eff5403;hpb=47bc09f338f3c1199a878f77b7b18be8d2a224f6 diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index ccf2a9b8..229e457a 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -234,10 +234,10 @@ void ust_unlock(void) */ static sem_t constructor_wait; /* - * Doing this for both the global and local sessiond. + * Doing this for the ust_app, global and local sessiond. */ enum { - sem_count_initial_value = 4, + sem_count_initial_value = 6, }; static int sem_count = sem_count_initial_value; @@ -264,8 +264,15 @@ struct sock_info { int socket; int notify_socket; + /* + * If wait_shm_is_file is true, use standard open to open and + * create the shared memory used for waiting on session daemon. + * Otherwise, use shm_open to create this file. + */ + bool wait_shm_is_file; char wait_shm_path[PATH_MAX]; char *wait_shm_mmap; + /* Keep track of lazy state dump not performed yet. */ int statedump_pending; int initial_statedump_done; @@ -274,6 +281,26 @@ struct sock_info { }; /* Socket from app (connect) to session daemon (listen) for communication */ +static struct sock_info ust_app = { + .name = "ust_app", + .multi_user = true, + + .root_handle = -1, + .registration_done = 0, + .allowed = 0, + .thread_active = 0, + + .socket = -1, + .notify_socket = -1, + + .wait_shm_is_file = true, + + .statedump_pending = 0, + .initial_statedump_done = 0, + .procname[0] = '\0' +}; + + static struct sock_info global_apps = { .name = "global", .multi_user = true, @@ -287,6 +314,7 @@ static struct sock_info global_apps = { .socket = -1, .notify_socket = -1, + .wait_shm_is_file = false, .wait_shm_path = "/" LTTNG_UST_WAIT_FILENAME, .statedump_pending = 0, @@ -294,8 +322,6 @@ static struct sock_info global_apps = { .procname[0] = '\0' }; -/* TODO: allow global_apps_sock_path override */ - static struct sock_info local_apps = { .name = "local", .multi_user = false, @@ -307,6 +333,8 @@ static struct sock_info local_apps = { .socket = -1, .notify_socket = -1, + .wait_shm_is_file = false, + .statedump_pending = 0, .initial_statedump_done = 0, .procname[0] = '\0' @@ -383,6 +411,12 @@ const char *get_lttng_home_dir(void) return (const char *) lttng_ust_getenv("HOME"); } +static +const char *get_lttng_ust_app_path(void) +{ + return (const char *) lttng_ust_getenv("LTTNG_UST_APP_PATH"); +} + /* * Force a read (imply TLS allocation for dlopen) of TLS variables. */ @@ -480,12 +514,70 @@ void print_cmd(int cmd, int handle) lttng_ust_obj_get_name(handle), handle); } +static +int setup_ust_apps(void) +{ + const char *ust_app_path; + int ret = 0; + uid_t uid; + + assert(!ust_app.wait_shm_mmap); + + uid = getuid(); + /* + * Disallow ust apps tracing for setuid binaries, because we + * cannot use the environment variables anyway. + */ + if (uid != geteuid()) { + DBG("UST app tracing disabled for setuid binary."); + assert(ust_app.allowed == 0); + ret = 0; + goto end; + } + ust_app_path = get_lttng_ust_app_path(); + if (!ust_app_path) { + DBG("LTTNG_UST_APP_PATH environment variable not set."); + assert(ust_app.allowed == 0); + ret = -ENOENT; + goto end; + } + /* + * The LTTNG_UST_APP_PATH env. var. disables global and local + * sessiond connections. + */ + ust_app.allowed = 1; + snprintf(ust_app.sock_path, PATH_MAX, "%s/%s", + ust_app_path, LTTNG_UST_SOCK_FILENAME); + snprintf(ust_app.wait_shm_path, PATH_MAX, "%s/%s", + ust_app_path, + LTTNG_UST_WAIT_FILENAME); + + ust_app.wait_shm_mmap = get_map_shm(&ust_app); + if (!ust_app.wait_shm_mmap) { + WARN("Unable to get map shm for ust_app. Disabling LTTng-UST ust_app tracing."); + ust_app.allowed = 0; + ret = -EIO; + goto end; + } + + lttng_pthread_getname_np(ust_app.procname, LTTNG_UST_CONTEXT_PROCNAME_LEN); +end: + return ret; +} + static int setup_global_apps(void) { int ret = 0; assert(!global_apps.wait_shm_mmap); + /* + * The LTTNG_UST_APP_PATH env. var. disables global sessiond + * connections. + */ + if (ust_app.allowed) + return 0; + global_apps.wait_shm_mmap = get_map_shm(&global_apps); if (!global_apps.wait_shm_mmap) { WARN("Unable to get map shm for global apps. Disabling LTTng-UST global tracing."); @@ -499,6 +591,7 @@ int setup_global_apps(void) error: return ret; } + static int setup_local_apps(void) { @@ -508,6 +601,13 @@ int setup_local_apps(void) assert(!local_apps.wait_shm_mmap); + /* + * The LTTNG_UST_APP_PATH env. var. disables local sessiond + * connections. + */ + if (ust_app.allowed) + return 0; + uid = getuid(); /* * Disallow per-user tracing for setuid binaries. @@ -1520,6 +1620,15 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) } } +static +int wait_shm_open(struct sock_info *sock_info, int flags, mode_t mode) +{ + if (sock_info->wait_shm_is_file) + return open(sock_info->wait_shm_path, flags, mode); + else + return shm_open(sock_info->wait_shm_path, flags, mode); +} + /* * 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 @@ -1538,7 +1647,7 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) /* * Try to open read-only. */ - wait_shm_fd = shm_open(sock_info->wait_shm_path, O_RDONLY, 0); + wait_shm_fd = wait_shm_open(sock_info, O_RDONLY, 0); if (wait_shm_fd >= 0) { int32_t tmp_read; ssize_t len; @@ -1598,7 +1707,7 @@ open_write: /* * Try to open read-only again after creation. */ - wait_shm_fd = shm_open(sock_info->wait_shm_path, O_RDONLY, 0); + wait_shm_fd = wait_shm_open(sock_info, O_RDONLY, 0); if (wait_shm_fd < 0) { /* * Real-only open did not work. It's a failure @@ -1625,7 +1734,7 @@ open_write: * We don't do an exclusive open, because we allow other * processes to create+ftruncate it concurrently. */ - wait_shm_fd = shm_open(sock_info->wait_shm_path, + wait_shm_fd = wait_shm_open(sock_info, O_RDWR | O_CREAT, create_mode); if (wait_shm_fd >= 0) { ret = ftruncate(wait_shm_fd, mmap_size); @@ -2258,6 +2367,11 @@ void lttng_ust_ctor(void) PERROR("sem_init"); } + ret = setup_ust_apps(); + if (ret) { + assert(ust_app.allowed == 0); + DBG("ust_app setup returned %d", ret); + } ret = setup_global_apps(); if (ret) { assert(global_apps.allowed == 0); @@ -2290,6 +2404,19 @@ void lttng_ust_ctor(void) ERR("pthread_attr_setdetachstate: %s", strerror(ret)); } + if (ust_app.allowed) { + pthread_mutex_lock(&ust_exit_mutex); + ret = pthread_create(&ust_app.ust_listener, &thread_attr, + ust_listener_thread, &ust_app); + if (ret) { + ERR("pthread_create ust_app: %s", strerror(ret)); + } + ust_app.thread_active = 1; + pthread_mutex_unlock(&ust_exit_mutex); + } else { + handle_register_done(&ust_app); + } + if (global_apps.allowed) { pthread_mutex_lock(&ust_exit_mutex); ret = pthread_create(&global_apps.ust_listener, &thread_attr, @@ -2369,8 +2496,10 @@ void lttng_ust_ctor(void) static void lttng_ust_cleanup(int exiting) { + cleanup_sock_info(&ust_app, exiting); cleanup_sock_info(&global_apps, exiting); cleanup_sock_info(&local_apps, exiting); + ust_app.allowed = 0; local_apps.allowed = 0; global_apps.allowed = 0; /* @@ -2420,6 +2549,15 @@ void lttng_ust_exit(void) pthread_mutex_lock(&ust_exit_mutex); /* cancel threads */ + if (ust_app.thread_active) { + ret = pthread_cancel(ust_app.ust_listener); + if (ret) { + ERR("Error cancelling ust listener thread: %s", + strerror(ret)); + } else { + ust_app.thread_active = 0; + } + } if (global_apps.thread_active) { ret = pthread_cancel(global_apps.ust_listener); if (ret) {