X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=f0af340770ca59bd98ddda1d48e0ffd4d01bd262;hp=96ba2f4bcad0649afe1cfcec93e2f6c1f13002df;hb=c8fea79c745d42ea8143b7020ae11b4fc2da0d8a;hpb=df5b86c84d896eb2d74a8757c234492c1d1fc3be diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 96ba2f4bc..f0af34077 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -15,7 +15,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE #define _LGPL_SOURCE #include #include @@ -101,12 +100,14 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key) { struct ust_app_event *event; const struct ust_app_ht_key *key; + int ev_loglevel_value; assert(node); assert(_key); event = caa_container_of(node, struct ust_app_event, node.node); key = _key; + ev_loglevel_value = event->attr.loglevel; /* Match the 4 elements of the key: name, filter, loglevel, exclusions */ @@ -116,9 +117,10 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key) } /* Event loglevel. */ - if (event->attr.loglevel != key->loglevel) { + if (ev_loglevel_value != key->loglevel_type) { if (event->attr.loglevel_type == LTTNG_UST_LOGLEVEL_ALL - && key->loglevel == 0 && event->attr.loglevel == -1) { + && key->loglevel_type == 0 && + ev_loglevel_value == -1) { /* * Match is accepted. This is because on event creation, the * loglevel is set to -1 if the event loglevel type is ALL so 0 and @@ -184,7 +186,7 @@ static void add_unique_ust_app_event(struct ust_app_channel *ua_chan, ht = ua_chan->events; key.name = event->attr.name; key.filter = event->filter; - key.loglevel = event->attr.loglevel; + key.loglevel_type = event->attr.loglevel; key.exclusion = event->exclusion; node_ptr = cds_lfht_add_unique(ht->ht, @@ -262,14 +264,17 @@ error: * this function. */ static -void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx) +void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx, + struct ust_app *app) { int ret; assert(ua_ctx); if (ua_ctx->obj) { + pthread_mutex_lock(&app->sock_lock); ret = ustctl_release_object(sock, ua_ctx->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app sock %d release ctx obj handle %d failed with ret %d", sock, ua_ctx->obj->handle, ret); @@ -284,7 +289,8 @@ void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx) * this function. */ static -void delete_ust_app_event(int sock, struct ust_app_event *ua_event) +void delete_ust_app_event(int sock, struct ust_app_event *ua_event, + struct ust_app *app) { int ret; @@ -294,7 +300,9 @@ void delete_ust_app_event(int sock, struct ust_app_event *ua_event) if (ua_event->exclusion != NULL) free(ua_event->exclusion); if (ua_event->obj != NULL) { + pthread_mutex_lock(&app->sock_lock); ret = ustctl_release_object(sock, ua_event->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app sock %d release event obj failed with ret %d", sock, ret); @@ -309,14 +317,17 @@ void delete_ust_app_event(int sock, struct ust_app_event *ua_event) * * Return 0 on success or else a negative value. */ -static int release_ust_app_stream(int sock, struct ust_app_stream *stream) +static int release_ust_app_stream(int sock, struct ust_app_stream *stream, + struct ust_app *app) { int ret = 0; assert(stream); if (stream->obj) { + pthread_mutex_lock(&app->sock_lock); ret = ustctl_release_object(sock, stream->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app sock %d release stream obj failed with ret %d", sock, ret); @@ -333,11 +344,12 @@ static int release_ust_app_stream(int sock, struct ust_app_stream *stream) * this function. */ static -void delete_ust_app_stream(int sock, struct ust_app_stream *stream) +void delete_ust_app_stream(int sock, struct ust_app_stream *stream, + struct ust_app *app) { assert(stream); - (void) release_ust_app_stream(sock, stream); + (void) release_ust_app_stream(sock, stream, app); free(stream); } @@ -380,7 +392,7 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, /* Wipe stream */ cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) { cds_list_del(&stream->list); - delete_ust_app_stream(sock, stream); + delete_ust_app_stream(sock, stream, app); } /* Wipe context */ @@ -388,7 +400,7 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, cds_list_del(&ua_ctx->list); ret = lttng_ht_del(ua_chan->ctx, &iter); assert(!ret); - delete_ust_app_ctx(sock, ua_ctx); + delete_ust_app_ctx(sock, ua_ctx, app); } /* Wipe events */ @@ -396,7 +408,7 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, node.node) { ret = lttng_ht_del(ua_chan->events, &iter); assert(!ret); - delete_ust_app_event(sock, ua_event); + delete_ust_app_event(sock, ua_event, app); } if (ua_chan->session->buffer_type == LTTNG_BUFFER_PER_PID) { @@ -412,7 +424,9 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, iter.iter.node = &ua_chan->ust_objd_node.node; ret = lttng_ht_del(app->ust_objd, &iter); assert(!ret); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_release_object(sock, ua_chan->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app sock %d release channel obj failed with ret %d", sock, ret); @@ -423,6 +437,33 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, call_rcu(&ua_chan->rcu_head, delete_ust_app_channel_rcu); } +int ust_app_register_done(struct ust_app *app) +{ + int ret; + + pthread_mutex_lock(&app->sock_lock); + ret = ustctl_register_done(app->sock); + pthread_mutex_unlock(&app->sock_lock); + return ret; +} + +int ust_app_release_object(struct ust_app *app, struct lttng_ust_object_data *data) +{ + int ret, sock; + + if (app) { + pthread_mutex_lock(&app->sock_lock); + sock = app->sock; + } else { + sock = -1; + } + ret = ustctl_release_object(sock, data); + if (app) { + pthread_mutex_unlock(&app->sock_lock); + } + return ret; +} + /* * Push metadata to consumer socket. * @@ -440,17 +481,20 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry, { int ret; char *metadata_str = NULL; - size_t len, offset; + size_t len, offset, new_metadata_len_sent; ssize_t ret_val; + uint64_t metadata_key; assert(registry); assert(socket); + metadata_key = registry->metadata_key; + /* * Means that no metadata was assigned to the session. This can * happens if no start has been done previously. */ - if (!registry->metadata_key) { + if (!metadata_key) { return 0; } @@ -468,6 +512,7 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry, offset = registry->metadata_len_sent; len = registry->metadata_len - registry->metadata_len_sent; + new_metadata_len_sent = registry->metadata_len; if (len == 0) { DBG3("No metadata to push for metadata key %" PRIu64, registry->metadata_key); @@ -486,13 +531,26 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry, ret_val = -ENOMEM; goto error; } - /* Copy what we haven't send out. */ + /* Copy what we haven't sent out. */ memcpy(metadata_str, registry->metadata + offset, len); - registry->metadata_len_sent += len; push_data: - ret = consumer_push_metadata(socket, registry->metadata_key, + pthread_mutex_unlock(®istry->lock); + /* + * We need to unlock the registry while we push metadata to + * break a circular dependency between the consumerd metadata + * lock and the sessiond registry lock. Indeed, pushing metadata + * to the consumerd awaits that it gets pushed all the way to + * relayd, but doing so requires grabbing the metadata lock. If + * a concurrent metadata request is being performed by + * consumerd, this can try to grab the registry lock on the + * sessiond while holding the metadata lock on the consumer + * daemon. Those push and pull schemes are performed on two + * different bidirectionnal communication sockets. + */ + ret = consumer_push_metadata(socket, metadata_key, metadata_str, len, offset); + pthread_mutex_lock(®istry->lock); if (ret < 0) { /* * There is an acceptable race here between the registry @@ -510,17 +568,29 @@ push_data: */ if (ret == -LTTCOMM_CONSUMERD_CHANNEL_FAIL) { ret = 0; + } else { + ERR("Error pushing metadata to consumer"); } - - /* - * Update back the actual metadata len sent since it - * failed here. - */ - registry->metadata_len_sent -= len; ret_val = ret; goto error_push; + } else { + /* + * Metadata may have been concurrently pushed, since + * we're not holding the registry lock while pushing to + * consumer. This is handled by the fact that we send + * the metadata content, size, and the offset at which + * that metadata belongs. This may arrive out of order + * on the consumer side, and the consumer is able to + * deal with overlapping fragments. The consumer + * supports overlapping fragments, which must be + * contiguous starting from offset 0. We keep the + * largest metadata_len_sent value of the concurrent + * send. + */ + registry->metadata_len_sent = + max_t(size_t, registry->metadata_len_sent, + new_metadata_len_sent); } - free(metadata_str); return len; @@ -714,7 +784,9 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, } if (ua_sess->handle != -1) { + pthread_mutex_lock(&app->sock_lock); ret = ustctl_release_handle(sock, ua_sess->handle); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app sock %d release session handle failed with ret %d", sock, ret); @@ -1079,7 +1151,8 @@ error: * Return an ust_app_event object or NULL on error. */ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht, - char *name, struct lttng_filter_bytecode *filter, int loglevel, + char *name, struct lttng_filter_bytecode *filter, + int loglevel_value, const struct lttng_event_exclusion *exclusion) { struct lttng_ht_iter iter; @@ -1093,7 +1166,7 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht, /* Setup key for event lookup. */ key.name = name; key.filter = filter; - key.loglevel = loglevel; + key.loglevel_type = loglevel_value; /* lttng_event_exclusion and lttng_ust_event_exclusion structures are similar */ key.exclusion = exclusion; @@ -1124,8 +1197,10 @@ int create_ust_channel_context(struct ust_app_channel *ua_chan, health_code_update(); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_add_context(app->sock, &ua_ctx->ctx, ua_chan->obj, &ua_ctx->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app create channel context failed for app (pid: %d) " @@ -1174,8 +1249,10 @@ int set_ust_event_filter(struct ust_app_event *ua_event, ret = -LTTNG_ERR_NOMEM; goto error; } + pthread_mutex_lock(&app->sock_lock); ret = ustctl_set_filter(app->sock, ust_bytecode, ua_event->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app event %s filter failed for app (pid: %d) " @@ -1244,7 +1321,9 @@ int set_ust_event_exclusion(struct ust_app_event *ua_event, ret = -LTTNG_ERR_NOMEM; goto error; } + pthread_mutex_lock(&app->sock_lock); ret = ustctl_set_exclusion(app->sock, ust_exclusion, ua_event->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app event %s exclusions failed for app (pid: %d) " @@ -1279,7 +1358,9 @@ static int disable_ust_event(struct ust_app *app, health_code_update(); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_disable(app->sock, ua_event->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app event %s disable failed for app (pid: %d) " @@ -1315,7 +1396,9 @@ static int disable_ust_channel(struct ust_app *app, health_code_update(); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_disable(app->sock, ua_chan->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app channel %s disable failed for app (pid: %d) " @@ -1351,7 +1434,9 @@ static int enable_ust_channel(struct ust_app *app, health_code_update(); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_enable(app->sock, ua_chan->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app channel %s enable failed for app (pid: %d) " @@ -1389,7 +1474,9 @@ static int enable_ust_event(struct ust_app *app, health_code_update(); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_enable(app->sock, ua_event->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app event %s enable failed for app (pid: %d) " @@ -1457,7 +1544,7 @@ static int send_channel_pid_to_ust(struct ust_app *app, } /* We don't need the stream anymore once sent to the tracer. */ cds_list_del(&stream->list); - delete_ust_app_stream(-1, stream); + delete_ust_app_stream(-1, stream, app); } /* Flag the channel that it is sent to the application. */ ua_chan->is_sent = 1; @@ -1481,8 +1568,10 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess, health_code_update(); /* Create UST event on tracer */ + pthread_mutex_lock(&app->sock_lock); ret = ustctl_create_event(app->sock, &ua_event->attr, ua_chan->obj, &ua_event->obj); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("Error ustctl create event %s for app pid: %d with ret %d", @@ -2015,7 +2104,9 @@ static int create_ust_app_session(struct ltt_ust_session *usess, health_code_update(); if (ua_sess->handle == -1) { + pthread_mutex_lock(&app->sock_lock); ret = ustctl_create_session(app->sock); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("Creating session for app pid %d with ret %d", @@ -2441,7 +2532,8 @@ error_fd_get: * Return 0 on success or else a negative value. */ static int setup_buffer_reg_streams(struct buffer_reg_channel *reg_chan, - struct ust_app_channel *ua_chan) + struct ust_app_channel *ua_chan, + struct ust_app *app) { int ret = 0; struct ust_app_stream *stream, *stmp; @@ -2470,7 +2562,7 @@ static int setup_buffer_reg_streams(struct buffer_reg_channel *reg_chan, /* We don't need the streams anymore. */ cds_list_del(&stream->list); - delete_ust_app_stream(-1, stream); + delete_ust_app_stream(-1, stream, app); } error: @@ -2534,7 +2626,8 @@ error_create: * Return 0 on success else a negative value. */ static int setup_buffer_reg_channel(struct buffer_reg_session *reg_sess, - struct ust_app_channel *ua_chan, struct buffer_reg_channel *reg_chan) + struct ust_app_channel *ua_chan, struct buffer_reg_channel *reg_chan, + struct ust_app *app) { int ret; @@ -2546,7 +2639,7 @@ static int setup_buffer_reg_channel(struct buffer_reg_session *reg_sess, DBG2("UST app setup buffer registry channel for %s", ua_chan->name); /* Setup all streams for the registry. */ - ret = setup_buffer_reg_streams(reg_chan, ua_chan); + ret = setup_buffer_reg_streams(reg_chan, ua_chan, app); if (ret < 0) { goto error; } @@ -2609,7 +2702,7 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan, ret = ust_consumer_send_stream_to_ust(app, ua_chan, &stream); if (ret < 0) { - (void) release_ust_app_stream(-1, &stream); + (void) release_ust_app_stream(-1, &stream, app); if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) { ret = -ENOTCONN; /* Caused by app exiting. */ goto error_stream_unlock; @@ -2623,7 +2716,7 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan, * The return value is not important here. This function will output an * error if needed. */ - (void) release_ust_app_stream(-1, &stream); + (void) release_ust_app_stream(-1, &stream, app); } ua_chan->is_sent = 1; @@ -2697,7 +2790,8 @@ static int create_channel_per_uid(struct ust_app *app, /* * Setup the streams and add it to the session registry. */ - ret = setup_buffer_reg_channel(reg_uid->registry, ua_chan, reg_chan); + ret = setup_buffer_reg_channel(reg_uid->registry, + ua_chan, reg_chan, app); if (ret < 0) { ERR("Error setting up UST channel \"%s\"", ua_chan->name); @@ -2943,7 +3037,7 @@ end: error: /* Valid. Calling here is already in a read side lock */ - delete_ust_app_event(-1, ua_event); + delete_ust_app_event(-1, ua_event, app); return ret; } @@ -3134,10 +3228,10 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock) lta->pid = msg->pid; lttng_ht_node_init_ulong(<a->pid_n, (unsigned long) lta->pid); lta->sock = sock; + pthread_mutex_init(<a->sock_lock, NULL); lttng_ht_node_init_ulong(<a->sock_n, (unsigned long) lta->sock); CDS_INIT_LIST_HEAD(<a->teardown_head); - error: return lta; } @@ -3189,7 +3283,9 @@ int ust_app_version(struct ust_app *app) assert(app); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_tracer_version(app->sock, &app->version); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) { ERR("UST app %d version failed with ret %d", app->sock, ret); @@ -3354,12 +3450,14 @@ int ust_app_list_events(struct lttng_event **events) */ continue; } + pthread_mutex_lock(&app->sock_lock); handle = ustctl_tracepoint_list(app->sock); if (handle < 0) { if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) { ERR("UST app list events getting handle failed for app pid %d", app->pid); } + pthread_mutex_unlock(&app->sock_lock); continue; } @@ -3367,6 +3465,8 @@ int ust_app_list_events(struct lttng_event **events) &uiter)) != -LTTNG_UST_ERR_NOENT) { /* Handle ustctl error. */ if (ret < 0) { + int release_ret; + if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) { ERR("UST app tp list get failed for app %d with ret %d", app->sock, ret); @@ -3380,6 +3480,13 @@ int ust_app_list_events(struct lttng_event **events) break; } free(tmp_event); + release_ret = ustctl_release_handle(app->sock, handle); + if (release_ret < 0 && + release_ret != -LTTNG_UST_ERR_EXITING && + release_ret != -EPIPE) { + ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret); + } + pthread_mutex_unlock(&app->sock_lock); goto rcu_error; } @@ -3395,9 +3502,18 @@ int ust_app_list_events(struct lttng_event **events) new_tmp_event = realloc(tmp_event, new_nbmem * sizeof(struct lttng_event)); if (new_tmp_event == NULL) { + int release_ret; + PERROR("realloc ust app events"); free(tmp_event); ret = -ENOMEM; + release_ret = ustctl_release_handle(app->sock, handle); + if (release_ret < 0 && + release_ret != -LTTNG_UST_ERR_EXITING && + release_ret != -EPIPE) { + ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret); + } + pthread_mutex_unlock(&app->sock_lock); goto rcu_error; } /* Zero the new memory */ @@ -3413,6 +3529,11 @@ int ust_app_list_events(struct lttng_event **events) tmp_event[count].enabled = -1; count++; } + ret = ustctl_release_handle(app->sock, handle); + pthread_mutex_unlock(&app->sock_lock); + if (ret < 0 && ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) { + ERR("Error releasing app handle for app %d with ret %d", app->sock, ret); + } } ret = count; @@ -3460,12 +3581,14 @@ int ust_app_list_event_fields(struct lttng_event_field **fields) */ continue; } + pthread_mutex_lock(&app->sock_lock); handle = ustctl_tracepoint_field_list(app->sock); if (handle < 0) { if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) { ERR("UST app list field getting handle failed for app pid %d", app->pid); } + pthread_mutex_unlock(&app->sock_lock); continue; } @@ -3473,6 +3596,8 @@ int ust_app_list_event_fields(struct lttng_event_field **fields) &uiter)) != -LTTNG_UST_ERR_NOENT) { /* Handle ustctl error. */ if (ret < 0) { + int release_ret; + if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) { ERR("UST app tp list field failed for app %d with ret %d", app->sock, ret); @@ -3486,6 +3611,13 @@ int ust_app_list_event_fields(struct lttng_event_field **fields) break; } free(tmp_event); + release_ret = ustctl_release_handle(app->sock, handle); + pthread_mutex_unlock(&app->sock_lock); + if (release_ret < 0 && + release_ret != -LTTNG_UST_ERR_EXITING && + release_ret != -EPIPE) { + ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret); + } goto rcu_error; } @@ -3501,9 +3633,18 @@ int ust_app_list_event_fields(struct lttng_event_field **fields) new_tmp_event = realloc(tmp_event, new_nbmem * sizeof(struct lttng_event_field)); if (new_tmp_event == NULL) { + int release_ret; + PERROR("realloc ust app event fields"); free(tmp_event); ret = -ENOMEM; + release_ret = ustctl_release_handle(app->sock, handle); + pthread_mutex_unlock(&app->sock_lock); + if (release_ret && + release_ret != -LTTNG_UST_ERR_EXITING && + release_ret != -EPIPE) { + ERR("Error releasing app handle for app %d with ret %d", app->sock, release_ret); + } goto rcu_error; } /* Zero the new memory */ @@ -3525,6 +3666,13 @@ int ust_app_list_event_fields(struct lttng_event_field **fields) tmp_event[count].event.enabled = -1; count++; } + ret = ustctl_release_handle(app->sock, handle); + pthread_mutex_unlock(&app->sock_lock); + if (ret < 0 && + ret != -LTTNG_UST_ERR_EXITING && + ret != -EPIPE) { + ERR("Error releasing app handle for app %d with ret %d", app->sock, ret); + } } ret = count; @@ -3734,7 +3882,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, { int ret = 0; struct lttng_ht_iter iter, uiter; - struct lttng_ht_node_str *ua_chan_node, *ua_event_node; + struct lttng_ht_node_str *ua_chan_node; struct ust_app *app; struct ust_app_session *ua_sess; struct ust_app_channel *ua_chan; @@ -3771,14 +3919,14 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, } ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node); - lttng_ht_lookup(ua_chan->events, (void *)uevent->attr.name, &uiter); - ua_event_node = lttng_ht_iter_get_node_str(&uiter); - if (ua_event_node == NULL) { + ua_event = find_ust_app_event(ua_chan->events, uevent->attr.name, + uevent->filter, uevent->attr.loglevel, + uevent->exclusion); + if (ua_event == NULL) { DBG2("Event %s not found in channel %s for app pid %d." "Skipping", uevent->attr.name, uchan->name, app->pid); continue; } - ua_event = caa_container_of(ua_event_node, struct ust_app_event, node); ret = disable_ust_app_event(ua_sess, ua_event, app); if (ret < 0) { @@ -4105,7 +4253,9 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) skip_setup: /* This start the UST tracing */ + pthread_mutex_lock(&app->sock_lock); ret = ustctl_start_session(app->sock, ua_sess->handle); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("Error starting tracing for app pid: %d (ret: %d)", @@ -4131,7 +4281,9 @@ skip_setup: health_code_update(); /* Quiescent wait after starting trace */ + pthread_mutex_lock(&app->sock_lock); ret = ustctl_wait_quiescent(app->sock); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app wait quiescent failed for app pid %d ret %d", app->pid, ret); @@ -4192,7 +4344,9 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) health_code_update(); /* This inhibits UST tracing */ + pthread_mutex_lock(&app->sock_lock); ret = ustctl_stop_session(app->sock, ua_sess->handle); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("Error stopping tracing for app pid: %d (ret: %d)", @@ -4212,7 +4366,9 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) health_code_update(); /* Quiescent wait after stopping trace */ + pthread_mutex_lock(&app->sock_lock); ret = ustctl_wait_quiescent(app->sock); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app wait quiescent failed for app pid %d ret %d", app->pid, ret); @@ -4410,7 +4566,9 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app) health_code_update(); /* Quiescent wait after stopping trace */ + pthread_mutex_lock(&app->sock_lock); ret = ustctl_wait_quiescent(app->sock); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app wait quiescent failed for app pid %d ret %d", app->pid, ret); @@ -4797,7 +4955,9 @@ int ust_app_calibrate_glb(struct lttng_ust_calibrate *calibrate) health_code_update(); + pthread_mutex_lock(&app->sock_lock); ret = ustctl_calibrate(app->sock, calibrate); + pthread_mutex_unlock(&app->sock_lock); if (ret < 0) { switch (ret) { case -ENOSYS: @@ -5026,8 +5186,8 @@ error_rcu_unlock: * On success 0 is returned else a negative value. */ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name, - char *sig, size_t nr_fields, struct ustctl_field *fields, int loglevel, - char *model_emf_uri) + char *sig, size_t nr_fields, struct ustctl_field *fields, + int loglevel_value, char *model_emf_uri) { int ret, ret_code; uint32_t event_id = 0; @@ -5082,9 +5242,9 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name, * three variables MUST NOT be read/write after this. */ ret_code = ust_registry_create_event(registry, chan_reg_key, - sobjd, cobjd, name, sig, nr_fields, fields, loglevel, - model_emf_uri, ua_sess->buffer_type, &event_id, - app); + sobjd, cobjd, name, sig, nr_fields, fields, + loglevel_value, model_emf_uri, ua_sess->buffer_type, + &event_id, app); /* * The return value is returned to ustctl so in case of an error, the @@ -5140,15 +5300,16 @@ int ust_app_recv_notify(int sock) switch (cmd) { case USTCTL_NOTIFY_CMD_EVENT: { - int sobjd, cobjd, loglevel; + int sobjd, cobjd, loglevel_value; char name[LTTNG_UST_SYM_NAME_LEN], *sig, *model_emf_uri; size_t nr_fields; struct ustctl_field *fields; DBG2("UST app ustctl register event received"); - ret = ustctl_recv_register_event(sock, &sobjd, &cobjd, name, &loglevel, - &sig, &nr_fields, &fields, &model_emf_uri); + ret = ustctl_recv_register_event(sock, &sobjd, &cobjd, name, + &loglevel_value, &sig, &nr_fields, &fields, + &model_emf_uri); if (ret < 0) { if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) { ERR("UST app recv event failed with ret %d", ret); @@ -5165,7 +5326,7 @@ int ust_app_recv_notify(int sock) * to the this function. */ ret = add_event_ust_registry(sock, sobjd, cobjd, name, sig, nr_fields, - fields, loglevel, model_emf_uri); + fields, loglevel_value, model_emf_uri); if (ret < 0) { goto error; }