X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=0b0a62532125e6bc7ecd4a72728f1b8e997a18ba;hb=58d3fed5a62a82ce8487dce41a3092e79a9bca15;hp=ad6bc09f74cac51c2ab1ce349779d5f26d17b740;hpb=61539f9685f7786bc6fe8d23a7c1cef4fa716b7c;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index ad6bc09f7..0b0a62532 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -437,6 +437,9 @@ void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan) end: rcu_read_unlock(); + if (session) { + session_put(session); + } } /* @@ -487,9 +490,16 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, registry = get_session_registry(ua_chan->session); if (registry) { ust_registry_channel_del_free(registry, ua_chan->key, - true); + sock >= 0); + } + /* + * A negative socket can be used by the caller when + * cleaning-up a ua_chan in an error path. Skip the + * accounting in this case. + */ + if (sock >= 0) { + save_per_pid_lost_discarded_counters(ua_chan); } - save_per_pid_lost_discarded_counters(ua_chan); } if (ua_chan->obj != NULL) { @@ -2858,7 +2868,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; - struct ltt_session *session; + struct ltt_session *session = NULL; enum lttng_error_code notification_ret; struct ust_registry_channel *chan_reg; @@ -2961,6 +2971,9 @@ send_channel: } error: + if (session) { + session_put(session); + } return ret; } @@ -2979,7 +2992,7 @@ 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; + struct ltt_session *session = NULL; uint64_t chan_reg_key; struct ust_registry_channel *chan_reg; @@ -3017,7 +3030,7 @@ static int create_channel_per_pid(struct ust_app *app, if (ret < 0) { ERR("Error creating UST channel \"%s\" on the consumer daemon", ua_chan->name); - goto error; + goto error_remove_from_registry; } ret = send_channel_pid_to_ust(app, ua_sess, ua_chan); @@ -3025,7 +3038,7 @@ static int create_channel_per_pid(struct ust_app *app, if (ret != -ENOTCONN) { ERR("Error sending channel to application"); } - goto error; + goto error_remove_from_registry; } chan_reg_key = ua_chan->key; @@ -3045,11 +3058,18 @@ static int create_channel_per_pid(struct ust_app *app, if (cmd_ret != LTTNG_OK) { ret = - (int) cmd_ret; ERR("Failed to add channel to notification thread"); - goto error; + goto error_remove_from_registry; } +error_remove_from_registry: + if (ret) { + ust_registry_channel_del_free(registry, ua_chan->key, false); + } error: rcu_read_unlock(); + if (session) { + session_put(session); + } return ret; } @@ -3240,7 +3260,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess, struct ust_app_channel *metadata; struct consumer_socket *socket; struct ust_registry_session *registry; - struct ltt_session *session; + struct ltt_session *session = NULL; assert(ua_sess); assert(app); @@ -3331,6 +3351,9 @@ error_consumer: delete_ust_app_channel(-1, metadata, app); error: pthread_mutex_unlock(®istry->lock); + if (session) { + session_put(session); + } return ret; } @@ -3898,6 +3921,24 @@ void ust_app_clean_list(void) rcu_read_lock(); + /* Cleanup notify socket hash table */ + if (ust_app_ht_by_notify_sock) { + cds_lfht_for_each_entry(ust_app_ht_by_notify_sock->ht, &iter.iter, app, + notify_sock_n.node) { + struct cds_lfht_node *node; + struct ust_app *app; + + node = cds_lfht_iter_get_node(&iter.iter); + if (!node) { + continue; + } + + app = container_of(node, struct ust_app, + notify_sock_n.node); + ust_app_notify_sock_unregister(app->notify_sock); + } + } + if (ust_app_ht) { cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { ret = lttng_ht_del(ust_app_ht, &iter); @@ -3915,14 +3956,6 @@ void ust_app_clean_list(void) } } - /* Cleanup notify socket hash table */ - if (ust_app_ht_by_notify_sock) { - cds_lfht_for_each_entry(ust_app_ht_by_notify_sock->ht, &iter.iter, app, - notify_sock_n.node) { - ret = lttng_ht_del(ust_app_ht_by_notify_sock, &iter); - assert(!ret); - } - } rcu_read_unlock(); /* Destroy is done only when the ht is empty */ @@ -3979,6 +4012,10 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, DBG2("UST app disabling channel %s from global domain for session id %" PRIu64, uchan->name, usess->id); + if (!usess->active) { + goto end; + } + rcu_read_lock(); /* For every registered applications */ @@ -4017,6 +4054,7 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, rcu_read_unlock(); error: +end: return ret; } @@ -4040,6 +4078,10 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess, DBG2("UST app enabling channel %s to global domain for session id %" PRIu64, uchan->name, usess->id); + if (!usess->active) { + goto end; + } + rcu_read_lock(); /* For every registered applications */ @@ -4067,6 +4109,7 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess, rcu_read_unlock(); error: +end: return ret; } @@ -4088,6 +4131,10 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, "%s for session id %" PRIu64, uevent->attr.name, uchan->name, usess->id); + if (!usess->active) { + goto end; + } + rcu_read_lock(); /* For all registered applications */ @@ -4132,7 +4179,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, } rcu_read_unlock(); - +end: return ret; } @@ -4154,6 +4201,10 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, DBG2("UST app adding channel %s to UST domain for session id %" PRIu64, uchan->name, usess->id); + if (!usess->active) { + goto end; + } + rcu_read_lock(); /* For every registered applications */ @@ -4233,6 +4284,7 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, error_rcu_unlock: rcu_read_unlock(); +end: return ret; } @@ -4253,6 +4305,10 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess, DBG("UST app enabling event %s for all apps for session id %" PRIu64, uevent->attr.name, usess->id); + if (!usess->active) { + goto end; + } + /* * NOTE: At this point, this function is called only if the session and * channel passed are already created for all apps. and enabled on the @@ -4318,6 +4374,7 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess, error: rcu_read_unlock(); +end: return ret; } @@ -4338,6 +4395,10 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess, DBG("UST app creating event %s for all apps for session id %" PRIu64, uevent->attr.name, usess->id); + if (!usess->active) { + goto end; + } + rcu_read_lock(); /* For all registered applications */ @@ -4384,7 +4445,7 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess, } rcu_read_unlock(); - +end: return ret; } @@ -4963,6 +5024,12 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess) DBG("Starting all UST traces"); + /* + * Even though the start trace might fail, flag this session active so + * other application coming in are started by default. + */ + usess->active = 1; + rcu_read_lock(); /* @@ -4973,6 +5040,10 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess) */ (void) ust_app_clear_quiescent_session(usess); + cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { + ust_app_global_update(usess, app); + } + cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { ret = ust_app_start_trace(usess, app); if (ret < 0) { @@ -4998,6 +5069,12 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess) DBG("Stopping all UST traces"); + /* + * Even though the stop trace might fail, flag this session inactive so + * other application coming in are not started by default. + */ + usess->active = 0; + rcu_read_lock(); cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { @@ -5061,6 +5138,9 @@ void ust_app_global_create(struct ltt_ust_session *usess, struct ust_app *app) /* App session already created. */ goto end; } + if (!usess->active) { + goto end; + } assert(ua_sess); pthread_mutex_lock(&ua_sess->lock); @@ -5114,14 +5194,12 @@ void ust_app_global_create(struct ltt_ust_session *usess, struct ust_app *app) pthread_mutex_unlock(&ua_sess->lock); - if (usess->active) { - ret = ust_app_start_trace(usess, app); - if (ret < 0) { - goto error; - } - - DBG2("UST trace started for app pid %d", app->pid); + ret = ust_app_start_trace(usess, app); + if (ret < 0) { + goto error; } + + DBG2("UST trace started for app pid %d", app->pid); end: /* Everything went well at this point. */ return; @@ -5163,7 +5241,9 @@ void ust_app_global_update(struct ltt_ust_session *usess, struct ust_app *app) if (!app->compatible) { return; } - + if (!usess->active) { + return; + } if (trace_ust_pid_tracker_lookup(usess, app->pid)) { ust_app_global_create(usess, app); } else { @@ -5179,6 +5259,9 @@ void ust_app_global_update_all(struct ltt_ust_session *usess) struct lttng_ht_iter iter; struct ust_app *app; + if (!usess->active) { + return; + } rcu_read_lock(); cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { ust_app_global_update(usess, app); @@ -5199,6 +5282,10 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, struct ust_app_session *ua_sess; struct ust_app *app; + if (!usess->active) { + goto end; + } + rcu_read_lock(); cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { @@ -5238,6 +5325,7 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, } rcu_read_unlock(); +end: return ret; } @@ -5941,17 +6029,18 @@ void ust_app_destroy(struct ust_app *app) * Take a snapshot for a given UST session. The snapshot is sent to the given * output. * - * Return 0 on success or else a negative value. + * Returns LTTNG_OK on success or a LTTNG_ERR error code. */ -int ust_app_snapshot_record(struct ltt_ust_session *usess, +enum lttng_error_code ust_app_snapshot_record(struct ltt_ust_session *usess, struct snapshot_output *output, int wait, uint64_t nb_packets_per_stream) { int ret = 0; + enum lttng_error_code status = LTTNG_OK; struct lttng_ht_iter iter; struct ust_app *app; char pathname[PATH_MAX]; - struct ltt_session *session; + struct ltt_session *session = NULL; uint64_t trace_archive_id; assert(usess); @@ -5983,7 +6072,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, socket = consumer_find_socket_by_bitness(reg->bits_per_long, usess->consumer); if (!socket) { - ret = -EINVAL; + status = LTTNG_ERR_INVALID; goto error; } @@ -5993,27 +6082,28 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, reg->uid, reg->bits_per_long); if (ret < 0) { PERROR("snprintf snapshot path"); + status = LTTNG_ERR_INVALID; goto error; } /* Add the UST default trace dir to path. */ cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, reg_chan, node.node) { - ret = consumer_snapshot_channel(socket, + status = consumer_snapshot_channel(socket, reg_chan->consumer_key, output, 0, usess->uid, usess->gid, pathname, wait, nb_packets_per_stream, trace_archive_id); - if (ret < 0) { + if (status != LTTNG_OK) { goto error; } } - ret = consumer_snapshot_channel(socket, + status = consumer_snapshot_channel(socket, reg->registry->reg.ust->metadata_key, output, 1, usess->uid, usess->gid, pathname, wait, 0, trace_archive_id); - if (ret < 0) { + if (status != LTTNG_OK) { goto error; } } @@ -6038,7 +6128,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, socket = consumer_find_socket_by_bitness(app->bits_per_long, output->consumer); if (!socket) { - ret = -EINVAL; + status = LTTNG_ERR_INVALID; goto error; } @@ -6047,35 +6137,45 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, ret = snprintf(pathname, sizeof(pathname), DEFAULT_UST_TRACE_DIR "/%s", ua_sess->path); if (ret < 0) { + status = LTTNG_ERR_INVALID; PERROR("snprintf snapshot path"); goto error; } cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) { - ret = consumer_snapshot_channel(socket, + status = consumer_snapshot_channel(socket, ua_chan->key, output, 0, ua_sess->euid, ua_sess->egid, pathname, wait, nb_packets_per_stream, trace_archive_id); - if (ret < 0) { + switch (status) { + case LTTNG_OK: + break; + case LTTNG_ERR_CHAN_NOT_FOUND: + continue; + default: goto error; } } registry = get_session_registry(ua_sess); if (!registry) { - DBG("Application session is being torn down. Abort snapshot record."); - ret = -1; - goto error; + DBG("Application session is being torn down. Skip application."); + continue; } - ret = consumer_snapshot_channel(socket, + status = consumer_snapshot_channel(socket, registry->metadata_key, output, 1, ua_sess->euid, ua_sess->egid, pathname, wait, 0, trace_archive_id); - if (ret < 0) { + switch (status) { + case LTTNG_OK: + break; + case LTTNG_ERR_CHAN_NOT_FOUND: + continue; + default: goto error; } } @@ -6088,7 +6188,10 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, error: rcu_read_unlock(); - return ret; + if (session) { + session_put(session); + } + return status; } /* @@ -6325,11 +6428,12 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess) /* * Rotate all the channels of a session. * - * Return 0 on success or else a negative value. + * Return LTTNG_OK on success or else an LTTng error code. */ -int ust_app_rotate_session(struct ltt_session *session) +enum lttng_error_code ust_app_rotate_session(struct ltt_session *session) { - int ret = 0; + int ret; + enum lttng_error_code cmd_ret = LTTNG_OK; struct lttng_ht_iter iter; struct ust_app *app; struct ltt_ust_session *usess = session->ust_session; @@ -6352,7 +6456,7 @@ int ust_app_rotate_session(struct ltt_session *session) socket = consumer_find_socket_by_bitness(reg->bits_per_long, usess->consumer); if (!socket) { - ret = -EINVAL; + cmd_ret = LTTNG_ERR_INVALID; goto error; } @@ -6361,6 +6465,7 @@ int ust_app_rotate_session(struct ltt_session *session) reg->uid, reg->bits_per_long); if (ret < 0 || ret == sizeof(pathname)) { PERROR("Failed to format rotation path"); + cmd_ret = LTTNG_ERR_INVALID; goto error; } @@ -6374,6 +6479,7 @@ int ust_app_rotate_session(struct ltt_session *session) /* is_metadata_channel */ false, session->current_archive_id); if (ret < 0) { + cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER; goto error; } } @@ -6387,6 +6493,7 @@ int ust_app_rotate_session(struct ltt_session *session) /* is_metadata_channel */ true, session->current_archive_id); if (ret < 0) { + cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER; goto error; } } @@ -6411,6 +6518,7 @@ int ust_app_rotate_session(struct ltt_session *session) ua_sess->path); if (ret < 0 || ret == sizeof(pathname)) { PERROR("Failed to format rotation path"); + cmd_ret = LTTNG_ERR_INVALID; goto error; } @@ -6418,15 +6526,14 @@ int ust_app_rotate_session(struct ltt_session *session) socket = consumer_find_socket_by_bitness(app->bits_per_long, usess->consumer); if (!socket) { - ret = -EINVAL; + cmd_ret = LTTNG_ERR_INVALID; goto error; } registry = get_session_registry(ua_sess); if (!registry) { - DBG("Application session is being torn down. Abort session rotation."); - ret = -1; - goto error; + DBG("Application session is being torn down. Skip application."); + continue; } @@ -6439,6 +6546,10 @@ int ust_app_rotate_session(struct ltt_session *session) /* is_metadata_channel */ false, session->current_archive_id); if (ret < 0) { + /* Per-PID buffer and application going away. */ + if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) + continue; + cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER; goto error; } } @@ -6451,6 +6562,10 @@ int ust_app_rotate_session(struct ltt_session *session) /* is_metadata_channel */ true, session->current_archive_id); if (ret < 0) { + /* Per-PID buffer and application going away. */ + if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) + continue; + cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER; goto error; } } @@ -6461,9 +6576,9 @@ int ust_app_rotate_session(struct ltt_session *session) break; } - ret = LTTNG_OK; + cmd_ret = LTTNG_OK; error: rcu_read_unlock(); - return ret; + return cmd_ret; }