X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=e79455b01fb055588c7473a913f583ae9e567ad3;hp=5a41c3800709ff3c2a628758ed89f01636be04f7;hb=d222983eed2efddbd4a1380e23bc3f43edfc522e;hpb=05997abc28d53778620e92f95134dfc6d5d2a0b4 diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 5a41c3800..e79455b01 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -41,6 +41,8 @@ #include "ust-ctl.h" #include "utils.h" #include "session.h" +#include "lttng-sessiond.h" +#include "notification-thread-commands.h" static int ust_app_flush_app_session(struct ust_app *app, struct ust_app_session *ua_sess); @@ -90,6 +92,7 @@ static void copy_channel_attr_to_ustctl( attr->switch_timer_interval = uattr->switch_timer_interval; attr->read_timer_interval = uattr->read_timer_interval; attr->output = uattr->output; + attr->blocking_timeout = uattr->u.s.blocking_timeout; } /* @@ -482,7 +485,8 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, /* Wipe and free registry from session registry. */ registry = get_session_registry(ua_chan->session); if (registry) { - ust_registry_channel_del_free(registry, ua_chan->key); + ust_registry_channel_del_free(registry, ua_chan->key, + true); } save_per_pid_lost_discarded_counters(ua_chan); } @@ -810,6 +814,7 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, ua_sess->deleted = true; registry = get_session_registry(ua_sess); + /* Registry can be null on error path during initialization. */ if (registry) { /* Push metadata for application before freeing the application. */ (void) push_metadata(registry, ua_sess->consumer); @@ -837,6 +842,10 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, if (ua_sess->buffer_type == LTTNG_BUFFER_PER_PID) { struct buffer_reg_pid *reg_pid = buffer_reg_pid_find(ua_sess->id); if (reg_pid) { + /* + * Registry can be null on error path during + * initialization. + */ buffer_reg_pid_remove(reg_pid); buffer_reg_pid_destroy(reg_pid); } @@ -1032,6 +1041,7 @@ struct ust_app_channel *alloc_ust_app_channel(char *name, ua_chan->attr.switch_timer_interval = attr->switch_timer_interval; ua_chan->attr.read_timer_interval = attr->read_timer_interval; ua_chan->attr.output = attr->output; + ua_chan->attr.blocking_timeout = attr->u.s.blocking_timeout; } /* By default, the channel is a per cpu channel. */ ua_chan->attr.type = LTTNG_UST_CHAN_PER_CPU; @@ -1793,7 +1803,10 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan, ua_chan->attr.overwrite = uchan->attr.overwrite; ua_chan->attr.switch_timer_interval = uchan->attr.switch_timer_interval; ua_chan->attr.read_timer_interval = uchan->attr.read_timer_interval; + ua_chan->monitor_timer_interval = uchan->monitor_timer_interval; ua_chan->attr.output = uchan->attr.output; + ua_chan->attr.blocking_timeout = uchan->attr.u.s.blocking_timeout; + /* * Note that the attribute channel type is not set since the channel on the * tracing registry side does not have this information. @@ -2352,7 +2365,7 @@ int create_ust_app_channel_context(struct ust_app_session *ua_sess, ua_ctx = alloc_ust_app_ctx(uctx); if (ua_ctx == NULL) { /* malloc failed */ - ret = -1; + ret = -ENOMEM; goto error; } @@ -2464,6 +2477,8 @@ error: /* * Ask the consumer to create a channel and get it if successful. * + * Called with UST app session lock held. + * * Return 0 on success or else a negative value. */ static int do_consumer_create_channel(struct ltt_ust_session *usess, @@ -2839,6 +2854,7 @@ static int create_channel_per_uid(struct ust_app *app, int ret; struct buffer_reg_uid *reg_uid; struct buffer_reg_channel *reg_chan; + bool created = false; assert(app); assert(usess); @@ -2882,7 +2898,7 @@ static int create_channel_per_uid(struct ust_app *app, * it's not visible anymore in the session registry. */ ust_registry_channel_del_free(reg_uid->registry->reg.ust, - ua_chan->tracing_channel_id); + ua_chan->tracing_channel_id, false); buffer_reg_channel_remove(reg_uid->registry, reg_chan); buffer_reg_channel_destroy(reg_chan, LTTNG_DOMAIN_UST); goto error; @@ -2898,7 +2914,7 @@ static int create_channel_per_uid(struct ust_app *app, ua_chan->name); goto error; } - + created = true; } /* Send buffers to the application. */ @@ -2910,6 +2926,41 @@ static int create_channel_per_uid(struct ust_app *app, goto error; } + if (created) { + enum lttng_error_code cmd_ret; + struct ltt_session *session; + uint64_t chan_reg_key; + struct ust_registry_channel *chan_reg; + + rcu_read_lock(); + chan_reg_key = ua_chan->tracing_channel_id; + + pthread_mutex_lock(®_uid->registry->reg.ust->lock); + chan_reg = ust_registry_channel_find(reg_uid->registry->reg.ust, + chan_reg_key); + assert(chan_reg); + chan_reg->consumer_key = ua_chan->key; + chan_reg = NULL; + pthread_mutex_unlock(®_uid->registry->reg.ust->lock); + + session = session_find_by_id(ua_sess->tracing_id); + assert(session); + + cmd_ret = notification_thread_command_add_channel( + notification_thread_handle, session->name, + ua_sess->euid, ua_sess->egid, + ua_chan->name, + ua_chan->key, + LTTNG_DOMAIN_UST, + ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf); + rcu_read_unlock(); + if (cmd_ret != LTTNG_OK) { + ret = - (int) cmd_ret; + ERR("Failed to add channel to notification thread"); + goto error; + } + } + error: return ret; } @@ -2917,6 +2968,8 @@ error: /* * Create and send to the application the created buffers with per PID buffers. * + * Called with UST app session lock held. + * * Return 0 on success else a negative value. */ static int create_channel_per_pid(struct ust_app *app, @@ -2925,6 +2978,10 @@ static int create_channel_per_pid(struct ust_app *app, { int ret; struct ust_registry_session *registry; + enum lttng_error_code cmd_ret; + struct ltt_session *session; + uint64_t chan_reg_key; + struct ust_registry_channel *chan_reg; assert(app); assert(usess); @@ -2936,6 +2993,7 @@ static int create_channel_per_pid(struct ust_app *app, rcu_read_lock(); registry = get_session_registry(ua_sess); + /* The UST app session lock is held, registry shall not be null. */ assert(registry); /* Create and add a new channel registry to session. */ @@ -2963,6 +3021,29 @@ static int create_channel_per_pid(struct ust_app *app, goto error; } + session = session_find_by_id(ua_sess->tracing_id); + assert(session); + + chan_reg_key = ua_chan->key; + pthread_mutex_lock(®istry->lock); + chan_reg = ust_registry_channel_find(registry, chan_reg_key); + assert(chan_reg); + chan_reg->consumer_key = ua_chan->key; + pthread_mutex_unlock(®istry->lock); + + cmd_ret = notification_thread_command_add_channel( + notification_thread_handle, session->name, + ua_sess->euid, ua_sess->egid, + ua_chan->name, + ua_chan->key, + LTTNG_DOMAIN_UST, + ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf); + if (cmd_ret != LTTNG_OK) { + ret = - (int) cmd_ret; + ERR("Failed to add channel to notification thread"); + goto error; + } + error: rcu_read_unlock(); return ret; @@ -2973,6 +3054,8 @@ error: * need and send it to the application. This MUST be called with a RCU read * side lock acquired. * + * Called with UST app session lock held. + * * Return 0 on success or else a negative value. Returns -ENOTCONN if * the application exited concurrently. */ @@ -3075,7 +3158,6 @@ static int create_ust_app_channel(struct ust_app_session *ua_sess, /* Only add the channel if successful on the tracer side. */ lttng_ht_add_unique_str(ua_sess->channels, &ua_chan->node); - end: if (ua_chanp) { *ua_chanp = ua_chan; @@ -3160,6 +3242,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess, assert(consumer); registry = get_session_registry(ua_sess); + /* The UST app session is held registry shall not be null. */ assert(registry); pthread_mutex_lock(®istry->lock); @@ -4296,6 +4379,9 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess, /* * Start tracing for a specific UST session and app. + * + * Called with UST app session lock held. + * */ static int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) @@ -4479,6 +4565,8 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) health_code_update(); registry = get_session_registry(ua_sess); + + /* The UST app session is held registry shall not be null. */ assert(registry); /* Push metadata for application before freeing the application. */ @@ -5320,19 +5408,17 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd, /* Lookup application. If not found, there is a code flow error. */ app = find_app_by_notify_sock(sock); if (!app) { - DBG("Application socket %d is being teardown. Abort event notify", + DBG("Application socket %d is being torn down. Abort event notify", sock); ret = 0; - free(fields); goto error_rcu_unlock; } /* Lookup channel by UST object descriptor. */ ua_chan = find_channel_by_objd(app, cobjd); if (!ua_chan) { - DBG("Application channel is being teardown. Abort event notify"); + DBG("Application channel is being torn down. Abort event notify"); ret = 0; - free(fields); goto error_rcu_unlock; } @@ -5341,7 +5427,11 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd, /* Get right session registry depending on the session buffer type. */ registry = get_session_registry(ua_sess); - assert(registry); + if (!registry) { + DBG("Application session is being torn down. Abort event notify"); + ret = 0; + goto error_rcu_unlock; + }; /* Depending on the buffer type, a different channel key is used. */ if (ua_sess->buffer_type == LTTNG_BUFFER_PER_UID) { @@ -5365,13 +5455,11 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd, chan_reg->nr_ctx_fields = nr_fields; chan_reg->ctx_fields = fields; + fields = NULL; chan_reg->header_type = type; } else { /* Get current already assigned values. */ type = chan_reg->header_type; - free(fields); - /* Set to NULL so the error path does not do a double free. */ - fields = NULL; } /* Channel id is set during the object creation. */ chan_id = chan_reg->chan_id; @@ -5407,9 +5495,7 @@ error: pthread_mutex_unlock(®istry->lock); error_rcu_unlock: rcu_read_unlock(); - if (ret) { - free(fields); - } + free(fields); return ret; } @@ -5439,23 +5525,17 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name, /* Lookup application. If not found, there is a code flow error. */ app = find_app_by_notify_sock(sock); if (!app) { - DBG("Application socket %d is being teardown. Abort event notify", + DBG("Application socket %d is being torn down. Abort event notify", sock); ret = 0; - free(sig); - free(fields); - free(model_emf_uri); goto error_rcu_unlock; } /* Lookup channel by UST object descriptor. */ ua_chan = find_channel_by_objd(app, cobjd); if (!ua_chan) { - DBG("Application channel is being teardown. Abort event notify"); + DBG("Application channel is being torn down. Abort event notify"); ret = 0; - free(sig); - free(fields); - free(model_emf_uri); goto error_rcu_unlock; } @@ -5463,7 +5543,11 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name, ua_sess = ua_chan->session; registry = get_session_registry(ua_sess); - assert(registry); + if (!registry) { + DBG("Application session is being torn down. Abort event notify"); + ret = 0; + goto error_rcu_unlock; + } if (ua_sess->buffer_type == LTTNG_BUFFER_PER_UID) { chan_reg_key = ua_chan->tracing_channel_id; @@ -5482,6 +5566,9 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name, sobjd, cobjd, name, sig, nr_fields, fields, loglevel_value, model_emf_uri, ua_sess->buffer_type, &event_id, app); + sig = NULL; + fields = NULL; + model_emf_uri = NULL; /* * The return value is returned to ustctl so in case of an error, the @@ -5509,6 +5596,9 @@ error: pthread_mutex_unlock(®istry->lock); error_rcu_unlock: rcu_read_unlock(); + free(sig); + free(fields); + free(model_emf_uri); return ret; } @@ -5545,13 +5635,17 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name, ua_sess = find_session_by_objd(app, sobjd); if (!ua_sess) { /* Return an error since this is not an error */ - DBG("Application session is being torn down. Aborting enum registration."); + DBG("Application session is being torn down (session not found). Aborting enum registration."); free(entries); goto error_rcu_unlock; } registry = get_session_registry(ua_sess); - assert(registry); + if (!registry) { + DBG("Application session is being torn down (registry not found). Aborting enum registration."); + free(entries); + goto error_rcu_unlock; + } pthread_mutex_lock(®istry->lock); @@ -5917,7 +6011,11 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, } registry = get_session_registry(ua_sess); - assert(registry); + if (!registry) { + DBG("Application session is being torn down. Abort snapshot record."); + ret = -1; + goto error; + } ret = consumer_snapshot_channel(socket, registry->metadata_key, output, 1, ua_sess->euid, ua_sess->egid, pathname, wait, 0); if (ret < 0) { @@ -6017,21 +6115,24 @@ int ust_app_uid_get_channel_runtime_stats(uint64_t ust_session_id, int ret; uint64_t consumer_chan_key; + *discarded = 0; + *lost = 0; + ret = buffer_reg_uid_consumer_channel_key( buffer_reg_uid_list, ust_session_id, uchan_id, &consumer_chan_key); if (ret < 0) { + /* Not found */ + ret = 0; goto end; } if (overwrite) { ret = consumer_get_lost_packets(ust_session_id, consumer_chan_key, consumer, lost); - *discarded = 0; } else { ret = consumer_get_discarded_events(ust_session_id, consumer_chan_key, consumer, discarded); - *lost = 0; } end: @@ -6050,10 +6151,13 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess, struct ust_app_session *ua_sess; struct ust_app_channel *ua_chan; + *discarded = 0; + *lost = 0; + rcu_read_lock(); /* - * Iterate over every registered applications, return when we - * found one in the right session and channel. + * Iterate over every registered applications. Sum counters for + * all applications containing requested session and channel. */ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { struct lttng_ht_iter uiter; @@ -6072,19 +6176,26 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess, ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node); if (overwrite) { + uint64_t _lost; + ret = consumer_get_lost_packets(usess->id, ua_chan->key, - consumer, lost); - *discarded = 0; - goto end; + consumer, &_lost); + if (ret < 0) { + break; + } + (*lost) += _lost; } else { + uint64_t _discarded; + ret = consumer_get_discarded_events(usess->id, - ua_chan->key, consumer, discarded); - *lost = 0; - goto end; + ua_chan->key, consumer, &_discarded); + if (ret < 0) { + break; + } + (*discarded) += _discarded; } } -end: rcu_read_unlock(); return ret; }