X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=lttng-sessiond%2Fust-app.c;h=3547679f8bc8dbe1381aae36f46a54a7f3933932;hb=8be98f9a4419d360bce0678981ba3f4b891b0a19;hp=2bee4d90ab7626b7b51c314b67ef539d65441634;hpb=477d7741a6555ba9d2ef0bbfc72fc7877cbbb869;p=lttng-tools.git diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index 2bee4d90a..3547679f8 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -143,6 +143,7 @@ static void delete_ust_app(struct ust_app *app) struct cds_lfht_node *node; struct cds_lfht_iter iter; struct ust_app_session *ua_sess; + int sock; rcu_read_lock(); @@ -167,9 +168,8 @@ static void delete_ust_app(struct ust_app *app) /* Socket is already closed at this point */ /* Delete ust app sessions info */ - if (app->sock_closed) { - app->key.sock = -1; - } + sock = app->key.sock; + app->key.sock = -1; cds_lfht_for_each_entry(app->sessions, &iter, ua_sess, node) { hashtable_del(app->sessions, &iter); @@ -182,9 +182,13 @@ static void delete_ust_app(struct ust_app *app) goto end; } - if (!app->sock_closed) { - close(app->key.sock); - } + /* + * Wait until we have removed the key from the sock hash table + * before closing this socket, otherwise an application could + * re-use the socket ID and race with the teardown, using the + * same hash table entry. + */ + close(sock); DBG2("UST app pid %d deleted", app->key.pid); free(app); @@ -881,10 +885,6 @@ void ust_app_unregister(int sock) goto error; } - /* We got called because the socket was closed on the remote end. */ - close(sock); - /* Using a flag because we still need "sock" as a key. */ - lta->sock_closed = 1; hashtable_del(ust_app_ht, &iter); call_rcu(&node->head, delete_ust_app_rcu); error: @@ -983,8 +983,6 @@ void ust_app_clean_list(void) cds_lfht_for_each(ust_app_ht, &iter, node) { app = caa_container_of(node, struct ust_app, node); - close(app->key.sock); - app->sock_closed = 1; ret = hashtable_del(ust_app_ht, &iter); if (!ret) { @@ -1124,6 +1122,10 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) goto error_rcu_unlock; } + /* upon restart, we skip the setup, already done */ + if (ua_sess->started) + goto skip_setup; + ret = create_ust_app_metadata(ua_sess, usess->pathname, app); if (ret < 0) { goto error_rcu_unlock; @@ -1167,7 +1169,9 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) if (ret < 0) { goto error_rcu_unlock; } + ua_sess->started = 1; +skip_setup: /* This start the UST tracing */ ret = ustctl_start_session(app->key.sock, ua_sess->handle); if (ret < 0) { @@ -1187,6 +1191,59 @@ error_rcu_unlock: return -1; } +/* + * Stop tracing for a specific UST session and app. + */ +int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) +{ + int ret = 0; + struct ust_app_session *ua_sess; + + DBG("Stopping tracing for ust app pid %d", app->key.pid); + + rcu_read_lock(); + + 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; + } + +#if 0 /* only useful when periodical flush will be supported */ + /* need to keep a handle on shm in session for this. */ + /* Flush all buffers before stopping */ + ret = ustctl_flush_buffer(usess->sock, usess->metadata->obj); + if (ret < 0) { + ERR("UST metadata flush failed"); + } + + cds_list_for_each_entry(ustchan, &usess->channels.head, list) { + ret = ustctl_flush_buffer(usess->sock, ustchan->obj); + if (ret < 0) { + ERR("UST flush buffer error"); + } + } +#endif + + /* This inhibits UST tracing */ + ret = ustctl_stop_session(app->key.sock, ua_sess->handle); + if (ret < 0) { + ERR("Error stopping tracing for app pid: %d", app->key.pid); + goto error_rcu_unlock; + } + + rcu_read_unlock(); + + /* Quiescent wait after stopping trace */ + ustctl_wait_quiescent(app->key.sock); + + return 0; + +error_rcu_unlock: + rcu_read_unlock(); + return -1; +} + /* * Start tracing for the UST session. */ @@ -1213,6 +1270,32 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess) return 0; } +/* + * Start tracing for the UST session. + */ +int ust_app_stop_trace_all(struct ltt_ust_session *usess) +{ + int ret = 0; + struct cds_lfht_iter iter; + struct ust_app *app; + + DBG("Stopping all UST traces"); + + rcu_read_lock(); + + cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + ret = ust_app_stop_trace(usess, app); + if (ret < 0) { + /* Continue to next apps even on error */ + continue; + } + } + + rcu_read_unlock(); + + return 0; +} + /* * Add channels/events from UST global domain to registered apps at sock. */