X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ftrace-ust.c;h=b6cf57cf2360bad1030fc1dfbf664ad41ea4018a;hp=a6c0c04ad864075d64cbf0c8dba6b66e96ce21cc;hb=246611b0dffa58fbc0e2329ddf6f9dc9d9eff7ce;hpb=a5a309207b81778262744a9de568f6d7c54996e2 diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index a6c0c04ad..b6cf57cf2 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -1,19 +1,9 @@ /* - * Copyright (C) 2011 - David Goulet - * Copyright (C) 2016 - Jérémie Galarneau + * Copyright (C) 2011 David Goulet + * Copyright (C) 2016 Jérémie Galarneau * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2 only, - * as published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _LGPL_SOURCE @@ -26,6 +16,7 @@ #include #include #include +#include #include "buffer-registry.h" #include "trace-ust.h" @@ -92,7 +83,7 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key) /* Event loglevel value and type. */ ll_match = loglevels_match(event->attr.loglevel_type, ev_loglevel_value, key->loglevel_type, - key->loglevel_value, LTTNG_UST_LOGLEVEL_ALL); + key->loglevel_value, LTTNG_UST_ABI_LOGLEVEL_ALL); if (!ll_match) { goto no_match; @@ -203,8 +194,8 @@ error: * MUST be acquired before calling this. */ struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht, - char *name, struct lttng_filter_bytecode *filter, - enum lttng_ust_loglevel_type loglevel_type, int loglevel_value, + char *name, struct lttng_bytecode *filter, + enum lttng_ust_abi_loglevel_type loglevel_type, int loglevel_value, struct lttng_event_exclusion *exclusion) { struct lttng_ht_node_str *node; @@ -281,7 +272,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 */ @@ -294,7 +285,7 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) lus->metadata_attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; lus->metadata_attr.switch_timer_interval = DEFAULT_METADATA_SWITCH_TIMER; lus->metadata_attr.read_timer_interval = DEFAULT_METADATA_READ_TIMER; - lus->metadata_attr.output = LTTNG_UST_MMAP; + lus->metadata_attr.output = LTTNG_UST_ABI_MMAP; /* * Default buffer type. This can be changed through an enable channel @@ -313,20 +304,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_vpid = process_attr_tracker_create(); + if (!lus->tracker_vpid) { + goto error; + } + lus->tracker_vuid = process_attr_tracker_create(); + if (!lus->tracker_vuid) { + goto error; + } + lus->tracker_vgid = process_attr_tracker_create(); + if (!lus->tracker_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: + process_attr_tracker_destroy(lus->tracker_vpid); + process_attr_tracker_destroy(lus->tracker_vuid); + process_attr_tracker_destroy(lus->tracker_vgid); ht_cleanup_push(lus->domain_global.channels); ht_cleanup_push(lus->agents); free(lus); -error: +error_alloc: return NULL; } @@ -356,7 +362,7 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan, luc->attr.num_subbuf = chan->attr.num_subbuf; 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->attr.output = (enum lttng_ust_abi_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 *) @@ -365,7 +371,7 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan, /* Translate to UST output enum */ switch (luc->attr.output) { default: - luc->attr.output = LTTNG_UST_MMAP; + luc->attr.output = LTTNG_UST_ABI_MMAP; break; } @@ -379,7 +385,7 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan, /* Copy channel name */ strncpy(luc->name, chan->name, sizeof(luc->name)); } - luc->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + luc->name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0'; /* Init node */ lttng_ht_node_init_str(&luc->node, luc->name); @@ -440,7 +446,7 @@ end: */ enum lttng_error_code trace_ust_create_event(struct lttng_event *ev, char *filter_expression, - struct lttng_filter_bytecode *filter, + struct lttng_bytecode *filter, struct lttng_event_exclusion *exclusion, bool internal_event, struct ltt_ust_event **ust_event) @@ -466,16 +472,16 @@ enum lttng_error_code trace_ust_create_event(struct lttng_event *ev, switch (ev->type) { case LTTNG_EVENT_PROBE: - local_ust_event->attr.instrumentation = LTTNG_UST_PROBE; + local_ust_event->attr.instrumentation = LTTNG_UST_ABI_PROBE; break; case LTTNG_EVENT_FUNCTION: - local_ust_event->attr.instrumentation = LTTNG_UST_FUNCTION; + local_ust_event->attr.instrumentation = LTTNG_UST_ABI_FUNCTION; break; case LTTNG_EVENT_FUNCTION_ENTRY: - local_ust_event->attr.instrumentation = LTTNG_UST_FUNCTION; + local_ust_event->attr.instrumentation = LTTNG_UST_ABI_FUNCTION; break; case LTTNG_EVENT_TRACEPOINT: - local_ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT; + local_ust_event->attr.instrumentation = LTTNG_UST_ABI_TRACEPOINT; break; default: ERR("Unknown ust instrumentation type (%d)", ev->type); @@ -484,20 +490,20 @@ enum lttng_error_code trace_ust_create_event(struct lttng_event *ev, } /* Copy event name */ - 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'; + strncpy(local_ust_event->attr.name, ev->name, LTTNG_UST_ABI_SYM_NAME_LEN); + local_ust_event->attr.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0'; switch (ev->loglevel_type) { case LTTNG_EVENT_LOGLEVEL_ALL: - local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_ALL; + local_ust_event->attr.loglevel_type = LTTNG_UST_ABI_LOGLEVEL_ALL; local_ust_event->attr.loglevel = -1; /* Force to -1 */ break; case LTTNG_EVENT_LOGLEVEL_RANGE: - local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_RANGE; + local_ust_event->attr.loglevel_type = LTTNG_UST_ABI_LOGLEVEL_RANGE; local_ust_event->attr.loglevel = ev->loglevel; break; case LTTNG_EVENT_LOGLEVEL_SINGLE: - local_ust_event->attr.loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE; + local_ust_event->attr.loglevel_type = LTTNG_UST_ABI_LOGLEVEL_SINGLE; local_ust_event->attr.loglevel = ev->loglevel; break; default: @@ -539,69 +545,72 @@ int trace_ust_context_type_event_to_ust( switch (type) { case LTTNG_EVENT_CONTEXT_VTID: - utype = LTTNG_UST_CONTEXT_VTID; + utype = LTTNG_UST_ABI_CONTEXT_VTID; break; case LTTNG_EVENT_CONTEXT_VPID: - utype = LTTNG_UST_CONTEXT_VPID; + utype = LTTNG_UST_ABI_CONTEXT_VPID; break; case LTTNG_EVENT_CONTEXT_PTHREAD_ID: - utype = LTTNG_UST_CONTEXT_PTHREAD_ID; + utype = LTTNG_UST_ABI_CONTEXT_PTHREAD_ID; break; case LTTNG_EVENT_CONTEXT_PROCNAME: - utype = LTTNG_UST_CONTEXT_PROCNAME; + utype = LTTNG_UST_ABI_CONTEXT_PROCNAME; break; case LTTNG_EVENT_CONTEXT_IP: - utype = LTTNG_UST_CONTEXT_IP; + utype = LTTNG_UST_ABI_CONTEXT_IP; break; case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER: if (!ustctl_has_perf_counters()) { utype = -1; WARN("Perf counters not implemented in UST"); } else { - utype = LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER; + utype = LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER; } break; case LTTNG_EVENT_CONTEXT_APP_CONTEXT: - utype = LTTNG_UST_CONTEXT_APP_CONTEXT; + utype = LTTNG_UST_ABI_CONTEXT_APP_CONTEXT; break; case LTTNG_EVENT_CONTEXT_CGROUP_NS: - utype = LTTNG_UST_CONTEXT_CGROUP_NS; + utype = LTTNG_UST_ABI_CONTEXT_CGROUP_NS; break; case LTTNG_EVENT_CONTEXT_IPC_NS: - utype = LTTNG_UST_CONTEXT_IPC_NS; + utype = LTTNG_UST_ABI_CONTEXT_IPC_NS; break; case LTTNG_EVENT_CONTEXT_MNT_NS: - utype = LTTNG_UST_CONTEXT_MNT_NS; + utype = LTTNG_UST_ABI_CONTEXT_MNT_NS; break; case LTTNG_EVENT_CONTEXT_NET_NS: - utype = LTTNG_UST_CONTEXT_NET_NS; + utype = LTTNG_UST_ABI_CONTEXT_NET_NS; break; case LTTNG_EVENT_CONTEXT_PID_NS: - utype = LTTNG_UST_CONTEXT_PID_NS; + utype = LTTNG_UST_ABI_CONTEXT_PID_NS; + break; + case LTTNG_EVENT_CONTEXT_TIME_NS: + utype = LTTNG_UST_ABI_CONTEXT_TIME_NS; break; case LTTNG_EVENT_CONTEXT_USER_NS: - utype = LTTNG_UST_CONTEXT_USER_NS; + utype = LTTNG_UST_ABI_CONTEXT_USER_NS; break; case LTTNG_EVENT_CONTEXT_UTS_NS: - utype = LTTNG_UST_CONTEXT_UTS_NS; + utype = LTTNG_UST_ABI_CONTEXT_UTS_NS; break; case LTTNG_EVENT_CONTEXT_VUID: - utype = LTTNG_UST_CONTEXT_VUID; + utype = LTTNG_UST_ABI_CONTEXT_VUID; break; case LTTNG_EVENT_CONTEXT_VEUID: - utype = LTTNG_UST_CONTEXT_VEUID; + utype = LTTNG_UST_ABI_CONTEXT_VEUID; break; case LTTNG_EVENT_CONTEXT_VSUID: - utype = LTTNG_UST_CONTEXT_VSUID; + utype = LTTNG_UST_ABI_CONTEXT_VSUID; break; case LTTNG_EVENT_CONTEXT_VGID: - utype = LTTNG_UST_CONTEXT_VGID; + utype = LTTNG_UST_ABI_CONTEXT_VGID; break; case LTTNG_EVENT_CONTEXT_VEGID: - utype = LTTNG_UST_CONTEXT_VEGID; + utype = LTTNG_UST_ABI_CONTEXT_VEGID; break; case LTTNG_EVENT_CONTEXT_VSGID: - utype = LTTNG_UST_CONTEXT_VSGID; + utype = LTTNG_UST_ABI_CONTEXT_VSGID; break; default: utype = -1; @@ -626,7 +635,7 @@ int trace_ust_match_context(const struct ltt_ust_context *uctx, return 0; } switch (utype) { - case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER: + case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER: if (uctx->ctx.u.perf_counter.type != ctx->u.perf_counter.type) { return 0; @@ -637,11 +646,11 @@ int trace_ust_match_context(const struct ltt_ust_context *uctx, } if (strncmp(uctx->ctx.u.perf_counter.name, ctx->u.perf_counter.name, - LTTNG_UST_SYM_NAME_LEN)) { + LTTNG_UST_ABI_SYM_NAME_LEN)) { return 0; } break; - case LTTNG_UST_CONTEXT_APP_CONTEXT: + case LTTNG_UST_ABI_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, @@ -682,16 +691,16 @@ struct ltt_ust_context *trace_ust_create_context( goto end; } - uctx->ctx.ctx = (enum lttng_ust_context_type) utype; + uctx->ctx.ctx = (enum lttng_ust_abi_context_type) utype; switch (utype) { - case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER: + case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER: uctx->ctx.u.perf_counter.type = ctx->u.perf_counter.type; uctx->ctx.u.perf_counter.config = ctx->u.perf_counter.config; strncpy(uctx->ctx.u.perf_counter.name, ctx->u.perf_counter.name, - LTTNG_UST_SYM_NAME_LEN); - uctx->ctx.u.perf_counter.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + LTTNG_UST_ABI_SYM_NAME_LEN); + uctx->ctx.u.perf_counter.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0'; break; - case LTTNG_UST_CONTEXT_APP_CONTEXT: + case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT: { char *provider_name = NULL, *ctx_name = NULL; @@ -719,29 +728,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; } @@ -750,63 +755,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_PROCESS_ATTR_EXISTS; goto end; } tracker_node = zmalloc(sizeof(*tracker_node)); @@ -814,48 +816,94 @@ 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_PROCESS_ATTR_MISSING; 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_process_attr process_attr) +{ + switch (process_attr) { + case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID: + return &session->vpid_tracker; + case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID: + return &session->vuid_tracker; + case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID: + return &session->vgid_tracker; + default: + return NULL; + } +} + +static struct process_attr_tracker *_trace_ust_get_process_attr_tracker( + struct ltt_ust_session *session, + enum lttng_process_attr process_attr) +{ + switch (process_attr) { + case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID: + return session->tracker_vpid; + case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID: + return session->tracker_vuid; + case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID: + return session->tracker_vgid; + default: + return NULL; + } +} + +const struct process_attr_tracker *trace_ust_get_process_attr_tracker( + struct ltt_ust_session *session, + enum lttng_process_attr process_attr) +{ + return (const struct process_attr_tracker *) + _trace_ust_get_process_attr_tracker( + session, process_attr); +} + /* * 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_process_attr process_attr, + 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, process_attr); + 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; @@ -864,152 +912,285 @@ 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) +enum lttng_error_code trace_ust_process_attr_tracker_set_tracking_policy( + struct ltt_ust_session *session, + enum lttng_process_attr process_attr, + enum lttng_tracking_policy policy) { - int retval = LTTNG_OK; + int ret; + enum lttng_error_code ret_code = LTTNG_OK; + struct ust_id_tracker *id_tracker = + get_id_tracker(session, process_attr); + struct process_attr_tracker *tracker = + _trace_ust_get_process_attr_tracker( + session, process_attr); bool should_update_apps = false; + enum lttng_tracking_policy previous_policy; + + if (!tracker) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } - if (pid == -1) { - /* Track all pids: destroy tracker if exists. */ - if (session->pid_tracker.ht) { - fini_pid_tracker(&session->pid_tracker); + previous_policy = process_attr_tracker_get_tracking_policy(tracker); + ret = process_attr_tracker_set_tracking_policy(tracker, policy); + if (ret) { + ret_code = LTTNG_ERR_UNK; + goto end; + } + + if (previous_policy == policy) { + goto end; + } + + switch (policy) { + case LTTNG_TRACKING_POLICY_INCLUDE_ALL: + /* Track all values: destroy tracker if exists. */ + if (id_tracker->ht) { + fini_id_tracker(id_tracker); /* Ensure all apps have session. */ should_update_apps = true; } - } else { - int ret; - - if (!session->pid_tracker.ht) { - /* Create tracker. */ - if (init_pid_tracker(&session->pid_tracker)) { - ERR("Error initializing PID tracker"); - retval = LTTNG_ERR_NOMEM; - goto end; - } - ret = pid_tracker_add_pid(&session->pid_tracker, pid); - if (ret != LTTNG_OK) { - retval = ret; - fini_pid_tracker(&session->pid_tracker); - goto end; - } - /* Remove all apps from session except pid. */ - 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; - } - /* Add session to application */ - app = ust_app_find_by_pid(pid); - if (app) { - should_update_apps = true; - } + break; + case LTTNG_TRACKING_POLICY_EXCLUDE_ALL: + case LTTNG_TRACKING_POLICY_INCLUDE_SET: + /* fall-through. */ + fini_id_tracker(id_tracker); + ret_code = init_id_tracker(id_tracker); + if (ret_code != LTTNG_OK) { + ERR("Error initializing ID tracker"); + goto end; } + /* Remove all apps from session. */ + should_update_apps = true; + break; + default: + abort(); } if (should_update_apps && session->active) { ust_app_global_update_all(session); } end: - return retval; + return ret_code; } -/* - * Called with the session lock held. - */ -int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid) +/* Called with the session lock held. */ +enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_add_value( + struct ltt_ust_session *session, + enum lttng_process_attr process_attr, + const struct process_attr_value *value) { - int retval = LTTNG_OK; + enum lttng_error_code ret_code = LTTNG_OK; bool should_update_apps = false; + struct ust_id_tracker *id_tracker = + get_id_tracker(session, process_attr); + struct process_attr_tracker *tracker; + int integral_value; + enum process_attr_tracker_status status; + struct ust_app *app; - if (pid == -1) { - /* Create empty tracker, replace old tracker. */ - struct ust_pid_tracker tmp_tracker; - - tmp_tracker = session->pid_tracker; - if (init_pid_tracker(&session->pid_tracker)) { - ERR("Error initializing PID tracker"); - retval = LTTNG_ERR_NOMEM; - /* Rollback operation. */ - session->pid_tracker = tmp_tracker; - goto end; + /* + * Convert process attribute tracker value to the integral + * representation required by the kern-ctl API. + */ + switch (process_attr) { + case LTTNG_PROCESS_ATTR_PROCESS_ID: + case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID: + integral_value = (int) value->value.pid; + break; + case LTTNG_PROCESS_ATTR_USER_ID: + case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID: + if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) { + uid_t uid; + + ret_code = utils_user_id_from_name( + value->value.user_name, &uid); + if (ret_code != LTTNG_OK) { + goto end; + } + integral_value = (int) uid; + } else { + integral_value = (int) value->value.uid; + } + break; + case LTTNG_PROCESS_ATTR_GROUP_ID: + case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID: + if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) { + gid_t gid; + + ret_code = utils_group_id_from_name( + value->value.group_name, &gid); + if (ret_code != LTTNG_OK) { + goto end; + } + integral_value = (int) gid; + } else { + integral_value = (int) value->value.gid; } - fini_pid_tracker(&tmp_tracker); + break; + default: + ret_code = LTTNG_ERR_INVALID; + goto end; + } - /* Remove session from all applications */ - should_update_apps = true; - } else { - int ret; - struct ust_app *app; + tracker = _trace_ust_get_process_attr_tracker(session, process_attr); + if (!tracker) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } - if (!session->pid_tracker.ht) { - /* No PID being tracked. */ - retval = LTTNG_ERR_PID_NOT_TRACKED; - goto end; + status = process_attr_tracker_inclusion_set_add_value(tracker, value); + if (status != PROCESS_ATTR_TRACKER_STATUS_OK) { + switch (status) { + case PROCESS_ATTR_TRACKER_STATUS_EXISTS: + ret_code = LTTNG_ERR_PROCESS_ATTR_EXISTS; + break; + case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY: + ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY; + break; + case PROCESS_ATTR_TRACKER_STATUS_ERROR: + default: + ret_code = LTTNG_ERR_UNK; + break; } - /* Remove PID from tracker */ - ret = pid_tracker_del_pid(&session->pid_tracker, pid); - if (ret != LTTNG_OK) { - retval = ret; - goto end; - } - /* Remove session from application. */ - app = ust_app_find_by_pid(pid); + goto end; + } + + DBG("User space track %s %d for session id %" PRIu64, + lttng_process_attr_to_string(process_attr), + integral_value, session->id); + + ret_code = id_tracker_add_id(id_tracker, integral_value); + if (ret_code != LTTNG_OK) { + goto end; + } + /* Add session to application */ + switch (process_attr) { + case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID: + app = ust_app_find_by_pid(integral_value); if (app) { should_update_apps = true; } + break; + default: + should_update_apps = true; + break; } if (should_update_apps && session->active) { ust_app_global_update_all(session); } end: - return retval; + return ret_code; } -/* - * Called with session lock held. - */ -ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session, - int32_t **_pids) +/* Called with the session lock held. */ +enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_remove_value( + struct ltt_ust_session *session, + enum lttng_process_attr process_attr, + const struct process_attr_value *value) { - 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; + enum lttng_error_code ret_code = LTTNG_OK; + bool should_update_apps = false; + struct ust_id_tracker *id_tracker = + get_id_tracker(session, process_attr); + struct process_attr_tracker *tracker; + int integral_value; + enum process_attr_tracker_status status; + struct ust_app *app; - if (!session->pid_tracker.ht) { - /* Tracker disabled. Set first entry to -1. */ - pids = zmalloc(sizeof(*pids)); - if (!pids) { - ret = -1; - goto end; + /* + * Convert process attribute tracker value to the integral + * representation required by the kern-ctl API. + */ + switch (process_attr) { + case LTTNG_PROCESS_ATTR_PROCESS_ID: + case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID: + integral_value = (int) value->value.pid; + break; + case LTTNG_PROCESS_ATTR_USER_ID: + case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID: + if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) { + uid_t uid; + + ret_code = utils_user_id_from_name( + value->value.user_name, &uid); + if (ret_code != LTTNG_OK) { + goto end; + } + integral_value = (int) uid; + } else { + integral_value = (int) value->value.uid; } - pids[0] = -1; - *_pids = pids; - return 1; + break; + case LTTNG_PROCESS_ATTR_GROUP_ID: + case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID: + if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) { + gid_t gid; + + ret_code = utils_group_id_from_name( + value->value.group_name, &gid); + if (ret_code != LTTNG_OK) { + goto end; + } + integral_value = (int) gid; + } else { + integral_value = (int) value->value.gid; + } + break; + default: + ret_code = LTTNG_ERR_INVALID; + goto end; } - 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; + tracker = _trace_ust_get_process_attr_tracker(session, process_attr); + if (!tracker) { + ret_code = LTTNG_ERR_INVALID; goto end; } - cds_lfht_for_each_entry(session->pid_tracker.ht->ht, - &iter.iter, tracker_node, node.node) { - pids[i++] = tracker_node->node.key; + + status = process_attr_tracker_inclusion_set_remove_value( + tracker, value); + if (status != PROCESS_ATTR_TRACKER_STATUS_OK) { + switch (status) { + case PROCESS_ATTR_TRACKER_STATUS_MISSING: + ret_code = LTTNG_ERR_PROCESS_ATTR_MISSING; + break; + case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY: + ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY; + break; + case PROCESS_ATTR_TRACKER_STATUS_ERROR: + default: + ret_code = LTTNG_ERR_UNK; + break; + } + goto end; + } + + DBG("User space untrack %s %d for session id %" PRIu64, + lttng_process_attr_to_string(process_attr), + integral_value, session->id); + + ret_code = id_tracker_del_id(id_tracker, integral_value); + if (ret_code != LTTNG_OK) { + goto end; + } + /* Add session to application */ + switch (process_attr) { + case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID: + app = ust_app_find_by_pid(integral_value); + if (app) { + should_update_apps = true; + } + break; + default: + should_update_apps = true; + break; + } + if (should_update_apps && session->active) { + ust_app_global_update_all(session); } - *_pids = pids; - ret = count; end: - rcu_read_unlock(); - return ret; + return ret_code; } /* @@ -1074,7 +1255,7 @@ void trace_ust_destroy_context(struct ltt_ust_context *ctx) { assert(ctx); - if (ctx->ctx.ctx == LTTNG_UST_CONTEXT_APP_CONTEXT) { + if (ctx->ctx.ctx == LTTNG_UST_ABI_CONTEXT_APP_CONTEXT) { free(ctx->ctx.u.app_ctx.provider_name); free(ctx->ctx.u.app_ctx.ctx_name); } @@ -1241,7 +1422,13 @@ void trace_ust_destroy_session(struct ltt_ust_session *session) buffer_reg_uid_destroy(reg, session->consumer); } - fini_pid_tracker(&session->pid_tracker); + process_attr_tracker_destroy(session->tracker_vpid); + process_attr_tracker_destroy(session->tracker_vuid); + process_attr_tracker_destroy(session->tracker_vgid); + + 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); }