X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=70a647608a3f8881e36a9e22b004ef66cdbc35dd;hb=cd2b09ed75c28ef5e82698972582c99e6b423134;hp=ec6f998bb7a87e6a6d2cc957a26cf753381c3c66;hpb=c4a1715b6c7b500eac97e149b3994a877f3023bb;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index ec6f998bb..70a647608 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -256,8 +256,7 @@ static void delete_ust_app(struct ust_app *app) { int ret, sock; - struct lttng_ht_iter iter; - struct ust_app_session *ua_sess; + struct ust_app_session *ua_sess, *tmp_ua_sess; rcu_read_lock(); @@ -265,17 +264,14 @@ void delete_ust_app(struct ust_app *app) sock = app->sock; app->sock = -1; + lttng_ht_destroy(app->sessions); + /* Wipe sessions */ - cds_lfht_for_each_entry(app->sessions->ht, &iter.iter, ua_sess, - node.node) { - ret = lttng_ht_del(app->sessions, &iter); - if (ret) { - /* The session is already scheduled for teardown. */ - continue; - } - delete_ust_app_session(app->sock, ua_sess); + cds_list_for_each_entry_safe(ua_sess, tmp_ua_sess, &app->teardown_head, + teardown_node) { + /* Free every object in the session and the session. */ + delete_ust_app_session(sock, ua_sess); } - lttng_ht_destroy(app->sessions); /* * Wait until we have deleted the application from the sock hash table @@ -1216,11 +1212,12 @@ error: } /* - * Create UST app channel and create it on the tracer. + * Create UST app channel and create it on the tracer. Set ua_chanp of the + * newly created channel if not NULL. */ -static struct ust_app_channel *create_ust_app_channel( - struct ust_app_session *ua_sess, struct ltt_ust_channel *uchan, - struct ust_app *app) +static int create_ust_app_channel(struct ust_app_session *ua_sess, + struct ltt_ust_channel *uchan, struct ust_app *app, + struct ust_app_channel **ua_chanp) { int ret = 0; struct lttng_ht_iter iter; @@ -1238,6 +1235,7 @@ static struct ust_app_channel *create_ust_app_channel( ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr); if (ua_chan == NULL) { /* Only malloc can fail here */ + ret = -ENOMEM; goto error; } shadow_copy_channel(ua_chan, uchan); @@ -1249,17 +1247,23 @@ static struct ust_app_channel *create_ust_app_channel( goto error; } + /* Only add the channel if successful on the tracer side. */ lttng_ht_add_unique_str(ua_sess->channels, &ua_chan->node); DBG2("UST app create channel %s for PID %d completed", ua_chan->name, app->pid); end: - return ua_chan; + if (ua_chanp) { + *ua_chanp = ua_chan; + } + + /* Everything went well. */ + return 0; error: delete_ust_app_channel(-1, ua_chan); - return NULL; + return ret; } /* @@ -1465,6 +1469,8 @@ int ust_app_register(struct ust_register_msg *msg, int sock) lta->sock = sock; lttng_ht_node_init_ulong(<a->sock_n, (unsigned long)lta->sock); + CDS_INIT_LIST_HEAD(<a->teardown_head); + rcu_read_lock(); /* @@ -1500,6 +1506,7 @@ void ust_app_unregister(int sock) struct ust_app *lta; struct lttng_ht_node_ulong *node; struct lttng_ht_iter iter; + struct ust_app_session *ua_sess; int ret; rcu_read_lock(); @@ -1534,6 +1541,22 @@ void ust_app_unregister(int sock) lta->pid); } + /* Remove sessions so they are not visible during deletion.*/ + cds_lfht_for_each_entry(lta->sessions->ht, &iter.iter, ua_sess, + node.node) { + ret = lttng_ht_del(lta->sessions, &iter); + if (ret) { + /* The session was already removed so scheduled for teardown. */ + continue; + } + + /* + * Add session to list for teardown. This is safe since at this point we + * are the only one using this list. + */ + cds_list_add(&ua_sess->teardown_node, <a->teardown_head); + } + /* Free memory */ call_rcu(<a->pid_n.head, delete_ust_app_rcu); @@ -2006,7 +2029,6 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, struct lttng_ht_iter iter; struct ust_app *app; struct ust_app_session *ua_sess; - struct ust_app_channel *ua_chan; /* Very wrong code flow */ assert(usess); @@ -2034,26 +2056,27 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, ua_sess = create_ust_app_session(usess, app); if (ua_sess == NULL) { /* The malloc() failed. */ - ret = -1; - goto error; + ret = -ENOMEM; + goto error_rcu_unlock; } else if (ua_sess == (void *) -1UL) { - /* The application's socket is not valid. Contiuing */ - ret = -1; + /* + * The application's socket is not valid. Either a bad socket or a + * timeout on it. We can't inform yet the caller that for a + * specific app, the session failed so we continue here. + */ continue; } - /* Create channel onto application */ - ua_chan = create_ust_app_channel(ua_sess, uchan, app); - if (ua_chan == NULL) { - /* Major problem here and it's maybe the tracer or malloc() */ - ret = -1; - goto error; + /* Create channel onto application. We don't need the chan ref. */ + ret = create_ust_app_channel(ua_sess, uchan, app, NULL); + if (ret < 0 && ret == -ENOMEM) { + /* No more memory is a fatal error. Stop right now. */ + goto error_rcu_unlock; } } +error_rcu_unlock: rcu_read_unlock(); - -error: return ret; } @@ -2206,7 +2229,8 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { - goto error_rcu_unlock; + /* The session is in teardown process. Ignore and continue. */ + goto end; } /* Upon restart, we skip the setup, already done */ @@ -2364,8 +2388,7 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { - /* Only malloc can failed so something is really wrong */ - goto error_rcu_unlock; + goto end; } /* @@ -2427,7 +2450,7 @@ error_rcu_unlock: /* * Destroy a specific UST session in apps. */ -int ust_app_destroy_trace(struct ltt_ust_session *usess, struct ust_app *app) +static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app) { struct ust_app_session *ua_sess; struct lttng_ust_object_data obj; @@ -2446,8 +2469,8 @@ int ust_app_destroy_trace(struct ltt_ust_session *usess, struct ust_app *app) __lookup_session_by_app(usess, app, &iter); node = lttng_ht_iter_get_node_ulong(&iter); if (node == NULL) { - /* Only malloc can failed so something is really wrong */ - goto error_rcu_unlock; + /* Session is being or is deleted. */ + goto end; } ua_sess = caa_container_of(node, struct ust_app_session, node); ret = lttng_ht_del(app->sessions, &iter); @@ -2473,11 +2496,6 @@ end: rcu_read_unlock(); health_code_update(&health_thread_cmd); return 0; - -error_rcu_unlock: - rcu_read_unlock(); - health_code_update(&health_thread_cmd); - return -1; } /* @@ -2546,7 +2564,7 @@ int ust_app_destroy_trace_all(struct ltt_ust_session *usess) rcu_read_lock(); cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { - ret = ust_app_destroy_trace(usess, app); + ret = destroy_trace(usess, app); if (ret < 0) { /* Continue to next apps even on error */ continue; @@ -2571,10 +2589,7 @@ void ust_app_global_update(struct ltt_ust_session *usess, int sock) struct ust_app_event *ua_event; struct ust_app_ctx *ua_ctx; - if (usess == NULL) { - ERR("No UST session on global update. Returning"); - goto error; - } + assert(usess); DBG2("UST app global update for app sock %d for session id %d", sock, usess->id);