X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lttng-sessiond%2Fust-app.c;h=09989ff49ea7af21f1cb116d62923e193043e2cb;hb=67f747d8095da3f240f71e33c4a1eb0f84aa5e41;hp=7276cbb63755113512bfd97e69da8b945c66f0b7;hpb=8b366481a27ae38bce4099ac17817511e0cd5425;p=lttng-tools.git diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index 7276cbb63..09989ff49 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -34,6 +34,7 @@ #include "ust-app.h" #include "ust-consumer.h" #include "ust-ctl.h" +#include "utils.h" /* * Delete ust context safely. RCU read lock must be held before calling @@ -163,6 +164,9 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess) ret = hashtable_destroy(ua_sess->channels); assert(!ret); + if (ua_sess->handle != -1) { + ustctl_release_handle(sock, ua_sess->handle); + } free(ua_sess); } @@ -565,6 +569,8 @@ static int open_ust_metadata(struct ust_app *app, goto error; } + ua_sess->metadata->handle = ua_sess->metadata->obj->handle; + error: return ret; } @@ -764,7 +770,9 @@ static void shadow_copy_session(struct ust_app_session *ua_sess, DBG2("Shadow copy of session handle %d", ua_sess->handle); + ua_sess->id = usess->id; ua_sess->uid = usess->uid; + ua_sess->gid = usess->gid; ret = snprintf(ua_sess->path, PATH_MAX, "%s/%s-%d-%s", @@ -812,13 +820,13 @@ void __lookup_session_by_app(struct ltt_ust_session *usess, { /* Get right UST app session from app */ (void) hashtable_lookup(app->sessions, - (void *) ((unsigned long) usess->uid), sizeof(void *), + (void *) ((unsigned long) usess->id), sizeof(void *), iter); } /* * Return ust app session from the app session hashtable using the UST session - * uid. + * id. */ static struct ust_app_session *lookup_session_by_app( struct ltt_ust_session *usess, struct ust_app *app) @@ -852,8 +860,8 @@ static struct ust_app_session *create_ust_app_session( ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { - DBG2("UST app pid: %d session uid %d not found, creating it", - app->key.pid, usess->uid); + DBG2("UST app pid: %d session id %d not found, creating it", + app->key.pid, usess->id); ua_sess = alloc_ust_app_session(); if (ua_sess == NULL) { /* Only malloc can failed so something is really wrong */ @@ -876,7 +884,7 @@ static struct ust_app_session *create_ust_app_session( /* Add ust app session to app's HT */ hashtable_node_init(&ua_sess->node, - (void *)((unsigned long) ua_sess->uid), sizeof(void *)); + (void *)((unsigned long) ua_sess->id), sizeof(void *)); hashtable_add_unique(app->sessions, &ua_sess->node); DBG2("UST app session created successfully with handle %d", ret); @@ -996,8 +1004,7 @@ error: * Disable on the tracer side a ust app event for the session and channel. */ static int disable_ust_app_event(struct ust_app_session *ua_sess, - struct ust_app_channel *ua_chan, struct ust_app_event *ua_event, - struct ust_app *app) + struct ust_app_event *ua_event, struct ust_app *app) { int ret; @@ -1046,8 +1053,8 @@ static int enable_ust_app_channel(struct ust_app_session *ua_sess, ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name, strlen(uchan->name), &iter); if (ua_chan_node == NULL) { - DBG2("Unable to find channel %s in ust session uid %u", - uchan->name, ua_sess->uid); + DBG2("Unable to find channel %s in ust session id %u", + uchan->name, ua_sess->id); goto error; } @@ -1078,8 +1085,8 @@ static struct ust_app_channel *create_ust_app_channel( ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name, strlen(uchan->name), &iter); if (ua_chan_node == NULL) { - DBG2("Unable to find channel %s in ust session uid %u", - uchan->name, ua_sess->uid); + DBG2("Unable to find channel %s in ust session id %u", + uchan->name, ua_sess->id); ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr); if (ua_chan == NULL) { goto error; @@ -1136,7 +1143,9 @@ int create_ust_app_event(struct ust_app_session *ua_sess, /* Create it on the tracer side */ ret = create_ust_event(app, ua_sess, ua_chan, ua_event); if (ret < 0) { + rcu_read_lock(); delete_ust_app_event(app->key.sock, ua_event); + rcu_read_unlock(); goto error; } @@ -1144,6 +1153,9 @@ int create_ust_app_event(struct ust_app_session *ua_sess, hashtable_add_unique(ua_chan->events, &ua_event->node); + DBG2("UST app create event %s for PID %d completed", + ua_event->name, app->key.pid); + end: error: return ret; @@ -1181,7 +1193,8 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess, goto error; } - ret = mkdir(ua_sess->path, S_IRWXU | S_IRWXG); + ret = mkdir_run_as(ua_sess->path, S_IRWXU | S_IRWXG, + ua_sess->uid, ua_sess->gid); if (ret < 0) { PERROR("mkdir UST metadata"); goto error; @@ -1370,6 +1383,8 @@ int ust_app_list_events(struct lttng_event **events) rcu_read_lock(); cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct lttng_ust_tracepoint_iter uiter; + handle = ustctl_tracepoint_list(app->key.sock); if (handle < 0) { ERR("UST app list events getting handle failed for app pid %d", @@ -1378,11 +1393,11 @@ int ust_app_list_events(struct lttng_event **events) } while ((ret = ustctl_tracepoint_list_get(app->key.sock, handle, - tmp[count].name)) != -ENOENT) { - if (count > nbmem) { - DBG2("Reallocating event list from %zu to %zu bytes", nbmem, - nbmem + UST_APP_EVENT_LIST_SIZE); - nbmem += UST_APP_EVENT_LIST_SIZE; + &uiter)) != -ENOENT) { + if (count >= nbmem) { + DBG2("Reallocating event list from %zu to %zu entries", nbmem, + 2 * nbmem); + nbmem *= 2; tmp = realloc(tmp, nbmem * sizeof(struct lttng_event)); if (tmp == NULL) { PERROR("realloc ust app events"); @@ -1390,7 +1405,9 @@ int ust_app_list_events(struct lttng_event **events) goto rcu_error; } } - + memcpy(tmp[count].name, uiter.name, LTTNG_UST_SYM_NAME_LEN); + memcpy(tmp[count].loglevel, uiter.loglevel, LTTNG_UST_SYM_NAME_LEN); + tmp[count].loglevel_value = uiter.loglevel_value; tmp[count].type = LTTNG_UST_TRACEPOINT; tmp[count].pid = app->key.pid; tmp[count].enabled = -1; @@ -1462,13 +1479,15 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, goto error; } - DBG2("UST app disabling channel %s from global domain for session uid %d", - uchan->name, usess->uid); + DBG2("UST app disabling channel %s from global domain for session id %d", + uchan->name, usess->id); rcu_read_lock(); /* For every registered applications */ cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct cds_lfht_iter uiter; + ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { continue; @@ -1476,7 +1495,7 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, /* Get channel */ ua_chan_node = hashtable_lookup(ua_sess->channels, - (void *)uchan->name, strlen(uchan->name), &iter); + (void *)uchan->name, strlen(uchan->name), &uiter); /* If the session if found for the app, the channel must be there */ assert(ua_chan_node); @@ -1515,8 +1534,8 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess, goto error; } - DBG2("UST app enabling channel %s to global domain for session uid %d", - uchan->name, usess->uid); + DBG2("UST app enabling channel %s to global domain for session id %d", + uchan->name, usess->id); rcu_read_lock(); @@ -1548,7 +1567,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent) { int ret = 0; - struct cds_lfht_iter iter, uiter; + struct cds_lfht_iter iter; struct cds_lfht_node *ua_chan_node, *ua_event_node; struct ust_app *app; struct ust_app_session *ua_sess; @@ -1556,12 +1575,14 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, struct ust_app_event *ua_event; DBG("UST app disabling event %s for all apps in channel " - "%s for session uid %d", uevent->attr.name, uchan->name, usess->uid); + "%s for session id %d", uevent->attr.name, uchan->name, usess->id); rcu_read_lock(); /* For all registered applications */ cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct cds_lfht_iter uiter; + ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { /* Next app */ @@ -1572,8 +1593,8 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name, strlen(uchan->name), &uiter); if (ua_chan_node == NULL) { - DBG2("Channel %s not found in session uid %d for app pid %d." - "Skipping", uchan->name, usess->uid, app->key.pid); + DBG2("Channel %s not found in session id %d for app pid %d." + "Skipping", uchan->name, usess->id, app->key.pid); continue; } ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node); @@ -1587,7 +1608,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess, } ua_event = caa_container_of(ua_event_node, struct ust_app_event, node); - ret = disable_ust_app_event(ua_sess, ua_chan, ua_event, app); + ret = disable_ust_app_event(ua_sess, ua_event, app); if (ret < 0) { /* XXX: Report error someday... */ continue; @@ -1607,7 +1628,7 @@ int ust_app_disable_all_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan) { int ret = 0; - struct cds_lfht_iter iter, uiter; + struct cds_lfht_iter iter; struct cds_lfht_node *ua_chan_node; struct ust_app *app; struct ust_app_session *ua_sess; @@ -1615,12 +1636,14 @@ int ust_app_disable_all_event_glb(struct ltt_ust_session *usess, struct ust_app_event *ua_event; DBG("UST app disabling all event for all apps in channel " - "%s for session uid %d", uchan->name, usess->uid); + "%s for session id %d", uchan->name, usess->id); rcu_read_lock(); /* For all registered applications */ cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct cds_lfht_iter uiter; + ua_sess = lookup_session_by_app(usess, app); /* If ua_sess is NULL, there is a code flow error */ assert(ua_sess); @@ -1635,7 +1658,7 @@ int ust_app_disable_all_event_glb(struct ltt_ust_session *usess, /* Disable each events of channel */ cds_lfht_for_each_entry(ua_chan->events, &uiter, ua_event, node) { - ret = disable_ust_app_event(ua_sess, ua_chan, ua_event, app); + ret = disable_ust_app_event(ua_sess, ua_event, app); if (ret < 0) { /* XXX: Report error someday... */ continue; @@ -1666,8 +1689,8 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, goto error; } - DBG2("UST app adding channel %s to global domain for session uid %d", - uchan->name, usess->uid); + DBG2("UST app adding channel %s to global domain for session id %d", + uchan->name, usess->id); rcu_read_lock(); @@ -1703,15 +1726,15 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent) { int ret = 0; - struct cds_lfht_iter iter, uiter; + struct cds_lfht_iter iter; struct cds_lfht_node *ua_chan_node, *ua_event_node; struct ust_app *app; struct ust_app_session *ua_sess; struct ust_app_channel *ua_chan; struct ust_app_event *ua_event; - DBG("UST app enabling event %s for all apps for session uid %d", - uevent->attr.name, usess->uid); + DBG("UST app enabling event %s for all apps for session id %d", + uevent->attr.name, usess->id); /* * NOTE: At this point, this function is called only if the session and @@ -1723,6 +1746,8 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess, /* For all registered applications */ cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct cds_lfht_iter uiter; + ua_sess = lookup_session_by_app(usess, app); /* If ua_sess is NULL, there is a code flow error */ assert(ua_sess); @@ -1735,24 +1760,23 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess, ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node); - ua_event_node = hashtable_lookup(ua_sess->channels, + ua_event_node = hashtable_lookup(ua_chan->events, (void*)uevent->attr.name, strlen(uevent->attr.name), &uiter); if (ua_event_node == NULL) { - DBG3("UST app enable event %s not found. Skipping app", - uevent->attr.name); + DBG3("UST app enable event %s not found for app PID %d." + "Skipping app", uevent->attr.name, app->key.pid); continue; } ua_event = caa_container_of(ua_event_node, struct ust_app_event, node); ret = enable_ust_app_event(ua_sess, ua_event, app); if (ret < 0) { - /* XXX: Report error someday... */ - continue; + goto error; } } +error: rcu_read_unlock(); - return ret; } @@ -1764,14 +1788,14 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent) { int ret = 0; - struct cds_lfht_iter iter, uiter; + struct cds_lfht_iter iter; struct cds_lfht_node *ua_chan_node; struct ust_app *app; struct ust_app_session *ua_sess; struct ust_app_channel *ua_chan; - DBG("UST app creating event %s for all apps for session uid %d", - uevent->attr.name, usess->uid); + DBG("UST app creating event %s for all apps for session id %d", + uevent->attr.name, usess->id); /* * NOTE: At this point, this function is called only if the session and @@ -1783,6 +1807,8 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess, /* For all registered applications */ cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct cds_lfht_iter uiter; + ua_sess = lookup_session_by_app(usess, app); /* If ua_sess is NULL, there is a code flow error */ assert(ua_sess); @@ -1915,7 +1941,9 @@ error_rcu_unlock: int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) { int ret = 0; + struct cds_lfht_iter iter; struct ust_app_session *ua_sess; + struct ust_app_channel *ua_chan; DBG("Stopping tracing for ust app pid %d", app->key.pid); @@ -1927,34 +1955,37 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) 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); + /* This inhibits UST tracing */ + ret = ustctl_stop_session(app->key.sock, ua_sess->handle); if (ret < 0) { - ERR("UST metadata flush failed"); + ERR("Error stopping tracing for app pid: %d", app->key.pid); + goto error_rcu_unlock; } - cds_list_for_each_entry(ustchan, &usess->channels.head, list) { - ret = ustctl_flush_buffer(usess->sock, ustchan->obj); + /* Quiescent wait after stopping trace */ + ustctl_wait_quiescent(app->key.sock); + + /* Flushing buffers */ + cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) { + ret = ustctl_sock_flush_buffer(app->key.sock, ua_chan->obj); if (ret < 0) { - ERR("UST flush buffer error"); + ERR("UST app PID %d channel %s flush failed", + app->key.pid, ua_chan->name); + ERR("Ended with ret %d", ret); + /* Continuing flushing all buffers */ + continue; } } -#endif - /* This inhibits UST tracing */ - ret = ustctl_stop_session(app->key.sock, ua_sess->handle); + /* Flush all buffers before stopping */ + ret = ustctl_sock_flush_buffer(app->key.sock, ua_sess->metadata->obj); if (ret < 0) { - ERR("Error stopping tracing for app pid: %d", app->key.pid); - goto error_rcu_unlock; + ERR("UST app PID %d metadata flush failed", app->key.pid); + ERR("Ended with ret %d", ret); } rcu_read_unlock(); - /* Quiescent wait after stopping trace */ - ustctl_wait_quiescent(app->key.sock); - return 0; error_rcu_unlock: @@ -2100,8 +2131,8 @@ void ust_app_global_update(struct ltt_ust_session *usess, int sock) goto error; } - DBG2("UST app global update for app sock %d for session uid %d", sock, - usess->uid); + DBG2("UST app global update for app sock %d for session id %d", sock, + usess->id); rcu_read_lock(); @@ -2122,6 +2153,8 @@ void ust_app_global_update(struct ltt_ust_session *usess, int sock) * ltt ust session. */ cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) { + struct cds_lfht_iter uiter; + ret = create_ust_channel(app, ua_sess, ua_chan); if (ret < 0) { /* FIXME: Should we quit here or continue... */ @@ -2129,7 +2162,7 @@ void ust_app_global_update(struct ltt_ust_session *usess, int sock) } /* For each events */ - cds_lfht_for_each_entry(ua_chan->events, &iter, ua_event, node) { + cds_lfht_for_each_entry(ua_chan->events, &uiter, ua_event, node) { ret = create_ust_event(app, ua_sess, ua_chan, ua_event); if (ret < 0) { /* FIXME: Should we quit here or continue... */ @@ -2160,7 +2193,7 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, { int ret = 0; struct cds_lfht_node *ua_chan_node; - struct cds_lfht_iter iter, uiter; + struct cds_lfht_iter iter; struct ust_app_channel *ua_chan = NULL; struct ust_app_session *ua_sess; struct ust_app *app; @@ -2168,6 +2201,8 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, rcu_read_lock(); cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct cds_lfht_iter uiter; + ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { continue; @@ -2188,9 +2223,6 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess, } } - /* Add ltt UST context node to ltt UST channel */ - hashtable_add_unique(uchan->ctx, &uctx->node); - rcu_read_unlock(); return ret; } @@ -2204,7 +2236,7 @@ int ust_app_add_ctx_event_glb(struct ltt_ust_session *usess, { int ret = 0; struct cds_lfht_node *ua_chan_node, *ua_event_node; - struct cds_lfht_iter iter, uiter; + struct cds_lfht_iter iter; struct ust_app_session *ua_sess; struct ust_app_event *ua_event; struct ust_app_channel *ua_chan = NULL; @@ -2213,6 +2245,8 @@ int ust_app_add_ctx_event_glb(struct ltt_ust_session *usess, rcu_read_lock(); cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + struct cds_lfht_iter uiter; + ua_sess = lookup_session_by_app(usess, app); if (ua_sess == NULL) { continue; @@ -2241,9 +2275,120 @@ int ust_app_add_ctx_event_glb(struct ltt_ust_session *usess, } } - /* Add ltt UST context node to ltt UST event */ - hashtable_add_unique(uevent->ctx, &uctx->node); + rcu_read_unlock(); + return ret; +} + +/* + * Enable event for a channel from a UST session for a specific PID. + */ +int ust_app_enable_event_pid(struct ltt_ust_session *usess, + struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid) +{ + int ret = 0; + struct cds_lfht_iter iter; + struct cds_lfht_node *ua_chan_node, *ua_event_node; + struct ust_app *app; + struct ust_app_session *ua_sess; + struct ust_app_channel *ua_chan; + struct ust_app_event *ua_event; + + DBG("UST app enabling event %s for PID %d", uevent->attr.name, pid); + + rcu_read_lock(); + + app = ust_app_find_by_pid(pid); + if (app == NULL) { + ERR("UST app enable event per PID %d not found", pid); + ret = -1; + goto error; + } + + ua_sess = lookup_session_by_app(usess, app); + /* If ua_sess is NULL, there is a code flow error */ + assert(ua_sess); + + /* Lookup channel in the ust app session */ + ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name, + strlen(uchan->name), &iter); + /* If the channel is not found, there is a code flow error */ + assert(ua_chan_node); + + ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node); + + ua_event_node = hashtable_lookup(ua_chan->events, + (void*)uevent->attr.name, strlen(uevent->attr.name), &iter); + if (ua_event_node == NULL) { + ret = create_ust_app_event(ua_sess, ua_chan, uevent, app); + if (ret < 0) { + goto error; + } + } else { + ua_event = caa_container_of(ua_event_node, struct ust_app_event, node); + + ret = enable_ust_app_event(ua_sess, ua_event, app); + if (ret < 0) { + goto error; + } + } + +error: + rcu_read_unlock(); + return ret; +} +/* + * Disable event for a channel from a UST session for a specific PID. + */ +int ust_app_disable_event_pid(struct ltt_ust_session *usess, + struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid) +{ + int ret = 0; + struct cds_lfht_iter iter; + struct cds_lfht_node *ua_chan_node, *ua_event_node; + struct ust_app *app; + struct ust_app_session *ua_sess; + struct ust_app_channel *ua_chan; + struct ust_app_event *ua_event; + + DBG("UST app disabling event %s for PID %d", uevent->attr.name, pid); + + rcu_read_lock(); + + app = ust_app_find_by_pid(pid); + if (app == NULL) { + ERR("UST app disable event per PID %d not found", pid); + ret = -1; + goto error; + } + + ua_sess = lookup_session_by_app(usess, app); + /* If ua_sess is NULL, there is a code flow error */ + assert(ua_sess); + + /* Lookup channel in the ust app session */ + ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name, + strlen(uchan->name), &iter); + if (ua_chan_node == NULL) { + /* Channel does not exist, skip disabling */ + goto error; + } + ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node); + + ua_event_node = hashtable_lookup(ua_chan->events, + (void*)uevent->attr.name, strlen(uevent->attr.name), &iter); + if (ua_event_node == NULL) { + /* Event does not exist, skip disabling */ + goto error; + } + ua_event = caa_container_of(ua_event_node, struct ust_app_event, node); + + ret = disable_ust_app_event(ua_sess, ua_event, app); + if (ret < 0) { + goto error; + } + +error: rcu_read_unlock(); return ret; }