X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=libust%2Ftracectl.c;h=e84a35aecf4e3f979d4cb85163b89e3204ccf45c;hb=37ee34e4d9b9363c758aa43255d71661900e89b0;hp=3b60975391abf72c155f9822a1b06fe3db68004d;hpb=0b362d6f999cbbe4b1a0d8cee2a9fb9a34422b7a;p=ust.git diff --git a/libust/tracectl.c b/libust/tracectl.c index 3b60975..e84a35a 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -41,7 +41,7 @@ #include #include #include "tracer.h" -#include "usterr.h" +#include "usterr_signal_safe.h" #include "ustcomm.h" #include "buffers.h" #include "marker-control.h" @@ -77,8 +77,6 @@ static struct ustcomm_sock *listen_sock; extern struct chan_info_struct chan_infos[]; -static struct cds_list_head open_buffers_list = CDS_LIST_HEAD_INIT(open_buffers_list); - static struct cds_list_head ust_socks = CDS_LIST_HEAD_INIT(ust_socks); /* volatile because shared between the listener and the main thread */ @@ -489,11 +487,6 @@ static int notify_buffer_mapped(const char *trace_name, CMM_STORE_SHARED(buffers_to_export, CMM_LOAD_SHARED(buffers_to_export)-1); } - /* The buffer has been exported, ergo, we can add it to the - * list of open buffers - */ - cds_list_add(&buf->open_buffers_list, &open_buffers_list); - unlock_traces: ltt_unlock_traces(); @@ -543,6 +536,11 @@ unlock_traces: return retval; } +static void release_listener_mutex(void *ptr) +{ + pthread_mutex_unlock(&listener_thread_data_mutex); +} + static void listener_cleanup(void *ptr) { pthread_mutex_lock(&listen_sock_mutex); @@ -553,47 +551,32 @@ static void listener_cleanup(void *ptr) pthread_mutex_unlock(&listen_sock_mutex); } -static void force_subbuf_switch() +static int force_subbuf_switch(const char *trace_name) { - struct ust_buffer *buf; - - cds_list_for_each_entry(buf, &open_buffers_list, - open_buffers_list) { - ltt_force_switch(buf, FORCE_FLUSH); - } -} + struct ust_trace *trace; + int i, j, retval = 0; -/* Simple commands are those which need only respond with a return value. */ -static int process_simple_client_cmd(int command, char *recv_buf) -{ - int result; + ltt_lock_traces(); + trace = _ltt_trace_find(trace_name); + if (!trace) { + retval = -ENODATA; + DBG("Cannot find trace. It was likely destroyed by the user."); + goto unlock_traces; + } - switch(command) { - case SET_SOCK_PATH: - { - struct ustcomm_single_field *sock_msg; - sock_msg = (struct ustcomm_single_field *)recv_buf; - result = ustcomm_unpack_single_field(sock_msg); - if (result < 0) { - return result; + for (i = 0; i < trace->nr_channels; i++) { + for (j = 0; j < trace->channels[i].n_cpus; j++) { + ltt_force_switch(trace->channels[i].buf[j], + FORCE_FLUSH); } - return setenv("UST_DAEMON_SOCKET", sock_msg->field, 1); } - case FORCE_SUBBUF_SWITCH: - /* FIXME: return codes? */ - force_subbuf_switch(); - - break; - - default: - return -EINVAL; - } +unlock_traces: + ltt_unlock_traces(); - return 0; + return retval; } - static int process_trace_cmd(int command, char *trace_name) { int result; @@ -711,6 +694,15 @@ static int process_trace_cmd(int command, char *trace_name) return result; } return 0; + case FORCE_SUBBUF_SWITCH: + DBG("force switch"); + + result = force_subbuf_switch(trace_name); + if (result < 0) { + ERR("force_subbuf_switch failed"); + return result; + } + return 0; } return 0; @@ -952,7 +944,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header, print_markers(fp); fclose(fp); - reply_header->size = size; + reply_header->size = size + 1; /* Include final \0 */ result = ustcomm_send(sock, reply_header, ptr); @@ -978,7 +970,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header, print_trace_events(fp); fclose(fp); - reply_header->size = size; + reply_header->size = size + 1; /* Include final \0 */ result = ustcomm_send(sock, reply_header, ptr); @@ -1036,6 +1028,21 @@ static void process_client_cmd(struct ustcomm_header *recv_header, goto send_response; } + case SET_SOCK_PATH: + { + struct ustcomm_single_field *sock_msg; + sock_msg = (struct ustcomm_single_field *)recv_buf; + result = ustcomm_unpack_single_field(sock_msg); + if (result < 0) { + reply_header->result = -EINVAL; + goto send_response; + } + + reply_header->result = setenv("UST_DAEMON_SOCKET", + sock_msg->field, 1); + + goto send_response; + } case START: case SETUP_TRACE: case ALLOC_TRACE: @@ -1043,6 +1050,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header, case START_TRACE: case STOP_TRACE: case DESTROY_TRACE: + case FORCE_SUBBUF_SWITCH: { struct ustcomm_single_field *trace_inf = (struct ustcomm_single_field *)recv_buf; @@ -1061,11 +1069,9 @@ static void process_client_cmd(struct ustcomm_header *recv_header, } default: - reply_header->result = - process_simple_client_cmd(recv_header->command, - recv_buf); - goto send_response; + reply_header->result = -EINVAL; + goto send_response; } return; @@ -1096,6 +1102,7 @@ void *listener_main(void *p) for (i = 0; i < nfds; i++) { pthread_mutex_lock(&listener_thread_data_mutex); + pthread_cleanup_push(release_listener_mutex, NULL); epoll_sock = (struct ustcomm_sock *)events[i].data.ptr; if (epoll_sock == listen_sock) { addr_size = sizeof(struct sockaddr); @@ -1124,7 +1131,7 @@ void *listener_main(void *p) epoll_sock->fd); } } - pthread_mutex_unlock(&listener_thread_data_mutex); + pthread_cleanup_pop(1); /* release listener mutex */ } } @@ -1214,37 +1221,41 @@ static void auto_probe_connect(struct marker *m) static struct ustcomm_sock * init_app_socket(int epoll_fd) { - char *name; + char *dir_name, *sock_name; int result; - struct ustcomm_sock *sock; + struct ustcomm_sock *sock = NULL; + + dir_name = ustcomm_user_sock_dir(); + if (!dir_name) + return NULL; - result = asprintf(&name, "%s/%d", SOCK_DIR, (int)getpid()); + result = asprintf(&sock_name, "%s/%d", dir_name, (int)getpid()); if (result < 0) { ERR("string overflow allocating socket name, " "UST thread bailing"); - return NULL; + goto free_dir_name; } - result = ensure_dir_exists(SOCK_DIR); + result = ensure_dir_exists(dir_name, S_IRWXU); if (result == -1) { ERR("Unable to create socket directory %s, UST thread bailing", - SOCK_DIR); - goto free_name; + dir_name); + goto free_sock_name; } - sock = ustcomm_init_named_socket(name, epoll_fd); + sock = ustcomm_init_named_socket(sock_name, epoll_fd); if (!sock) { ERR("Error initializing named socket (%s). Check that directory" - "exists and that it is writable. UST thread bailing", name); - goto free_name; + "exists and that it is writable. UST thread bailing", sock_name); + goto free_sock_name; } - free(name); - return sock; +free_sock_name: + free(sock_name); +free_dir_name: + free(dir_name); -free_name: - free(name); - return NULL; + return sock; } static void __attribute__((constructor)) init() @@ -1565,7 +1576,7 @@ static void __attribute__((destructor)) keepalive() void ust_potential_exec(void) { - trace_mark(ust, potential_exec, MARK_NOARGS); + trace_mark(potential_exec, MARK_NOARGS); DBG("test"); @@ -1584,7 +1595,6 @@ void ust_potential_exec(void) static void ust_fork(void) { - struct ust_buffer *buf, *buf_tmp; struct ustcomm_sock *sock, *sock_tmp; struct ust_trace *trace, *trace_tmp; int result; @@ -1608,12 +1618,6 @@ static void ust_fork(void) ustcomm_del_sock(sock, 1); } - /* Delete all blocked consumers */ - cds_list_for_each_entry_safe(buf, buf_tmp, &open_buffers_list, - open_buffers_list) { - cds_list_del(&buf->open_buffers_list); - } - /* * FIXME: This could be prettier, we loop over the list twice and * following good locking practice should lock around the loop @@ -1691,6 +1695,7 @@ void ust_before_fork(ust_fork_info_t *fork_info) * Hold listen_sock_mutex to protect from listen_sock teardown. */ pthread_mutex_lock(&listen_sock_mutex); + rcu_bp_before_fork(); } /* Don't call this function directly in a traced program */ @@ -1711,24 +1716,20 @@ static void ust_after_fork_common(ust_fork_info_t *fork_info) void ust_after_fork_parent(ust_fork_info_t *fork_info) { + rcu_bp_after_fork_parent(); /* Release mutexes and reenable signals */ ust_after_fork_common(fork_info); } void ust_after_fork_child(ust_fork_info_t *fork_info) { - /* First sanitize the child */ + /* Release urcu mutexes */ + rcu_bp_after_fork_child(); + + /* Sanitize the child */ ust_fork(); /* Then release mutexes and reenable signals */ ust_after_fork_common(fork_info); - - /* - * Make sure we clean up the urcu-bp thread list in the child by running - * the garbage collection before any pthread_create can be called. - * Failure to do so could lead to a deadlock caused by reuse of a thread - * ID before urcu-bp garbage collection is performed. - */ - synchronize_rcu(); }