X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=58308dec801f0bef53dedada426ba7bd574e51e8;hp=56860d714e3a6e5a605e75c56a1fb200037fd1bb;hb=495dece518e24e6c8563c588be77b5e23e060a02;hpb=3b9677124ab48bddc945ca67947c49b87b5853e0 diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 56860d714..58308dec8 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -38,7 +37,8 @@ #include "health-sessiond.h" #include "ust-app.h" #include "ust-consumer.h" -#include "ust-ctl.h" +#include "lttng-ust-ctl.h" +#include "lttng-ust-error.h" #include "utils.h" #include "session.h" #include "lttng-sessiond.h" @@ -741,6 +741,10 @@ error: * nullified. The session lock MUST be held unless the application is * in the destroy path. * + * Do not hold the registry lock while communicating with the consumerd, because + * doing so causes inter-process deadlocks between consumerd and sessiond with + * the metadata request notification. + * * Return 0 on success else a negative value. */ static int close_metadata(struct ust_registry_session *registry, @@ -748,6 +752,8 @@ static int close_metadata(struct ust_registry_session *registry, { int ret; struct consumer_socket *socket; + uint64_t metadata_key; + bool registry_was_already_closed; assert(registry); assert(consumer); @@ -755,8 +761,19 @@ static int close_metadata(struct ust_registry_session *registry, rcu_read_lock(); pthread_mutex_lock(®istry->lock); + metadata_key = registry->metadata_key; + registry_was_already_closed = registry->metadata_closed; + if (metadata_key != 0) { + /* + * Metadata closed. Even on error this means that the consumer + * is not responding or not found so either way a second close + * should NOT be emit for this registry. + */ + registry->metadata_closed = 1; + } + pthread_mutex_unlock(®istry->lock); - if (!registry->metadata_key || registry->metadata_closed) { + if (metadata_key == 0 || registry_was_already_closed) { ret = 0; goto end; } @@ -766,23 +783,15 @@ static int close_metadata(struct ust_registry_session *registry, consumer); if (!socket) { ret = -1; - goto error; + goto end; } - ret = consumer_close_metadata(socket, registry->metadata_key); + ret = consumer_close_metadata(socket, metadata_key); if (ret < 0) { - goto error; + goto end; } -error: - /* - * Metadata closed. Even on error this means that the consumer is not - * responding or not found so either way a second close should NOT be emit - * for this registry. - */ - registry->metadata_closed = 1; end: - pthread_mutex_unlock(®istry->lock); rcu_read_unlock(); return ret; } @@ -1100,7 +1109,7 @@ struct ust_app_event *alloc_ust_app_event(char *name, /* Init most of the default value by allocating and zeroing */ ua_event = zmalloc(sizeof(struct ust_app_event)); if (ua_event == NULL) { - PERROR("malloc"); + PERROR("Failed to allocate ust_app_event structure"); goto error; } @@ -1993,7 +2002,8 @@ static int setup_buffer_reg_pid(struct ust_app_session *ua_sess, app->byte_order, app->version.major, app->version.minor, reg_pid->root_shm_path, reg_pid->shm_path, ua_sess->effective_credentials.uid, - ua_sess->effective_credentials.gid); + ua_sess->effective_credentials.gid, ua_sess->tracing_id, + app->uid); if (ret < 0) { /* * reg_pid->registry->reg.ust is NULL upon error, so we need to @@ -2060,7 +2070,8 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess, app->uint64_t_alignment, app->long_alignment, app->byte_order, app->version.major, app->version.minor, reg_uid->root_shm_path, - reg_uid->shm_path, usess->uid, usess->gid); + reg_uid->shm_path, usess->uid, usess->gid, + ua_sess->tracing_id, app->uid); if (ret < 0) { /* * reg_uid->registry->reg.ust is NULL upon error, so we need to @@ -3131,7 +3142,7 @@ int create_ust_app_event(struct ust_app_session *ua_sess, ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr); if (ua_event == NULL) { - /* Only malloc can failed so something is really wrong */ + /* Only failure mode of alloc_ust_app_event(). */ ret = -ENOMEM; goto end; } @@ -3140,8 +3151,19 @@ int create_ust_app_event(struct ust_app_session *ua_sess, /* Create it on the tracer side */ ret = create_ust_event(app, ua_sess, ua_chan, ua_event); if (ret < 0) { - /* Not found previously means that it does not exist on the tracer */ - assert(ret != -LTTNG_UST_ERR_EXIST); + /* + * Not found previously means that it does not exist on the + * tracer. If the application reports that the event existed, + * it means there is a bug in the sessiond or lttng-ust + * (or corruption, etc.) + */ + if (ret == -LTTNG_UST_ERR_EXIST) { + ERR("Tracer for application reported that an event being created already existed: " + "event_name = \"%s\", pid = %d, ppid = %d, uid = %d, gid = %d", + uevent->attr.name, + app->pid, app->ppid, app->uid, + app->gid); + } goto error; } @@ -4199,7 +4221,7 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, if (session_was_created) { destroy_app_session(app, ua_sess); } - goto error_rcu_unlock; + /* Continue to the next application. */ } } @@ -4411,7 +4433,7 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) health_code_update(); skip_setup: - /* This start the UST tracing */ + /* This starts the UST tracing */ pthread_mutex_lock(&app->sock_lock); ret = ustctl_start_session(app->sock, ua_sess->handle); pthread_mutex_unlock(&app->sock_lock); @@ -5883,6 +5905,7 @@ enum lttng_error_code ust_app_snapshot_record( enum lttng_error_code status = LTTNG_OK; struct lttng_ht_iter iter; struct ust_app *app; + char *trace_path = NULL; assert(usess); assert(output); @@ -5897,7 +5920,6 @@ enum lttng_error_code ust_app_snapshot_record( cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { struct buffer_reg_channel *reg_chan; struct consumer_socket *socket; - char *trace_path = NULL; char pathname[PATH_MAX]; if (!reg->registry->reg.ust->metadata_key) { @@ -5926,6 +5948,8 @@ enum lttng_error_code ust_app_snapshot_record( status = LTTNG_ERR_INVALID; goto error; } + /* Free path allowed on previous iteration. */ + free(trace_path); trace_path = setup_channel_trace_path(usess->consumer, pathname); if (!trace_path) { status = LTTNG_ERR_INVALID; @@ -5940,14 +5964,12 @@ enum lttng_error_code ust_app_snapshot_record( usess->gid, trace_path, wait, nb_packets_per_stream); if (status != LTTNG_OK) { - free(trace_path); goto error; } } status = consumer_snapshot_channel(socket, reg->registry->reg.ust->metadata_key, output, 1, usess->uid, usess->gid, trace_path, wait, 0); - free(trace_path); if (status != LTTNG_OK) { goto error; } @@ -5962,7 +5984,6 @@ enum lttng_error_code ust_app_snapshot_record( struct ust_app_channel *ua_chan; struct ust_app_session *ua_sess; struct ust_registry_session *registry; - char *trace_path = NULL; char pathname[PATH_MAX]; ua_sess = lookup_session_by_app(usess, app); @@ -5988,6 +6009,8 @@ enum lttng_error_code ust_app_snapshot_record( PERROR("snprintf snapshot path"); goto error; } + /* Free path allowed on previous iteration. */ + free(trace_path); trace_path = setup_channel_trace_path(usess->consumer, pathname); if (!trace_path) { status = LTTNG_ERR_INVALID; @@ -6007,10 +6030,8 @@ enum lttng_error_code ust_app_snapshot_record( case LTTNG_OK: break; case LTTNG_ERR_CHAN_NOT_FOUND: - free(trace_path); continue; default: - free(trace_path); goto error; } } @@ -6025,7 +6046,6 @@ enum lttng_error_code ust_app_snapshot_record( ua_sess->effective_credentials.uid, ua_sess->effective_credentials.gid, trace_path, wait, 0); - free(trace_path); switch (status) { case LTTNG_OK: break; @@ -6043,6 +6063,7 @@ enum lttng_error_code ust_app_snapshot_record( } error: + free(trace_path); rcu_read_unlock(); return status; } @@ -6465,6 +6486,17 @@ enum lttng_error_code ust_app_create_channel_subdirectories( { struct ust_app *app; + /* + * Create the toplevel ust/ directory in case no apps are running. + */ + chunk_status = lttng_trace_chunk_create_subdirectory( + usess->current_trace_chunk, + DEFAULT_UST_TRACE_DIR); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + ret = LTTNG_ERR_CREATE_DIR_FAIL; + goto error; + } + cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { struct ust_app_session *ua_sess;