struct cds_lfht_node *node;
struct cds_lfht_iter iter;
struct ust_app_session *ua_sess;
+ int sock;
rcu_read_lock();
/* 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);
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);
/* Copy all events from ltt ust channel to ust app channel */
cds_lfht_for_each_entry(uchan->events, &iter, uevent, node) {
+ struct cds_lfht_iter uiter;
+
ua_event_node = hashtable_lookup(ua_chan->events,
- (void *) uevent->attr.name, strlen(uevent->attr.name), &iter);
+ (void *) uevent->attr.name, strlen(uevent->attr.name),
+ &uiter);
if (ua_event_node == NULL) {
DBG2("UST event %s not found on shadow copy channel",
uevent->attr.name);
* Copy data between a UST app session and a regular LTT session.
*/
static void shadow_copy_session(struct ust_app_session *ua_sess,
- struct ltt_ust_session *usess)
+ struct ltt_ust_session *usess,
+ struct ust_app *app)
{
struct cds_lfht_node *ua_chan_node;
struct cds_lfht_iter iter;
struct ltt_ust_channel *uchan;
struct ust_app_channel *ua_chan;
+ time_t rawtime;
+ struct tm *timeinfo;
+ char datetime[16];
+ int ret;
+
+ /* Get date and time for unique app path */
+ time(&rawtime);
+ timeinfo = localtime(&rawtime);
+ strftime(datetime, sizeof(datetime), "%Y%m%d-%H%M%S", timeinfo);
DBG2("Shadow copy of session handle %d", ua_sess->handle);
ua_sess->uid = usess->uid;
+ ret = snprintf(ua_sess->path, PATH_MAX,
+ "%s/%s-%d-%s",
+ usess->pathname, app->name, app->key.pid,
+ datetime);
+ if (ret < 0) {
+ PERROR("asprintf UST shadow copy session");
+ /* TODO: We cannot return an error from here.. */
+ assert(0);
+ }
+
/* TODO: support all UST domain */
/* Iterate over all channels in global domain. */
cds_lfht_for_each_entry(usess->domain_global.channels, &iter,
uchan, node) {
+ struct cds_lfht_iter uiter;
+
ua_chan_node = hashtable_lookup(ua_sess->channels,
- (void *)uchan->name, strlen(uchan->name), &iter);
+ (void *)uchan->name, strlen(uchan->name),
+ &uiter);
if (ua_chan_node != NULL) {
continue;
}
/* Only malloc can failed so something is really wrong */
goto error;
}
- shadow_copy_session(ua_sess, usess);
+ shadow_copy_session(ua_sess, usess, app);
}
if (ua_sess->handle == -1) {
goto error;
}
- ret = snprintf(ua_sess->metadata->pathname, PATH_MAX, "%s/%s-%d",
- pathname, app->name, app->key.pid);
- if (ret < 0) {
- PERROR("asprintf UST create stream");
- goto error;
- }
-
- ret = mkdir(ua_sess->metadata->pathname, S_IRWXU | S_IRWXG);
+ ret = mkdir(ua_sess->path, S_IRWXU | S_IRWXG);
if (ret < 0) {
PERROR("mkdir UST metadata");
goto error;
}
- ret = snprintf(ua_sess->metadata->pathname, PATH_MAX, "%s/%s-%d/metadata",
- pathname, app->name, app->key.pid);
+ ret = snprintf(ua_sess->metadata->pathname, PATH_MAX,
+ "%s/metadata", ua_sess->path);
if (ret < 0) {
PERROR("asprintf UST create stream");
goto error;
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:
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) {
/* For all registered applications */
cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
+ struct cds_lfht_iter uiter;
+
/* Create session on the tracer side and add it to app session HT */
ua_sess = create_ust_app_session(usess, app);
if (ua_sess == NULL) {
/* Lookup channel in the ust app session */
ua_chan_node = hashtable_lookup(ua_sess->channels,
- (void *)uchan->name, strlen(uchan->name), &iter);
+ (void *)uchan->name, strlen(uchan->name),
+ &uiter);
if (ua_chan_node == NULL) {
ERR("Channel %s not found in session uid %d. Skipping",
uchan->name, usess->uid);
/* Order is important */
cds_list_add_tail(&ustream->list, &ua_chan->streams.head);
- ret = snprintf(ustream->pathname, PATH_MAX, "%s/%s-%d/%s_%u",
- usess->pathname, app->name, app->key.pid,
- ua_chan->name, ua_chan->streams.count++);
+ ret = snprintf(ustream->pathname, PATH_MAX, "%s/%s_%u",
+ ua_sess->path, ua_chan->name,
+ ua_chan->streams.count++);
if (ret < 0) {
PERROR("asprintf UST create stream");
continue;