X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ftrace-ust.c;h=4a7e2610510cd805722315add867db300ea66823;hp=4ed8fb1a554868c10fa17f150f561f3eae808ee9;hb=2d97a0067600335f07eecb2c1d9ba68fc164583e;hpb=bdf640139afb02572eb23f014e4a61ad68fdfeb1 diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 4ed8fb1a5..4a7e26105 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -25,6 +25,7 @@ #include #include +#include #include "buffer-registry.h" #include "trace-ust.h" @@ -170,7 +171,7 @@ no_match: * lock MUST be acquired before calling this. */ struct ltt_ust_channel *trace_ust_find_channel_by_name(struct lttng_ht *ht, - char *name) + const char *name) { struct lttng_ht_node_str *node; struct lttng_ht_iter iter; @@ -280,7 +281,7 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) lus = zmalloc(sizeof(struct ltt_ust_session)); if (lus == NULL) { PERROR("create ust session zmalloc"); - goto error; + goto error_alloc; } /* Init data structure */ @@ -312,20 +313,35 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) /* Alloc agent hash table. */ lus->agents = lttng_ht_new(0, LTTNG_HT_TYPE_U64); + lus->tracker_list_vpid = lttng_tracker_list_create(); + if (!lus->tracker_list_vpid) { + goto error; + } + lus->tracker_list_vuid = lttng_tracker_list_create(); + if (!lus->tracker_list_vuid) { + goto error; + } + lus->tracker_list_vgid = lttng_tracker_list_create(); + if (!lus->tracker_list_vgid) { + goto error; + } lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL); if (lus->consumer == NULL) { - goto error_consumer; + goto error; } DBG2("UST trace session create successful"); return lus; -error_consumer: +error: + lttng_tracker_list_destroy(lus->tracker_list_vpid); + lttng_tracker_list_destroy(lus->tracker_list_vuid); + lttng_tracker_list_destroy(lus->tracker_list_vgid); ht_cleanup_push(lus->domain_global.channels); ht_cleanup_push(lus->agents); free(lus); -error: +error_alloc: return NULL; } @@ -356,6 +372,10 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan, luc->attr.switch_timer_interval = chan->attr.switch_timer_interval; luc->attr.read_timer_interval = chan->attr.read_timer_interval; luc->attr.output = (enum lttng_ust_output) chan->attr.output; + luc->monitor_timer_interval = ((struct lttng_channel_extended *) + chan->attr.extended.ptr)->monitor_timer_interval; + luc->attr.u.s.blocking_timeout = ((struct lttng_channel_extended *) + chan->attr.extended.ptr)->blocking_timeout; /* Translate to UST output enum */ switch (luc->attr.output) { @@ -431,91 +451,99 @@ end: * Allocate and initialize a ust event. Set name and event type. * We own filter_expression, filter, and exclusion. * - * Return pointer to structure or NULL. + * Return an lttng_error_code */ -struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev, +enum lttng_error_code trace_ust_create_event(struct lttng_event *ev, char *filter_expression, struct lttng_filter_bytecode *filter, struct lttng_event_exclusion *exclusion, - bool internal_event) + bool internal_event, + struct ltt_ust_event **ust_event) { - struct ltt_ust_event *lue; + struct ltt_ust_event *local_ust_event; + enum lttng_error_code ret = LTTNG_OK; assert(ev); if (exclusion && validate_exclusion(exclusion)) { + ret = LTTNG_ERR_INVALID; goto error; } - lue = zmalloc(sizeof(struct ltt_ust_event)); - if (lue == NULL) { + local_ust_event = zmalloc(sizeof(struct ltt_ust_event)); + if (local_ust_event == NULL) { PERROR("ust event zmalloc"); + ret = LTTNG_ERR_NOMEM; goto error; } - lue->internal = internal_event; + local_ust_event->internal = internal_event; switch (ev->type) { case LTTNG_EVENT_PROBE: - lue->attr.instrumentation = LTTNG_UST_PROBE; + local_ust_event->attr.instrumentation = LTTNG_UST_PROBE; break; case LTTNG_EVENT_FUNCTION: - lue->attr.instrumentation = LTTNG_UST_FUNCTION; + local_ust_event->attr.instrumentation = LTTNG_UST_FUNCTION; break; case LTTNG_EVENT_FUNCTION_ENTRY: - lue->attr.instrumentation = LTTNG_UST_FUNCTION; + local_ust_event->attr.instrumentation = LTTNG_UST_FUNCTION; break; case LTTNG_EVENT_TRACEPOINT: - lue->attr.instrumentation = LTTNG_UST_TRACEPOINT; + local_ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT; break; default: ERR("Unknown ust instrumentation type (%d)", ev->type); + ret = LTTNG_ERR_INVALID; goto error_free_event; } /* Copy event name */ - strncpy(lue->attr.name, ev->name, LTTNG_UST_SYM_NAME_LEN); - lue->attr.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + strncpy(local_ust_event->attr.name, ev->name, LTTNG_UST_SYM_NAME_LEN); + local_ust_event->attr.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; switch (ev->loglevel_type) { case LTTNG_EVENT_LOGLEVEL_ALL: - lue->attr.loglevel_type = LTTNG_UST_LOGLEVEL_ALL; - lue->attr.loglevel = -1; /* Force to -1 */ + local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_ALL; + local_ust_event->attr.loglevel = -1; /* Force to -1 */ break; case LTTNG_EVENT_LOGLEVEL_RANGE: - lue->attr.loglevel_type = LTTNG_UST_LOGLEVEL_RANGE; - lue->attr.loglevel = ev->loglevel; + local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_RANGE; + local_ust_event->attr.loglevel = ev->loglevel; break; case LTTNG_EVENT_LOGLEVEL_SINGLE: - lue->attr.loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE; - lue->attr.loglevel = ev->loglevel; + local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE; + local_ust_event->attr.loglevel = ev->loglevel; break; default: ERR("Unknown ust loglevel type (%d)", ev->loglevel_type); + ret = LTTNG_ERR_INVALID; goto error_free_event; } /* Same layout. */ - lue->filter_expression = filter_expression; - lue->filter = filter; - lue->exclusion = exclusion; + local_ust_event->filter_expression = filter_expression; + local_ust_event->filter = filter; + local_ust_event->exclusion = exclusion; /* Init node */ - lttng_ht_node_init_str(&lue->node, lue->attr.name); + lttng_ht_node_init_str(&local_ust_event->node, local_ust_event->attr.name); DBG2("Trace UST event %s, loglevel (%d,%d) created", - lue->attr.name, lue->attr.loglevel_type, - lue->attr.loglevel); + local_ust_event->attr.name, local_ust_event->attr.loglevel_type, + local_ust_event->attr.loglevel); + + *ust_event = local_ust_event; - return lue; + return ret; error_free_event: - free(lue); + free(local_ust_event); error: free(filter_expression); free(filter); free(exclusion); - return NULL; + return ret; } static @@ -551,6 +579,45 @@ int trace_ust_context_type_event_to_ust( case LTTNG_EVENT_CONTEXT_APP_CONTEXT: utype = LTTNG_UST_CONTEXT_APP_CONTEXT; break; + case LTTNG_EVENT_CONTEXT_CGROUP_NS: + utype = LTTNG_UST_CONTEXT_CGROUP_NS; + break; + case LTTNG_EVENT_CONTEXT_IPC_NS: + utype = LTTNG_UST_CONTEXT_IPC_NS; + break; + case LTTNG_EVENT_CONTEXT_MNT_NS: + utype = LTTNG_UST_CONTEXT_MNT_NS; + break; + case LTTNG_EVENT_CONTEXT_NET_NS: + utype = LTTNG_UST_CONTEXT_NET_NS; + break; + case LTTNG_EVENT_CONTEXT_PID_NS: + utype = LTTNG_UST_CONTEXT_PID_NS; + break; + case LTTNG_EVENT_CONTEXT_USER_NS: + utype = LTTNG_UST_CONTEXT_USER_NS; + break; + case LTTNG_EVENT_CONTEXT_UTS_NS: + utype = LTTNG_UST_CONTEXT_UTS_NS; + break; + case LTTNG_EVENT_CONTEXT_VUID: + utype = LTTNG_UST_CONTEXT_VUID; + break; + case LTTNG_EVENT_CONTEXT_VEUID: + utype = LTTNG_UST_CONTEXT_VEUID; + break; + case LTTNG_EVENT_CONTEXT_VSUID: + utype = LTTNG_UST_CONTEXT_VSUID; + break; + case LTTNG_EVENT_CONTEXT_VGID: + utype = LTTNG_UST_CONTEXT_VGID; + break; + case LTTNG_EVENT_CONTEXT_VEGID: + utype = LTTNG_UST_CONTEXT_VEGID; + break; + case LTTNG_EVENT_CONTEXT_VSGID: + utype = LTTNG_UST_CONTEXT_VSGID; + break; default: utype = -1; break; @@ -561,8 +628,8 @@ int trace_ust_context_type_event_to_ust( /* * Return 1 if contexts match, 0 otherwise. */ -int trace_ust_match_context(struct ltt_ust_context *uctx, - struct lttng_event_context *ctx) +int trace_ust_match_context(const struct ltt_ust_context *uctx, + const struct lttng_event_context *ctx) { int utype; @@ -589,6 +656,15 @@ int trace_ust_match_context(struct ltt_ust_context *uctx, return 0; } break; + case LTTNG_UST_CONTEXT_APP_CONTEXT: + assert(uctx->ctx.u.app_ctx.provider_name); + assert(uctx->ctx.u.app_ctx.ctx_name); + if (strcmp(uctx->ctx.u.app_ctx.provider_name, + ctx->u.app_ctx.provider_name) || + strcmp(uctx->ctx.u.app_ctx.ctx_name, + ctx->u.app_ctx.ctx_name)) { + return 0; + } default: break; @@ -602,7 +678,7 @@ int trace_ust_match_context(struct ltt_ust_context *uctx, * Return pointer to structure or NULL. */ struct ltt_ust_context *trace_ust_create_context( - struct lttng_event_context *ctx) + const struct lttng_event_context *ctx) { struct ltt_ust_context *uctx = NULL; int utype; @@ -658,29 +734,25 @@ error: return NULL; } -static -void destroy_pid_tracker_node_rcu(struct rcu_head *head) +static void destroy_id_tracker_node_rcu(struct rcu_head *head) { - struct ust_pid_tracker_node *tracker_node = - caa_container_of(head, struct ust_pid_tracker_node, node.head); + struct ust_id_tracker_node *tracker_node = caa_container_of( + head, struct ust_id_tracker_node, node.head); free(tracker_node); } -static -void destroy_pid_tracker_node(struct ust_pid_tracker_node *tracker_node) +static void destroy_id_tracker_node(struct ust_id_tracker_node *tracker_node) { - - call_rcu(&tracker_node->node.head, destroy_pid_tracker_node_rcu); + call_rcu(&tracker_node->node.head, destroy_id_tracker_node_rcu); } -static -int init_pid_tracker(struct ust_pid_tracker *pid_tracker) +static int init_id_tracker(struct ust_id_tracker *id_tracker) { - int ret = 0; + int ret = LTTNG_OK; - pid_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG); - if (!pid_tracker->ht) { - ret = -1; + id_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG); + if (!id_tracker->ht) { + ret = LTTNG_ERR_NOMEM; goto end; } @@ -689,63 +761,60 @@ end: } /* - * Teardown pid tracker content, but don't free pid_tracker object. + * Teardown id tracker content, but don't free id_tracker object. */ -static -void fini_pid_tracker(struct ust_pid_tracker *pid_tracker) +static void fini_id_tracker(struct ust_id_tracker *id_tracker) { - struct ust_pid_tracker_node *tracker_node; + struct ust_id_tracker_node *tracker_node; struct lttng_ht_iter iter; - if (!pid_tracker->ht) { + if (!id_tracker->ht) { return; } rcu_read_lock(); - cds_lfht_for_each_entry(pid_tracker->ht->ht, - &iter.iter, tracker_node, node.node) { - int ret = lttng_ht_del(pid_tracker->ht, &iter); + cds_lfht_for_each_entry (id_tracker->ht->ht, &iter.iter, tracker_node, + node.node) { + int ret = lttng_ht_del(id_tracker->ht, &iter); assert(!ret); - destroy_pid_tracker_node(tracker_node); + destroy_id_tracker_node(tracker_node); } rcu_read_unlock(); - ht_cleanup_push(pid_tracker->ht); - pid_tracker->ht = NULL; + ht_cleanup_push(id_tracker->ht); + id_tracker->ht = NULL; } -static -struct ust_pid_tracker_node *pid_tracker_lookup( - struct ust_pid_tracker *pid_tracker, int pid, +static struct ust_id_tracker_node *id_tracker_lookup( + struct ust_id_tracker *id_tracker, + int id, struct lttng_ht_iter *iter) { - unsigned long _pid = (unsigned long) pid; + unsigned long _id = (unsigned long) id; struct lttng_ht_node_ulong *node; - lttng_ht_lookup(pid_tracker->ht, (void *) _pid, iter); + lttng_ht_lookup(id_tracker->ht, (void *) _id, iter); node = lttng_ht_iter_get_node_ulong(iter); if (node) { - return caa_container_of(node, struct ust_pid_tracker_node, - node); + return caa_container_of(node, struct ust_id_tracker_node, node); } else { return NULL; } } -static -int pid_tracker_add_pid(struct ust_pid_tracker *pid_tracker, int pid) +static int id_tracker_add_id(struct ust_id_tracker *id_tracker, int id) { int retval = LTTNG_OK; - struct ust_pid_tracker_node *tracker_node; + struct ust_id_tracker_node *tracker_node; struct lttng_ht_iter iter; - if (pid < 0) { + if (id < 0) { retval = LTTNG_ERR_INVALID; goto end; } - tracker_node = pid_tracker_lookup(pid_tracker, pid, &iter); + tracker_node = id_tracker_lookup(id_tracker, id, &iter); if (tracker_node) { /* Already exists. */ - retval = LTTNG_ERR_PID_TRACKED; + retval = LTTNG_ERR_ID_TRACKED; goto end; } tracker_node = zmalloc(sizeof(*tracker_node)); @@ -753,48 +822,85 @@ int pid_tracker_add_pid(struct ust_pid_tracker *pid_tracker, int pid) retval = LTTNG_ERR_NOMEM; goto end; } - lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) pid); - lttng_ht_add_unique_ulong(pid_tracker->ht, &tracker_node->node); + lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) id); + lttng_ht_add_unique_ulong(id_tracker->ht, &tracker_node->node); end: return retval; } -static -int pid_tracker_del_pid(struct ust_pid_tracker *pid_tracker, int pid) +static int id_tracker_del_id(struct ust_id_tracker *id_tracker, int id) { int retval = LTTNG_OK, ret; - struct ust_pid_tracker_node *tracker_node; + struct ust_id_tracker_node *tracker_node; struct lttng_ht_iter iter; - if (pid < 0) { + if (id < 0) { retval = LTTNG_ERR_INVALID; goto end; } - tracker_node = pid_tracker_lookup(pid_tracker, pid, &iter); + tracker_node = id_tracker_lookup(id_tracker, id, &iter); if (!tracker_node) { /* Not found */ - retval = LTTNG_ERR_PID_NOT_TRACKED; + retval = LTTNG_ERR_ID_NOT_TRACKED; goto end; } - ret = lttng_ht_del(pid_tracker->ht, &iter); + ret = lttng_ht_del(id_tracker->ht, &iter); assert(!ret); - destroy_pid_tracker_node(tracker_node); + destroy_id_tracker_node(tracker_node); end: return retval; } +static struct ust_id_tracker *get_id_tracker(struct ltt_ust_session *session, + enum lttng_tracker_type tracker_type) +{ + switch (tracker_type) { + case LTTNG_TRACKER_VPID: + return &session->vpid_tracker; + case LTTNG_TRACKER_VUID: + return &session->vuid_tracker; + case LTTNG_TRACKER_VGID: + return &session->vgid_tracker; + default: + return NULL; + } +} + +static struct lttng_tracker_list *get_id_tracker_list( + struct ltt_ust_session *session, + enum lttng_tracker_type tracker_type) +{ + switch (tracker_type) { + case LTTNG_TRACKER_VPID: + return session->tracker_list_vpid; + case LTTNG_TRACKER_VUID: + return session->tracker_list_vuid; + case LTTNG_TRACKER_VGID: + return session->tracker_list_vgid; + default: + return NULL; + } +} + /* * The session lock is held when calling this function. */ -int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid) +int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type, + struct ltt_ust_session *session, + int id) { struct lttng_ht_iter iter; + struct ust_id_tracker *id_tracker; - if (!session->pid_tracker.ht) { + id_tracker = get_id_tracker(session, tracker_type); + if (!id_tracker) { + abort(); + } + if (!id_tracker->ht) { return 1; } - if (pid_tracker_lookup(&session->pid_tracker, pid, &iter)) { + if (id_tracker_lookup(id_tracker, id, &iter)) { return 1; } return 0; @@ -803,144 +909,226 @@ int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid) /* * Called with the session lock held. */ -int trace_ust_track_pid(struct ltt_ust_session *session, int pid) +int trace_ust_track_id(enum lttng_tracker_type tracker_type, + struct ltt_ust_session *session, + const struct lttng_tracker_id *id) { int retval = LTTNG_OK; + bool should_update_apps = false; + struct ust_id_tracker *id_tracker; + struct lttng_tracker_list *tracker_list; + int value; + struct lttng_tracker_id **saved_ids; + ssize_t saved_ids_count; + + if (tracker_type == LTTNG_TRACKER_PID) { + DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); + tracker_type = LTTNG_TRACKER_VPID; + } - if (pid == -1) { - /* Track all pids: destroy tracker if exists. */ - if (session->pid_tracker.ht) { - fini_pid_tracker(&session->pid_tracker); + retval = lttng_tracker_id_lookup_string(tracker_type, id, &value); + if (retval != LTTNG_OK) { + return retval; + } + tracker_list = get_id_tracker_list(session, tracker_type); + if (!tracker_list) { + return LTTNG_ERR_INVALID; + } + /* Save list for restore on error. */ + saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (saved_ids_count < 0) { + return LTTNG_ERR_INVALID; + } + /* Add to list. */ + retval = lttng_tracker_list_add(tracker_list, id); + if (retval != LTTNG_OK) { + goto end; + } + + id_tracker = get_id_tracker(session, tracker_type); + if (!id_tracker) { + abort(); + } + if (value == -1) { + /* Track all ids: destroy tracker if exists. */ + if (id_tracker->ht) { + fini_id_tracker(id_tracker); /* Ensure all apps have session. */ - ust_app_global_update_all(session); + should_update_apps = true; } } else { - int ret; - - if (!session->pid_tracker.ht) { + if (!id_tracker->ht) { /* Create tracker. */ - if (init_pid_tracker(&session->pid_tracker)) { - ERR("Error initializing PID tracker"); - retval = LTTNG_ERR_NOMEM; - goto end; + retval = init_id_tracker(id_tracker); + if (retval != LTTNG_OK) { + ERR("Error initializing ID tracker"); + goto end_restore; } - ret = pid_tracker_add_pid(&session->pid_tracker, pid); - if (ret != LTTNG_OK) { - retval = ret; - fini_pid_tracker(&session->pid_tracker); - goto end; + retval = id_tracker_add_id(id_tracker, value); + if (retval != LTTNG_OK) { + fini_id_tracker(id_tracker); + goto end_restore; } /* Remove all apps from session except pid. */ - ust_app_global_update_all(session); + should_update_apps = true; } else { struct ust_app *app; - ret = pid_tracker_add_pid(&session->pid_tracker, pid); - if (ret != LTTNG_OK) { - retval = ret; - goto end; + retval = id_tracker_add_id(id_tracker, value); + if (retval != LTTNG_OK) { + goto end_restore; } /* Add session to application */ - app = ust_app_find_by_pid(pid); - if (app) { - ust_app_global_update(session, app); + switch (tracker_type) { + case LTTNG_TRACKER_VPID: + app = ust_app_find_by_pid(value); + if (app) { + should_update_apps = true; + } + break; + default: + should_update_apps = true; } } } + if (should_update_apps && session->active) { + ust_app_global_update_all(session); + } + goto end; + +end_restore: + if (lttng_tracker_id_set_list(tracker_list, saved_ids, + saved_ids_count) != LTTNG_OK) { + ERR("Error on tracker add error handling.\n"); + } end: + lttng_tracker_ids_destroy(saved_ids, saved_ids_count); + free(saved_ids); return retval; } /* * Called with the session lock held. */ -int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid) +int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, + struct ltt_ust_session *session, + const struct lttng_tracker_id *id) { int retval = LTTNG_OK; + bool should_update_apps = false; + struct ust_id_tracker *id_tracker; + struct lttng_tracker_list *tracker_list; + int value; + struct lttng_tracker_id **saved_ids; + ssize_t saved_ids_count; + + if (tracker_type == LTTNG_TRACKER_PID) { + DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); + tracker_type = LTTNG_TRACKER_VPID; + } + + retval = lttng_tracker_id_lookup_string(tracker_type, id, &value); + if (retval != LTTNG_OK) { + return retval; + } - if (pid == -1) { + tracker_list = get_id_tracker_list(session, tracker_type); + if (!tracker_list) { + return LTTNG_ERR_INVALID; + } + /* Save list for restore on error. */ + saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (saved_ids_count < 0) { + return LTTNG_ERR_INVALID; + } + /* Remove from list. */ + retval = lttng_tracker_list_remove(tracker_list, id); + if (retval != LTTNG_OK) { + goto end; + } + + id_tracker = get_id_tracker(session, tracker_type); + if (!id_tracker) { + abort(); + } + + if (value == -1) { /* Create empty tracker, replace old tracker. */ - struct ust_pid_tracker tmp_tracker; + struct ust_id_tracker tmp_tracker; - tmp_tracker = session->pid_tracker; - if (init_pid_tracker(&session->pid_tracker)) { - ERR("Error initializing PID tracker"); - retval = LTTNG_ERR_NOMEM; + tmp_tracker = *id_tracker; + retval = init_id_tracker(id_tracker); + if (retval != LTTNG_OK) { + ERR("Error initializing ID tracker"); /* Rollback operation. */ - session->pid_tracker = tmp_tracker; - goto end; + *id_tracker = tmp_tracker; + goto end_restore; } - fini_pid_tracker(&tmp_tracker); + fini_id_tracker(&tmp_tracker); /* Remove session from all applications */ - ust_app_global_update_all(session); + should_update_apps = true; } else { - int ret; struct ust_app *app; - if (!session->pid_tracker.ht) { - /* No PID being tracked. */ - retval = LTTNG_ERR_PID_NOT_TRACKED; - goto end; + if (!id_tracker->ht) { + /* No ID being tracked. */ + retval = LTTNG_ERR_ID_NOT_TRACKED; + goto end_restore; } - /* Remove PID from tracker */ - ret = pid_tracker_del_pid(&session->pid_tracker, pid); - if (ret != LTTNG_OK) { - retval = ret; - goto end; + /* Remove ID from tracker */ + retval = id_tracker_del_id(id_tracker, value); + if (retval != LTTNG_OK) { + goto end_restore; } - /* Remove session from application. */ - app = ust_app_find_by_pid(pid); - if (app) { - ust_app_global_update(session, app); + switch (tracker_type) { + case LTTNG_TRACKER_VPID: + /* Remove session from application. */ + app = ust_app_find_by_pid(value); + if (app) { + should_update_apps = true; + } + break; + default: + /* Keep only apps matching ID. */ + should_update_apps = true; } } + if (should_update_apps && session->active) { + ust_app_global_update_all(session); + } + goto end; + +end_restore: + if (lttng_tracker_id_set_list(tracker_list, saved_ids, + saved_ids_count) != LTTNG_OK) { + ERR("Error on tracker remove error handling.\n"); + } end: + lttng_tracker_ids_destroy(saved_ids, saved_ids_count); + free(saved_ids); return retval; } /* * Called with session lock held. */ -ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session, - int32_t **_pids) +ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, + struct ltt_ust_session *session, + struct lttng_tracker_id ***_ids) { - struct ust_pid_tracker_node *tracker_node; - struct lttng_ht_iter iter; - unsigned long count, i = 0; - long approx[2]; - int32_t *pids; - int ret = 0; + struct lttng_tracker_list *tracker_list; - if (!session->pid_tracker.ht) { - /* Tracker disabled. Set first entry to -1. */ - pids = zmalloc(sizeof(*pids)); - if (!pids) { - ret = -1; - goto end; - } - pids[0] = -1; - *_pids = pids; - return 1; + if (tracker_type == LTTNG_TRACKER_PID) { + DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); + tracker_type = LTTNG_TRACKER_VPID; } - rcu_read_lock(); - cds_lfht_count_nodes(session->pid_tracker.ht->ht, - &approx[0], &count, &approx[1]); - pids = zmalloc(sizeof(*pids) * count); - if (!pids) { - ret = -1; - goto end; - } - cds_lfht_for_each_entry(session->pid_tracker.ht->ht, - &iter.iter, tracker_node, node.node) { - pids[i++] = tracker_node->node.key; + tracker_list = get_id_tracker_list(session, tracker_type); + if (!tracker_list) { + return -LTTNG_ERR_INVALID; } - *_pids = pids; - ret = count; -end: - rcu_read_unlock(); - return ret; + return lttng_tracker_id_get_list(tracker_list, _ids); } /* @@ -1135,7 +1323,8 @@ static void destroy_domain_global(struct ltt_ust_domain_global *dom) } /* - * Cleanup ust session structure + * Cleanup ust session structure, keeping data required by + * destroy notifier. * * Should *NOT* be called with RCU read-side lock held. */ @@ -1171,9 +1360,19 @@ void trace_ust_destroy_session(struct ltt_ust_session *session) buffer_reg_uid_destroy(reg, session->consumer); } - consumer_output_put(session->consumer); + lttng_tracker_list_destroy(session->tracker_list_vpid); + lttng_tracker_list_destroy(session->tracker_list_vuid); + lttng_tracker_list_destroy(session->tracker_list_vgid); - fini_pid_tracker(&session->pid_tracker); + fini_id_tracker(&session->vpid_tracker); + fini_id_tracker(&session->vuid_tracker); + fini_id_tracker(&session->vgid_tracker); + lttng_trace_chunk_put(session->current_trace_chunk); +} +/* Free elements needed by destroy notifiers. */ +void trace_ust_free_session(struct ltt_ust_session *session) +{ + consumer_output_put(session->consumer); free(session); }